Commit 738904e
feat(dashboard): 10ft UI — iPad/tvOS-style home + go-proxy playback (#438)
## Summary
Adds a TV/iPad-style "10ft UI" to the dashboard — two new pages modeled
on the iOS/tvOS app's Home + Playback screens. Existing Mosaic
(`grid.html`) is untouched.
- **`/dashboard/mosaic-10ft.html`** — Home: 16:9 hero pane on top +
CSS-grid LIVE row of preview tiles (0–16, user-tunable). Left-click tile
swaps to hero (preview-only), right-click tile or click hero starts
full-screen playback. Slide-in TV-style settings drawer (46vw / 78vw,
240ms ease-out). Keyboard: ↑/↓ between hero ↔ strip, ← → moves tile
focus, **Enter** swaps tile→hero or plays the hero, **S** settings,
**F** fullscreen, **?** help.
- **`/dashboard/play-10ft.html`** — Full-screen playback through
go-proxy with native HTML5 controls. Big 56×56 icon top bar: ‹ Back · 🔄
Reload · ↻ Restart · 🚨 911 · ⚙︎ Settings. TV-style nested drawer with
main list (Stream / Protocol / Codec / Segment / Max Res / Advanced) →
sub-pages with checkmark selection rows + back chevron. HUD overlay
(Engine / State / Resolution / Bitrate / Buffer / Live offset / Dropped
frames / Stalls, 1 Hz). Lean hls.js / Shaka config (`enableWorker:
true`, default ABR ramp from low variant) to keep cold-start CPU low.
- `content/shared/shared-nav.js` adds the **📺 10ft UI** sidebar entry.
- `content/dashboard/dashboard.html` adds a 10ft UI card link.
- `PRD.md` §7.2 — new "Mosaic (10ft)" bullet.
Reuses the existing `ismSelected*` localStorage keys for cross-page
state, and the same Shaka / hls.js / native HLS init shapes as
`grid.html`. `play-10ft.html` builds the manifest URL through go-proxy
(`<ui-port-prefix>081`) using the same shape as `grid.html`'s
testing-window helper.
## Pre-commit review
Ran `code-reviewer` (Sonnet) on the staged diff. Three real issues found
and fixed in this commit before push:
1. **`loadHero()` race** — added a monotonic `heroLoadGen` counter so
rapid overlapping calls (fast tile clicks) can't land two engines on the
same `<video>`. Same guard added on `play-10ft.html`'s `loadStream()`
for Reload/Restart spam.
2. **Drawer Tab-trap fired when drawer closed** — added `if
(!drawerOpen) return;` guard on both pages.
3. **Hero leak on empty filter** — `setHeroFromInitial()` now calls
`destroyHero()` when nothing resolves, preventing a stale hero engine
from continuing to decode.
Other reviewer feedback (`shaka.polyfill.installAll()` redundancy, drift
between mosaic-10ft and play-10ft) is acknowledged as deferred-for-v1
per CLAUDE.md ("Don't add features, refactor, or introduce abstractions
beyond what the task requires"). A shared module is the right move once
a third caller appears.
## Test plan
- [x] Hand-tested on `test-deploy-dev`
(`http://jonathanoliver-ubuntu.local:21000/dashboard/mosaic-10ft.html`)
— hero focus on entry, ↑/↓ between hero and strip, ← → tile focus wraps,
Enter swaps and plays correctly.
- [x] Right-click tile lands on `play-10ft.html` with go-proxy URL
routed via `:21081`.
- [x] Settings drawer opens / closes / Tab-trap behaves; preview-pane
counter applies and resizes the grid.
- [x] play-10ft Reload / Restart / 911 each behave correctly; Advanced
toggles persist; HUD updates at 1 Hz.
- [x] Existing `grid.html` unchanged — no regression on the original
Mosaic page.
- [x] CPU usage during cold-start playback now comparable to
`testing-session.html` (Web Worker + default ABR ramp).
- [ ] Cross-compare with `testing-session.html` — N/A, no edits to
testing pages.
Closes #434
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 770d1ef commit 738904e
5 files changed
Lines changed: 3550 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
147 | 147 | | |
148 | 148 | | |
149 | 149 | | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
150 | 155 | | |
151 | 156 | | |
152 | 157 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
107 | 107 | | |
108 | 108 | | |
109 | 109 | | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
110 | 113 | | |
111 | 114 | | |
112 | 115 | | |
| |||
0 commit comments