ecb329e578
Creator: 'when the test slide-out is active, then any click off the div should close the div — this behaviour applies to all tabs, not just TEST.' MainWindow.Window_PreviewMouseLeftButtonDown already closed the Stream Settings and YPP drawers on any click outside TextPullOutHost, but its close list skipped TestSession — so the TEST drawer never dismissed on an outside click. Fix: run TestSession.CloseDrawerCommand in the same outside-click branch. All three drawers share the rail host, so the containment check is unchanged. Good Dog: ONE integration test — the existing TestStream window section now raises a window-root PreviewMouseLeftButtonDown (source = window => outside the rail; deterministic, no OS mouse) and asserts the TEST and Stream Settings drawers both close. Gate: clean build 0 warnings, full vstest 318/318.
13 KiB
13 KiB
ytLlive — Task List
Catalog: task files live in
TASKS/(one file per task). This file is the index. Memory-map conventions:schema.md; architecture/decisions:ai.md.
Checklist markers — every task's Status line uses the same states:
- ✅ — completed / shipped
- 🔶 — in progress
- ⏳ — blocked / waiting
- ☐ — not started / queued
- ❌ — exception (known-issue, deliberately excluded, or merged)
2026-09-01 — v1 = feature-complete ruling: there is no v1.x. Everything queues to v1 or to "Out of product — permanently" (file end). Read those two sections before adding or reviving anything here.
Task catalog
| # | Task | Status | File |
|---|---|---|---|
| 01 | Initial Scaffold | ✅ Done | TASKS/task-01-initial-scaffold.md |
| 02 | YouTube OAuth2 Authentication | ✅ Done | TASKS/task-02-oauth2-auth.md |
| 03 | Capture Pipeline (Scenes/Sources) | 🔶 In progress — 27/30 items done; items 16, 17, 20 open | TASKS/task-03-capture-pipeline.md |
| 04 | RTMP Ingest to YouTube | ✅ Done — all 7 items shipped | TASKS/task-04-rtmp-ingest.md |
| 05 | Layout Persistence (SQLite) | ✅ Done | TASKS/task-05-layout-persistence.md |
| 06 | UI polish batch | ✅ Done | TASKS/task-06-ui-polish-batch.md |
| 07 | Meter scaling amplification | ✅ Done | TASKS/task-07-meter-scaling.md |
| 08 | Audio milestone | ✅ SHIPPED 2026-08-14 | TASKS/task-08-audio-milestone.md |
| 09 | YouTube Live Stream Management | ⏳ In progress — items 1–3, 4 shipped; item 5 open; item 6 locked (TASK 36) | TASKS/task-09-live-stream-management.md |
| 10 | Monetization: watermark-only one-time license + Polar billing | 🔶 In progress — steps 1–7 shipped | TASKS/task-10-monetization.md |
| 11 | Post-pause polish batch (creator's 8 review issues) | ✅ SHIPPED 2026-08-15 | TASKS/task-11-polish-batch.md |
| 12 | Master limiter on the live mix | ☐ Queued | TASKS/task-12-master-limiter.md |
| 13 | Social media launch kit | 🔶 Scoped — queued after v1 | TASKS/task-13-social-launch-kit.md |
| 14 | Creator feedback batch | 🔶 In progress — Branch 2 shipped | TASKS/task-14-creator-feedback-batch.md |
| 15 | Stock scene background images | ✅ Shipped | TASKS/task-15-scene-backgrounds.md |
| 16 | Kill infinity display | ✅ Shipped | TASKS/task-16-kill-infinity-display.md |
| 17 | Web source rendering (WebView2) | ✅ Done | TASKS/task-17-web-source-rendering.md |
| 18 | Local recording | ✅ Shipped a9eb360 (2026-08-29) |
TASKS/task-18-local-recording.md |
| 19 | Scene transitions | MERGED → TASK 23 (Control Surface UX) | TASKS/task-19-scene-transitions.md |
| 20 | Hotkeys (keyboard shortcuts) | ✅ Done — shipped 2026-08-26 | TASKS/task-20-hotkeys.md |
| 21 | Media source (video file playback) | 🔶 In progress — UI picker remaining | TASKS/task-21-media-source.md |
| 22 | Audio sync offset | ✅ Done (2026-08-31) | TASKS/task-22-audio-sync-offset.md |
| 23 | Studio mode | MERGED → TASK 23 (Control Surface UX) | TASKS/task-23-studio-mode.md |
| 24 | Toast notifications | ✅ Done (2026-08-23) | TASKS/task-24-toast-notifications.md |
| 25 | Background consolidation | ✅ Done (2026-08-23) | TASKS/task-25-background-consolidation.md |
| 30 | Gear menu cleanup + Default Location for Recordings + preview layout | ✅ Done (2026-08-29) | TASKS/task-30-gear-cleanup-preview-layout.md |
| 31 | SceneGraph component + static/dynamic compositor optimization | ✅ Done (2026-08-31) | TASKS/task-31-scenegraph-optimization.md |
| 32 | Stream resilience | ☐ Queued (2026-09-01) | TASKS/task-32-stream-resilience.md |
| 33 | Bandwidth auto step-down | ☐ Queued (2026-09-01) | TASKS/task-33-bandwidth-step-down.md |
| 34 | Scheduled streams (Text-drawer version) | ☐ Queued (2026-09-01) | TASKS/task-34-scheduled-streams.md |
| 35 | Scene-linked audio | ☐ Queued (2026-09-01) | TASKS/task-35-scene-linked-audio.md |
| 36 | Gold pass | ☐ Queued (2026-09-01) | TASKS/task-36-gold-pass.md |
| 37 | Defaults vs current layout split | ☐ Queued (2026-09-20) | TASKS/task-37-defaults-current-split.md |
| 38 | Capture Window… backdrop (in-app window picker) | ✅ Done — shipped 2026-09-21 | TASKS/task-38-window-backdrop.md |
| 39 | YPP journey tracker (slice 1: current-scope data) | 🔶 Slice 1 ✅ — 2026-09-22; refresh 403 fixed 2026-09-23 (auditDetails part dropped); slice 2 (Analytics + ETA) queued | TASKS/task-39-ypp-journey-tracker.md |
| 40 | App Settings round: active-camera picker + config dialog, gear move, defaults, accent | ☐ Queued (2026-09-22) — plan saved | TASKS/task-40-app-settings-round.md |
| 41 | Test Stream mode: private test broadcast + TEST drawer (mock chat input + simulated events) | ✅ Done (2026-09-22) | TASKS/task-41-test-stream-mode.md |
| 42 | Top bar redesign: one REC-or-Stream surface, gear up top, sign-in/account zone world-gated | ✅ Done (2026-09-22) | TASKS/task-42-top-bar-redesign.md |
| 43 | Native events & alerts: chat parity (all six event types + server poll cadence) + six-animation native alert box | ✅ Done (2026-09-24) | TASKS/task-43-native-alerts.md |
| 44 | TEST-tab chat fix: resolve liveChatId from snippet (not contentDetails) + poll until the broadcast is live | ✅ Done (2026-09-25); full suite 318/318 | TASKS/task-44-test-chat-fix.md |
| 45 | TEST-tab chat fix #2: insert body must declare snippet.type (400 MISSING_REQUIRED_FIELD) |
✅ Done (2026-09-25) | TASKS/task-45-chat-insert-type.md |
| 46 | Drawers: click outside the rail closes whichever is open — TEST added to the existing Stream Settings + YPP dismiss behavior | ✅ Done (2026-09-25) | TASKS/task-46-drawer-click-outside-close.md |
Open items (at a glance)
- TASK 3 — items 16 (Text source) + 20 (RewardEvent capture → SQLite, Alerts' persistence half) open; 17 (Alerts) is DONE via TASK 43 (2026-09-24) — native six-event alert box
- TASK 9 — item 5 open (webcam identity key reconciliation)
- TASK 10 — Velopack update URL pending
- TASK 12 — queued future
- TASK 13 — queued post-v1
- TASK 14 — Branch 2 shipped; branch 3+ in progress
- TASK 21 — UI picker slice remaining (Windows-only verification pending)
- TASK 32–36 — all queued future work (2026-09-01)
- Webcam resource lifecycle (2026-09-17) — startup slice shipped (OS poll at start, single-camera auto-lock, persistent red alert in the Layers panel on lock failure, re-polls until resolved); gate slice shipped same day — webcam = app-level default, one per stream per scene, Add places the default directly, offered only when a camera is ATTAINABLE (identity + live session, not just a saved identity), app base lock keeps the session after the last placement is removed, startup adopts a solo camera as default. TASK 26's app-wide gate superseded by creator directive. The App Settings webcam selector is now TASK 40 Unit A (plan saved 2026-09-22). Remaining next slice (user-queued): static (+) catalog rows (Background, YouTubeEvent, quoted labels) with reason-greying.
- TASK 40 — App Settings round — plan saved 2026-09-22 (
TASKS/task-40-app-settings-round.md), four units, one Good Dog test each: A active web camera section under Recordings (Change… sub-menu = live enumeration incl. vcams; Tune… config dialog viaICameraControlProbe, live-only tweaks), B gear moved top-left right of the wordmark (left-click App Settings, right-click Bug/Feature/About), C persist output resolution default + surface default scene transition/duration + confirm-before-End, D accent/theme color (consolidate 69 hardcoded accent sites into a DynamicResource brush + picker). Unit B (gear) is DONE early — shipped 2026-09-22 as part of TASK 42 (top bar redesign): gear top-right of the brand, single click = the Settings/Bug/ Feature/About menu, removed from BottomBar. A + C + D remain queued. - TASK 37 — queued (2026-09-20): split the layout data into a
defaultset (the established DB) and acurrentset carrying the build-id; a savedcurrentis honored only by the same build-id, otherwise defaults load — enables one-click revert to defaults too. Capture needed work OUT of current scope here; do not bolt it onto an in-flight change. - TASK 41 — Test Stream mode — DONE 2026-09-22 (
TASKS/task-41-test-stream-mode.md): a Test button next to Start runs the real private-only go-live pipeline withIsTestStreamset, and the TEST drawer (right rail, third tab) hosts Mock Chat Input (realliveChat/messages.insert→ ~2s poll round-trip renders on the overlay) + simulated Subscriber/New Member/Super Chat events that inject through the poller'sMessageReceivedseam (IsSimulated— YouTube's insert API only creates text, so these are local-only by design; styled member/SuperChat rows validate the chat overlay). Real Stinger/TTS alert widgets resolved by TASK 43's native alert box. - TASK 43 — Native events & alerts — DONE 2026-09-24 (
TASKS/task-43-native-alerts.md): StreamElements replaced with NATIVE YouTube events. Chat parity half:YouTubeChatServicenow decodes all SIXliveChat/messagesevent types (ChatEventKindonChatMessage) — the four formerly-empty event rows fixed — and re-arms its poll on the server'spollingIntervalMillis(streamList semantics, clamp 1000–6000ms,maxResults=2000). Alerts half: a newSourceType.AlertBox("Stream Alerts", one per layout) is an OBS-style celebration zone where the six events play six unique branded animations (AlertRenderer+ theAlertOverlayLayercomponent; 33ms ticker, deterministicAdvancetest clock; idle = transparent). Creator rulings baked in: free-sub mention = chat row only (no sub alert — YouTube emits none), NO viewer count, every alert card carries the "made with LlamaCasty!" brand line. - TASK 44 — TEST-tab chat fix — DONE 2026-09-25 (
TASKS/task-44-test-chat-fix.md): the open creator report ("I still cannot post a chat message in the TEST tab") was a single cause:GetBroadcastLiveChatIdAsyncreadcontentDetails.liveChatId(lifeChatId lives insnippet) AND ran before the broadcast was live (RTMP push flips ready→live via enableAutoStart; YouTube only populates the id on live broadcasts — official GetLiveChatId.java sample lists broadcastStatus=active). Fixed by readingsnippet.liveChatIdand polling with a bounded retry after the frame pump starts; chat stays non-fatal.
YouTube Live API research facts
See TASKS/research-youtube-api.md — authoritative facts for v3 build.
Out of product — permanently
These were explicitly ruled out:
- D3D11 swap compositor (superseded by software compositor; TASK 3 item 16)
- Background removal (ONNX/DirectML; TASK 3 item 19)
- OBS-style source expansion (game capture, browser source, media playlist, VLC, color-key, MIDI — the minimal source set is deliberate; creators who need more have graduated to OBS)
- Multi-layout (auto-save, single layout; multi-layout = OBS territory)
- Cross-process stream resume (API makes it impossible; creator ruling 2026-09-01)