Files
LlamaCasty/HANDOFF.md
T
gramps 4b9a8e515f Control Surface UX: pill toggle, background rename, per-scene properties
- Sliding pill toggle (green ON / red OFF) replaces checkbox
- Geometry mismatch error for custom backgrounds
- Backdrop -> Background: C# rename, SQL column rename with migration
- Source.IsBackground: new -> override (fixes WPF binding)
- Legacy 'Backdrop' display name migrated to 'Background'
- Per-scene UseDefaultBackground + CustomBackgroundPath
- Asset files renamed backdrop -> background
- StagedScene/LiveScene split, thumbnail strip, edit gating
- TransitionService (Cut/Fade/Move)
- Context menu: Capture Desktop, Refresh Desktop
- Resolution badge removed, ON-AIR status light added
2026-08-22 18:10:59 -07:00

114 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HANDOFF — Session State
## Branch
`main` — clean, last push `8951141` (TASK 10 shipped). TRAX meter fix pushed `e06bfa4`.
All Control Surface UX work is **uncommitted** — build passes 0 warnings/0 errors.
## ⚠️ IN FLIGHT: repo-wide Backdrop→Background rename (multi-session)
Models already renamed (`Source.IsBackground`, `Scene.HasBackground`/`CustomBackgroundPath`,
`SceneCatalog.HasBackground`, `Source` enum `Background`). Status per file:
- ✅ `ViewModels/MainViewModel.cs` — full case-sensitive rename done; compiles clean.
- ✅ `MainWindow.xaml.cs` + `MainWindow.xaml` — renamed; full solution builds 0 warnings/0 errors.
- ✅ `Services/Compositor/SceneCompositor.cs` — CS0128 duplicate locals fixed.
- ⏳ `Services/LayoutStore.cs` — C# members renamed, but DB column strings
(`HasBackdrop`/`IsBackdrop`) are **schema** and intentionally still say Backdrop:
renaming them needs a real migration (new user_version) touching every existing DB.
The V5-backfill unit test's raw CREATE TABLE must keep `IsBackdrop` to match —
blanket-renaming it breaks `V5_Database_Backfill_Removes_NonLive_Backgrounds`
(verified: migration can't see flags, Live source loses `IsBackground`).
- ✅ `ytLive.Tests` — all 5 files blanket-renamed (class/method/var/comment names +
C# property accesses); `BackdropTests.cs` → `BackgroundTests.cs`. Tests: 207/208 pass;
the only red is pre-existing `AudioPipelineTests.Mix_HonorsProviderGains_AndGameMute_KillsTheLoopback`
(unrelated gain-math assert at AudioPipelineTests.cs:373, zero backdrop occurrences).
- Pending elsewhere: leftover "backdrop" doc comments (`Source.cs`, `SceneCatalog.cs`,
`ScreenCaptureManager.cs`, `ScreenCaptureFrameSource.cs`, `MainWindow.xaml:769`),
asset files + csproj (`Assets/*-backdrop.jpg` — pack-URI strings in MainViewModel now say
`-background.jpg` so default-scene seeding silently no-ops until assets+csproj are renamed).
## What shipped this session
1. **TASK 10 — Polar billing + Velopack auto-updates (steps 1–7)** — full license key activation flow
2. **TRAX meter double-attenuation fix** — removed redundant slider multiplication
3. **LAN infrastructure documented** — all servers in `ai.md` + `CREDENTIALS.md`
4. **llamavault NFS/SMB diagnosis** — zombie SMB session from power outage, fixed by killing stale PID
## Active work: Control Surface UX (TASK 19/23 merged) — ALL PHASES COMPLETE
**Design philosophy:** Director's control surface, not an editor. Five scene monitors above one central live monitor. Click thumbnail = transition (live) or stage (offline). Edit mode only when offline. Live/Recording = read-only. Right-click + drag locked when live.
### Phases completed (ALL)
1. ✅ **Phase 1:** `StagedScene`/`LiveScene` split + `IsEditMode` in MainViewModel
2. ✅ **Phase 2:** Left panel two-state (edit: layers+props, live: chat)
3. ✅ **Phase 3:** Right panel eliminated
4. ✅ **Phase 4:** Thumbnail strip above center monitor + `Scene.Snapshot` + placeholder snapshots
5. ✅ **Phase 5:** Edit-mode gating (drag/resize/context menus blocked when live)
6. ✅ **Phase 6:** `TransitionService.cs` (Cut/Fade/Move) + `SceneCompositor.BlendFrames()`
7. ✅ **Phase 7:** `FramePump` integrated with `TransitionService`
8. ✅ **Phase 8:** Thumbnail click → `TransitionToScene()` wiring
9. ✅ **Phase 9:** Brand rename "ytLlive" → "LlamaCasty" (user-visible strings)
10. ✅ **Phase 10:** `LayoutStore.SaveTransitionSettings()` / `LoadTransitionSettings()`
### Key decisions
- **Mode is implicit:** offline = edit, live/recording = read-only. No toggle button.
- **Left panel = one panel, two states:** offline → LAYERS + PROPERTIES; live → YouTube Live Chat (entire panel replaced, never coexists)
- **No (=>) transition button:** clicking a thumbnail directly triggers the transition
- **Thumbnail glow:** active scene gets brand-red `#e94560` border via `IsStaged` data trigger
- **Right panel eliminated:** chat moved to left panel (live mode only)
- **5 thumbnails above center monitor**, 120px height, uniform grid. Placeholder colored boxes until compositor snapshots added.
- **Transitions:** Cut + Fade + Move (v1). Go Live always = Cut. Duration persisted to Settings table.
- **Brand rename:** "ytLlive" → "LlamaCasty" across all XAML, VM strings, service strings. File paths (`%APPDATA%\ytLlive\`) intentionally NOT renamed.
### Architecture changes
- `ActiveScene` → split into `StagedScene` (central monitor, editable) + `LiveScene` (encoder output, read-only)
- `IsEditMode` = derived property: `StreamStatus == StreamStatus.Offline`
- `TransitionService` — transition state machine with Start/Tick/BlendFrame
- `SceneCompositor.BlendFrames()` — crossfade between two VideoFrames
- `Scene.Snapshot` + `Scene.IsStaged` — thumbnail image and staged indicator
- `FramePump` — now accepts `TransitionService` + `fromSceneProvider`, blends during transitions
### Files changed
- `ViewModels/MainViewModel.cs` — StagedScene/LiveScene split, IsEditMode, TransitionToScene, snapshots, brand rename, transition persistence
- `MainWindow.xaml` — 2-col layout, thumbnail strip, left panel two-state, right panel deleted, brand rename
- `MainWindow.xaml.cs` — Thumbnail click, edit-mode gating, context menu gating, dead code cleanup
- `Models/Scene.cs` — Snapshot, IsStaged properties
- `Services/Compositor/SceneCompositor.cs` — BlendFrames() static method
- `Services/Encoder/FramePump.cs` — transition support in render loop
- `Services/TransitionService.cs` — **new** — Cut/Fade/Move transition engine
- `Services/LayoutStore.cs` — SaveTransitionSettings/LoadTransitionSettings/UpsertSetting
### What still needs testing
- Runtime visual testing (need Windows display to run)
- Actual transition animation quality (Fade + Move)
- Thumbnail generation from real scene compositor (currently placeholder colors)
- Drag-reorder of thumbnails (not yet implemented)
## Build
```bash
taskkill.exe /F /IM ytLive.exe # if running
"/mnt/c/Program Files/dotnet/dotnet.exe" build "C:\Users\gramp\Documents\Code\projects\ytLive\ytLive.csproj" --no-restore
```
**0 warnings, 0 errors.**
## Polar.sh resources
| Resource | ID |
|---|---|
| Org ID | `c05fb364-b967-4f6c-adf2-8a144e46d085` |
| Product | `d105dfa1-497e-423b-8cd4-e0ee2e3abbc0` |
| Price | `7c1b6f70-cf8c-46df-9bc8-6703f9fa64d0` |
| Benefit | `80f66bc1-d5a3-44a1-b9ea-1709ae508535` |
| Checkout | `70e037cd-9bcb-414e-8b26-c82c1d268f65` |
| Checkout URL | `https://buy.polar.sh/polar_cl_ueMy8AyAClO0o0yo19IroZwKTbD587gzUsjEW3bFapw` |
| Validate endpoint | `POST https://api.polar.sh/v1/customer-portal/license-keys/validate` |
| Key prefix | `LCYT-` |
## Next steps
1. **Visual testing** — run on Windows display, verify layout, transitions, thumbnail strip
2. **Thumbnail drag-reorder** — reorder scenes via drag on thumbnail strip
3. **Real snapshot generation** — replace placeholder colors with compositor-rendered thumbnails
4. **Transition dropdown UI** — add XAML control to pick transition type + duration
5. **Commit** — all this work needs to be committed once visually verified
## v1 vision
> A streaming tool that's intuitive and ready to go out-the-gate with nothing held back.
> Minimal configuration — they're ready to go live or record. Eliminate the OBS pain-point completely.