87509bcf99
TASKS.md is now the index (status table, open items, research pointer). 33 files: 32 task files + 1 research facts file. The full take-saga narrative and all design decisions are preserved verbatim; the catalog makes the queue readable without opening every task body. Schema and AGENTS.md updated to reflect the new layout.
40 lines
2.6 KiB
Markdown
40 lines
2.6 KiB
Markdown
# TASK 24 — Toast notifications (in-app, non-blocking)
|
||
|
||
> Catalog: [`TASKS.md`](../TASKS.md) — status and requirements live here.
|
||
|
||
|
||
### Status: ✅ Done (shipped 2026-08-23, branch `task24-notifications`)
|
||
|
||
Replace blocking MessageBoxes with in-window toasts; promote actionable log-only failures.
|
||
|
||
### Requirements:
|
||
1. Library: **Notification.Wpf 11.0.0** (Platonenkov fork of Federerer/Notifications.Wpf) — MIT, active, targets net8.0-windows. Notice #10 added to `THIRD-PARTY-NOTICES.txt`.
|
||
2. Placement: bottom-right above the footer (`NotificationArea x:Name="ToastArea"`, last child of MainWindow's root grid → topmost z-order, `Grid.RowSpan=4`, `Margin="0,0,12,96"`, outside the preview Viewbox), max 4 stacked.
|
||
3. Behavior: Info ~4s / Success ~4s / Warning ~8s auto-dismiss; **Error sticky until dismissed**.
|
||
4. Styling: dark card tints matching the health-banner language (slate `#3a3b52` info, green `#1d5c38` success, amber `#b8860b` warning, dark-red `#8f1f1f` error); corner radius 8; keep-visible-on-hover.
|
||
5. Threading: all Show calls marshal via a Dispatcher captured at construction (encoder/pump events fire off-thread).
|
||
|
||
### Migrations (MessageBox → toast):
|
||
- Webcam acquire failure ×2 (`AddWebcamToStagedSceneAsync`, `SwapWebcamIdentityAsync`) → Warning
|
||
- Image read failure (`PickImageBytes`) → Warning
|
||
- Sign-in unsuccessful → Warning; sign-in failed → Error
|
||
|
||
### Promotions (log-only → toast, each keeps its AppLog line):
|
||
- Go-live prep ×3: reusable stream unavailable / broadcast insert failed / prep exception → Error
|
||
- Frame-pump death while live (`OnFramePumpFailed`) → Error
|
||
- Mic missing at startup (`StartMicCaptureAsync`) → Warning (once)
|
||
- Premium lapse at startup re-validation → Warning
|
||
- Saved-session refresh failure (signed out notice) → Info
|
||
|
||
Deliberately left alone: offline license re-validation skip (log-only — would spam every launch); SocialsDialog slot-delete YesNo confirm (stays modal).
|
||
|
||
### Tests:
|
||
- Unit: pure severity→request mapping (`NotificationServiceTests`) — area routing, lifetimes, tints.
|
||
- Integration (the ONE): real window-hosted `ToastArea` + real service — Info auto-dismisses, Error sticks (`NotificationAreaIntegrationTests`, RealApp collection).
|
||
|
||
### Library facts (cost a hunt — see also ai.md):
|
||
- Area routing matches the area's XAML `Name` against the request's `AreaName`; unknown name silently drops.
|
||
- `NeverExpires()` = `ExpirationTime = TimeSpan.MaxValue` (not null); `NotificationColor.ToHex()` returns `#AARRGGBB`.
|
||
- Overlay-window shutdown caveat avoided entirely by using the in-window area mode.
|
||
|