From d17332f3ac984be41a3651accdd3d86985f5d50f Mon Sep 17 00:00:00 2001 From: fireshaper Date: Sun, 18 Oct 2026 14:06:53 -0400 Subject: [PATCH] Record CR-028: live toasts instead of the away pop-up (Phase 28) Co-Authored-By: Claude Opus 5.5 --- DECISIONS.md | 5 + .../change-requests/CR-028-live-toasts.md | 106 ++++++++++++++++++ memory-bank/implementation-plan.md | 10 ++ memory-bank/progress.md | 10 ++ 4 files changed, 131 insertions(+) create mode 100644 memory-bank/change-requests/CR-028-live-toasts.md diff --git a/DECISIONS.md b/DECISIONS.md index ae8c4ef..c87d9d2 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -2041,3 +2041,8 @@ Implementation decisions not spelled out in `memory-bank/implementation-plan.md` - **"Neglected" means a second trip in a row below 25% while the repair is affordable** above the spending floor: the first such trip is usually the one to the HQ. - **The away median drops from 60% to 49% of active play**: until now the simulator never repaired away hulls, so the old figure left out repair costs and shop time. Still inside 40–80%. - **Amendments go on each amended CR** as "Amended by CR-027" lines (CR-023 and CR-026 get an Amendments section). + +## CR-028 recorded (Live Toasts) + +- **Received as "CR-026 … Phase 26"; stored as CR-028, Phase 28**, decisions CR-026.D1–D4 = plan §0.5.160–0.5.163, with every reference mapped in the CR's numbering note. +- **"The HQ banner" is the Bridge's "Fleet asleep" panel** (CR-024), the panel that already shows while the fleet sleeps. diff --git a/memory-bank/change-requests/CR-028-live-toasts.md b/memory-bank/change-requests/CR-028-live-toasts.md new file mode 100644 index 0000000..4c58db0 --- /dev/null +++ b/memory-bank/change-requests/CR-028-live-toasts.md @@ -0,0 +1,106 @@ +# Change Request CR-028 — Live Toasts Instead of the Away Pop-up + +> **Numbering note (added when recorded):** this request arrived titled "CR-026 — Live Toasts Instead of the Away Pop-up" for "Phase 26". CR-026 (Random Events) and CR-027 (Service Bookings), and Phases 26 and 27, already existed, so it is stored as **CR-028** and done as **Phase 28**: every "26.n" below means **28.n**. Its references map to this repo as: "Phase 13 and CR-001 through CR-025" = Phase 13 and **CR-001 to CR-027**; "CR-008 settings" = **CR-011**; "CR-011 local-first" = **CR-014**; "CR-019 independent pilots" = **CR-021**; "CR-022 fleet sleep" = **CR-024**; "CR-023 away summary" = **CR-025** (its "Step 23.2" = **Step 25.2**); "CR-024 random events" = **CR-026**; "CR-025 service bookings" = **CR-027**. Its decisions CR-026.D1–D4 are recorded as **0.5.160–0.5.163** (D1 = 0.5.160 … D4 = 0.5.163). "Plan 9.2" is the plan's Step 9.2 ("While you were away"). +> +> **On recording:** "the HQ banner" for fleet sleep is the Bridge's "Fleet asleep" panel (CR-024, `FleetAsleep`). Today the pop-up opens on unacknowledged deliveries and finished upgrades and covers the absence since `player.awaySince`; per-entry "seen" replaces that as what opens it. Reduced motion is the Settings preference (CR-011) and the system setting. + +**Project:** Deadhead: Space Freight Tycoon +**Applies to:** a build with Phase 13 and CR-001 through CR-025 complete +**Do this:** as **Phase 26** +**Related docs:** `change-request-settings.md` (CR-008), `change-request-local-first.md` (CR-011), `change-request-independent-pilots.md` (CR-019), `change-request-fleet-sleep.md` (CR-022), `change-request-away-summary.md` (CR-023), `change-request-random-events.md` (CR-024), `change-request-service-bookings.md` (CR-025), `DECISIONS.md` + +This change request is written for the local-first engine (CR-011). + +--- + +## 1. Why + +The "while you were away" pop-up appears even when the player has the game open and is watching. If Deadhead is on screen, things that happen should show as **small notifications that close on their own**. The pop-up is only for when the player comes back after the game wasn't on screen and something happened in the meantime. + +## 2. Rules + +### When is the player "here"? + +- **Here:** the game's browser tab is visible (Page Visibility API), or the native app is in the foreground (Capacitor app state). +- **Away:** the tab is hidden or minimized, the app is in the background, or the game was closed. + +### While the player is here: toasts + +| Rule | Detail | +| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Position | **Desktop** (viewport 768 px or wider): top-right corner. **Mobile:** top of the screen, centered, below the safe area. | +| Duration | Closes on its own after **5 seconds**. Hovering (desktop) or touching (mobile) pauses the timer. Swipe or ✕ dismisses early. | +| Stacking | At most **3** visible; newer push older down. Overflow becomes one "+N more" toast that opens the Logbook (CR-023). | +| Tapping | Opens the related ship, pilot, location, or Logbook entry. | +| What gets a toast | Deliveries, discoveries, level-ups, goals ready, automatic events and radio-call outcomes (CR-024), service started and finished (CR-025), "waiting for funds" and "can't reach HQ" problems (CR-025). | +| Batching | Routine deliveries by Independent pilots within the same 10 seconds combine into one toast ("3 deliveries · +4,200 cr"). Player-dispatched deliveries, discoveries, level-ups, and problems always get their own toast. | +| Radio calls | Unchanged from CR-024: a radio call opens its card and stays until answered or expired. It is never an auto-closing toast. | +| Fleet sleep | If the fleet goes quiet while the player has the game open but hasn't made decisions (CR-022), show a toast and the HQ banner; no pop-up. | +| Accessibility | Toasts are announced politely to screen readers. With reduced motion (CR-008), they appear and disappear without sliding. | + +Every event that gets a toast is marked **seen**. + +### When the player comes back: the pop-up + +- On returning from away (tab visible again, app back in the foreground, or a fresh launch), show the CR-023 "while you were away" pop-up **only if unseen events happened while away**. +- The pop-up covers exactly the unseen events from that away period; nothing that was already toasted. +- **Short trips away:** if the player was away for less than **60 seconds**, show any unseen events as toasts instead of the pop-up. A quick tab switch shouldn't trigger a full summary. +- If nothing happened while away, show nothing. + +## 3. Rules for this change + +- All rules in `implementation-plan.md` §0.1 apply: steps in order, one commit per step, each step's test must pass. +- "Seen" is per logbook entry (CR-023) and saved, so a reload doesn't re-show toasted events as a pop-up. +- The pop-up's content builder (CR-023 Step 23.2) takes the unseen entries for the away period instead of all entries since last open. +- Toast timing and the 60-second short-absence threshold live in the client config, not game content. +- Update `progress.md` after every step. Stop for the user's review at the end of Phase 26. + +## 4. Decisions + +Record these in `DECISIONS.md` and `implementation-plan.md` §0.5, using the next free numbers (labeled CR-026.D1–D4 here; note the mapping). + +- **CR-026.D1 Presence.** "Here" means the tab is visible or the app is in the foreground. +- **CR-026.D2 Toasts while here.** Per §2: top-right on desktop, top of the screen on mobile, 5-second auto-close, max 3, batched routine deliveries; radio calls keep their own card. +- **CR-026.D3 Pop-up only after being away,** and only for unseen events; under 60 seconds away uses toasts instead. +- **CR-026.D4 Seen tracking** per logbook entry, saved. + +## 5. Steps — Phase 26 + +### Step 26.1 — Engine: seen tracking + +- Add a "seen" flag to logbook entries and a command to mark entries seen (not a manual decision for CR-022). Save migration: all existing entries are marked seen. +- **Test:** New entries start unseen; marking them seen persists across reload; migrated saves have everything seen. + +### Step 26.2 — Client: presence tracking + +- Track here/away from the Page Visibility API (web) and Capacitor app state (native), recording when the player went away and came back. +- **Test:** Simulated visibility changes produce the right away start and end times; a cold start counts as returning from away since the last saved time. + +### Step 26.3 — Client: toasts + +- Build the toast system per §2: positions by viewport width, 5-second auto-close with pause on hover or touch, max 3 with "+N more", tap targets, batching of Independent deliveries, screen-reader announcements, reduced-motion behavior. Mark each toasted entry seen. +- **Test:** Component tests: at 1280 px wide toasts render top-right, at 375 px top-center below the safe area; a toast closes after 5 seconds and not while hovered; a fourth toast produces "+1 more"; three Independent deliveries within 10 seconds produce one combined toast; a discovery always gets its own; tapping opens the right screen; toasted entries are marked seen. + +### Step 26.4 — Client: pop-up only after being away + +- On return from away, if the away period was 60 seconds or more and unseen entries exist, show the CR-023 pop-up built from those entries and mark them seen when it closes. Under 60 seconds, show them as toasts. With no unseen entries, show nothing. +- Remove any path that opens the pop-up while the player is here. +- **Test:** With the game visible, a delivery produces a toast and no pop-up. Hiding the tab for 5 minutes during which two deliveries resolve, then returning, shows the pop-up with exactly those two. Hiding it for 30 seconds produces toasts, not the pop-up. Returning after an away period with nothing new shows nothing. Reloading after the pop-up closed doesn't show it again. + +### Step 26.5 — Regression + +- Run the full suite. +- **Test:** CI is green. Manual check on desktop and phone: keep the game open and watch deliveries arrive as toasts; switch away for a few minutes and confirm the pop-up summarizes only what happened while away. + +## 6. Amendments + +| Where | Change | +| --------------- | ---------------------------------------------------------------------------- | +| Plan 0.5 | Add CR-026.D1–D4. | +| Plan 9.2, CR-023 | The pop-up shows only after being away, for unseen events only. | +| CR-022 | Sleep while the game is open shows a toast and HQ banner, not the pop-up. | +| CR-024 | Event outcomes become toasts while the player is here; radio calls unchanged. | + +## 7. Out of scope + +A notification history panel beyond the Logbook, per-type toast settings, sounds, browser (system) notifications on web, and anything else in `implementation-plan.md` §0.3. diff --git a/memory-bank/implementation-plan.md b/memory-bank/implementation-plan.md index f6fa5b6..58960e7 100644 --- a/memory-bank/implementation-plan.md +++ b/memory-bank/implementation-plan.md @@ -215,6 +215,10 @@ These answer the pre-build review. Log each one in `DECISIONS.md` as it is imple 157. **Auto-repair** (CR-027). Per ship, on at 40% by default (10–90% in steps of 5): with an Independent crew, a hull dropping below it adds a repair booking at the nearest reachable HQ (or to the ship's booking); with a Manual crew it shows "Repair recommended" instead. 158. **Sleep exception** (CR-027). Service trips continue while the fleet is asleep; afterwards the pilot waits for orders. Asleep, the trip flies empty (Step 27.7): a paid job to the HQ would earn while the fleet is quiet (decision 0.5.137). 159. **No double waiting** (CR-027). Rest and service run at the same time when they coincide; the pilot is free when the later ends, and a service long enough to count as rest (decision 0.5.135) resets duty and ends any remaining rest. +160. **Presence** (CR-028). The player is "here" while the game's tab is visible or the native app is in the foreground; otherwise away (hidden, backgrounded or closed). +161. **Toasts while here** (CR-028). Things that happen while the player is here show as toasts: top-right on desktop (768 px or wider), top-center below the safe area on phones; 5 s each, paused by hover or touch, dismissed by swipe or ✕; at most 3, overflow as "+N more" opening the Logbook; tapping opens the ship, pilot, place or Logbook. Independent pilots' routine deliveries within 10 s combine into one; player deliveries, discoveries, level-ups and problems get their own. Radio calls keep their card. Fleet sleep while here is a toast plus the Bridge's "Fleet asleep" panel. Announced politely; no sliding with reduced motion. +162. **Pop-up only after being away** (CR-028). On coming back (tab visible, app in front, or a fresh launch), "While you were away" opens only for unseen entries from that absence, and covers exactly those; under 60 s away they show as toasts; nothing new, nothing shown. +163. **Seen per entry** (CR-028). Each logbook entry has a saved "seen" flag, set when toasted or when the pop-up showing it closes; marking entries seen isn't a manual decision. ### 0.6 Translating change requests written for the server (CR-014 §7) @@ -942,6 +946,12 @@ Steps 27.1–27.7 are specified in `memory-bank/change-requests/CR-027-service-b --- +## Phase 28 — Live Toasts Instead of the Away Pop-up (CR-028) + +Steps 28.1–28.5 are specified in `memory-bank/change-requests/CR-028-live-toasts.md` §5 (written there as 26.1–26.5). Stop for review at the end. + +--- + ## Definition of Done (Base Game) - All step tests pass in CI. diff --git a/memory-bank/progress.md b/memory-bank/progress.md index 617300b..5379aea 100644 --- a/memory-bank/progress.md +++ b/memory-bank/progress.md @@ -576,3 +576,13 @@ Spec: `memory-bank/change-requests/CR-027-service-bookings.md` (received as "CR- - [x] **Step 27.5 — Client: Service section and tags.** `apps/web/src/components/Service.tsx`: the Service section in the ship's Upgrades sheet (the booking's items, HQ, estimate and status; Book service with a repair box, an upgrade picker (the next level of each) and an HQ picker defaulting to the nearest reachable (`defaultHq`, the sim's `nearestReachableHq`), with the estimate; Change and Cancel booking until the work starts; the auto-repair box and a 10–90% slider in steps of 5). `serviceTag` on the Fleet card and in the dispatch sheet ("Service booked: Engine Tuning 2 at Earth", "Repair recommended"); `serviceStatus` ("Heading to Earth for service", "In the shop at Earth (resting)", "Waiting for funds: Repair at Earth", "Can't reach Earth for service") leads an Independent pilot's status line. Tests (`apps/web/test/service.test.tsx`): booking with the estimate and the nearest HQ; a booking's items and status, Change and Cancel calling the engine; no change once started; the slider and the box; the Fleet tag; each status wording; the pilot line; the dispatch sheet tag. Screenshots: `docs/screenshots/27-5-*` (Repair recommended, the booking form, a booked ship's card and sheet; phone and desktop). - [x] **Step 27.6 — Client: Logbook and summaries.** Logbook lines for `service` entries: "Iron Mule: Repair booked automatically at Earth", "service started at Earth (Repair + Engine Tuning), 3,600 cr", "service finished at Earth (…)", "waiting for funds for Repair at Earth". New away problems from the state (`awayProblems`, schema and sim `AwayProblem`): `service-waiting-funds` and `service-cant-reach`, with wording in `awayWording.highlights` ("Iron Mule is waiting for funds: Repair at Earth", "Iron Mule can't reach Jupiter Cloud Platform for its booked service"). Tests: the engine reports each problem (`packages/engine/test/service.test.ts`); the four logbook lines and both highlights render (`apps/web/test/service.test.tsx`). Screenshots: `docs/screenshots/27-6-logbook-*`. - [x] **Step 27.7 — Balance and regression.** The balance simulator's away scenario now runs auto-repair at 40% with events on: hull loss that crosses the threshold books a repair at the nearest reachable HQ (`bookAutoRepair`), the pilot's decisions pass the booking to `chooseAction`, a ship idle at its HQ starts the repair when credits stay above the spending floor (`startServices`), and service trips go on while asleep. Results gain `service` (bookings, services, the most trips in a row an Independent ship flew below 25% with its repair affordable); a second such trip is a `hull-neglected` violation. Measured over the 7 balance seeds, 8 hours away (`balance/measure-service.ts`): 3–4 bookings and as many repairs a run, at most 1 trip below 25%, no violations; away earns a median 49% of active play (target 40–80%; 60% before, when away hulls were never repaired). Asleep, a service trip flies empty, so the week-away bound (CR-024) still holds. Amendments (CR-027 §8) added to CR-009, CR-021, CR-023, CR-024, CR-025 and CR-026. Test: `packages/sim/test/balance.test.ts` (no ship more than one trip below 25%, bookings made and done, the away ratio and the week bound), the engine sleep test (an empty flight to the HQ with a paid job home on the board); full suite green. + +## Phase 28 — Live Toasts Instead of the Away Pop-up (CR-028) + +Spec: `memory-bank/change-requests/CR-028-live-toasts.md` (received as "CR-026 … Phase 26"). New decisions recorded as plan §0.5.160–0.5.163. + +- [ ] Step 28.1 — Engine: seen tracking +- [ ] Step 28.2 — Client: presence tracking +- [ ] Step 28.3 — Client: toasts +- [ ] Step 28.4 — Client: pop-up only after being away +- [ ] Step 28.5 — Regression