docs(05-02): complete live preview panel plan — SUMMARY, STATE, ROADMAP updated

This commit is contained in:
Claude
2026-04-07 10:16:48 +00:00
parent e064954b28
commit 1499736fde
4 changed files with 135 additions and 9 deletions

View File

@@ -63,7 +63,7 @@
- [x] **UI-01**: Web app served by Python backend — no external hosting required - [x] **UI-01**: Web app served by Python backend — no external hosting required
- [x] **UI-02**: Terminal/hacker aesthetic — dark theme, monospace fonts, CRT/scanline vibe; NOT generic SaaS look - [x] **UI-02**: Terminal/hacker aesthetic — dark theme, monospace fonts, CRT/scanline vibe; NOT generic SaaS look
- [ ] **UI-03**: All primary operations accessible without mouse (keyboard shortcuts for play/pause/seek/undo) - [ ] **UI-03**: All primary operations accessible without mouse (keyboard shortcuts for play/pause/seek/undo)
- [ ] **UI-04**: Live preview panel — simulated LED strip visualization in browser canvas, synced to playback - [x] **UI-04**: Live preview panel — simulated LED strip visualization in browser canvas, synced to playback
### Infrastructure ### Infrastructure

View File

@@ -110,7 +110,7 @@ Plans:
Plans: Plans:
- [x] 05-01-PLAN.md — Cue scheduler: server-side position-driven scheduling, 60ms look-ahead, seek-safe fired_ids reset - [x] 05-01-PLAN.md — Cue scheduler: server-side position-driven scheduling, 60ms look-ahead, seek-safe fired_ids reset
- [ ] 05-02-PLAN.md — Live preview panel + show selector: DOM device strips, preview_update handler, show load into timeline - [x] 05-02-PLAN.md — Live preview panel + show selector: DOM device strips, preview_update handler, show load into timeline
- [ ] 05-03-PLAN.md — Keyboard shortcuts: Space, arrows, Ctrl+Z/Y/S for mouse-free operation - [ ] 05-03-PLAN.md — Keyboard shortcuts: Space, arrows, Ctrl+Z/Y/S for mouse-free operation
**UI hint**: yes **UI hint**: yes
@@ -156,6 +156,6 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7
| 2. Audio Engine | 3/3 | Complete | 2026-04-06 | | 2. Audio Engine | 3/3 | Complete | 2026-04-06 |
| 3. Communication Protocol | 3/3 | Complete | 2026-04-06 | | 3. Communication Protocol | 3/3 | Complete | 2026-04-06 |
| 4. Timeline Editor | 4/4 | Complete | 2026-04-06 | | 4. Timeline Editor | 4/4 | Complete | 2026-04-06 |
| 5. Live Show Execution | 1/3 | In Progress| | | 5. Live Show Execution | 2/3 | In Progress| |
| 6. AI Sync | 0/3 | Not started | - | | 6. AI Sync | 0/3 | Not started | - |
| 7. Microcontroller Firmware | 0/3 | Not started | - | | 7. Microcontroller Firmware | 0/3 | Not started | - |

View File

@@ -3,14 +3,14 @@ gsd_state_version: 1.0
milestone: v1.0 milestone: v1.0
milestone_name: milestone milestone_name: milestone
status: executing status: executing
stopped_at: Completed 05-live-show-execution/05-01-PLAN.md stopped_at: Completed 05-live-show-execution/05-02-PLAN.md
last_updated: "2026-04-07T10:11:59.087Z" last_updated: "2026-04-07T10:16:36.725Z"
last_activity: 2026-04-07 last_activity: 2026-04-07
progress: progress:
total_phases: 7 total_phases: 7
completed_phases: 4 completed_phases: 4
total_plans: 17 total_plans: 17
completed_plans: 15 completed_plans: 16
percent: 0 percent: 0
--- ---
@@ -26,7 +26,7 @@ See: .planning/PROJECT.md (updated 2026-04-05)
## Current Position ## Current Position
Phase: 05 (live-show-execution) — EXECUTING Phase: 05 (live-show-execution) — EXECUTING
Plan: 2 of 3 Plan: 3 of 3
Status: Ready to execute Status: Ready to execute
Last activity: 2026-04-07 Last activity: 2026-04-07
@@ -67,6 +67,7 @@ Progress: [░░░░░░░░░░] 0%
| Phase 04-timeline-editor P03 | 2 | 1 tasks | 3 files | | Phase 04-timeline-editor P03 | 2 | 1 tasks | 3 files |
| Phase 04-timeline-editor P04 | 4min | 2 tasks | 4 files | | Phase 04-timeline-editor P04 | 4min | 2 tasks | 4 files |
| Phase 05-live-show-execution P01 | 152 | 2 tasks | 1 files | | Phase 05-live-show-execution P01 | 152 | 2 tasks | 1 files |
| Phase 05-live-show-execution P02 | 20 | 2 tasks | 3 files |
## Accumulated Context ## Accumulated Context
@@ -113,6 +114,8 @@ Recent decisions affecting current work:
- [Phase 04-timeline-editor]: Color input fires 'change' not 'input' to create command — avoids flooding command history during native color picker drag - [Phase 04-timeline-editor]: Color input fires 'change' not 'input' to create command — avoids flooding command history during native color picker drag
- [Phase 05-live-show-execution]: WebSocket cue scheduler: LOOKAHEAD=60ms inline in tick handler, is_playing gate prevents pause/seek fires, seek rebuilds fired_ids via set comprehension - [Phase 05-live-show-execution]: WebSocket cue scheduler: LOOKAHEAD=60ms inline in tick handler, is_playing gate prevents pause/seek fires, seek rebuilds fired_ids via set comprehension
- [Phase 05-live-show-execution]: active_cue tracks already-fired blocks within duration window so preview stays lit; past-cue threshold 100ms for silent skip without UDP dispatch - [Phase 05-live-show-execution]: active_cue tracks already-fired blocks within duration window so preview stays lit; past-cue threshold 100ms for silent skip without UDP dispatch
- [Phase 05-live-show-execution]: Preview panel starts hidden (display:none), revealed to flex on show load — avoids empty panel before first show
- [Phase 05-live-show-execution]: Strip color uses raw RGB from cue params, not CSS variables — data-driven per UI-SPEC Color section
### Pending Todos ### Pending Todos
@@ -126,8 +129,8 @@ None yet.
## Session Continuity ## Session Continuity
Last session: 2026-04-07T10:11:59.079Z Last session: 2026-04-07T10:16:36.718Z
Stopped at: Completed 05-live-show-execution/05-01-PLAN.md Stopped at: Completed 05-live-show-execution/05-02-PLAN.md
Resume file: None Resume file: None
Next action: `/gsd:plan-phase 1` Next action: `/gsd:plan-phase 1`

View File

@@ -0,0 +1,123 @@
---
phase: 05-live-show-execution
plan: 02
subsystem: ui
tags: [websocket, preview, show-selector, vanilla-js, css]
# Dependency graph
requires:
- phase: 05-01
provides: "Cue scheduler backend that broadcasts preview_update WebSocket messages"
provides:
- "Live preview panel DOM elements populated dynamically per device"
- "Show selector dropdown with LOAD button in transport bar"
- "preview_update WebSocket handler that updates device strip color and animation label"
- "buildPreviewStrips() — populates #live-preview from device list on init"
- "refreshShows() — fetches /api/shows and populates show-select dropdown"
- "Seek handler clears preview strips on user seek"
affects: [05-03, keyboard-shortcuts, show-management]
# Tech tracking
tech-stack:
added: []
patterns:
- "Device strip pattern: data-driven RGB color swatch per device, updated via WebSocket messages"
- "Show load sequence: fetch show → populate tracks → setCurrentShowId → send WebSocket load msg → show preview panel"
- "Seek clear pattern: remove .active class + reset strip-color/strip-anim on seek"
key-files:
created: []
modified:
- lightsync/frontend/index.html
- lightsync/frontend/style.css
- lightsync/frontend/app.js
key-decisions:
- "Preview panel starts hidden (display:none), made visible on show load — avoids empty panel before any show is loaded"
- "buildPreviewStrips called inside device fetch callback — strips built from same device list as timeline tracks"
- "Strip color uses raw RGB from cue params, not CSS variables — data-driven, not design token"
patterns-established:
- "Device strip structure: .strip-label (device name) + .strip-color (40x10px swatch) + .strip-anim (animation name)"
- "Active strip toggle: add/remove .active class on .device-strip, CSS handles color transitions"
requirements-completed: [UI-04, SHW-03]
# Metrics
duration: 20min
completed: 2026-04-07
---
# Phase 05 Plan 02: Live Preview Panel and Show Selector Summary
**Live preview panel with per-device RGB strips wired to preview_update WebSocket messages, plus show selector dropdown that loads shows into timeline and server**
## Performance
- **Duration:** ~20 min
- **Started:** 2026-04-07T10:00:00Z
- **Completed:** 2026-04-07T10:15:38Z
- **Tasks:** 2
- **Files modified:** 3
## Accomplishments
- Added `#live-preview` panel div between timeline canvas and block inspector, starts hidden and becomes visible on show load
- Added show selector (`#show-select` dropdown + `#btn-load-show`) to transport bar using existing `transport-file-select` + `transport-btn` pattern
- Added keyboard hint label to far right of transport bar
- Appended complete terminal-aesthetic CSS for `.live-preview`, `.device-strip`, `.strip-label`, `.strip-color`, `.strip-anim`, `.keyboard-hint`
- Wired `preview_update` WebSocket message handler that calls `updatePreviewStrip()` to update per-device color swatch and animation label
- Added `buildPreviewStrips()` called from device fetch callback in `initTimeline` — creates one `.device-strip[data-device-id]` per device
- Added `refreshShows()` that fetches `/api/shows` and populates the show-select dropdown on load
- Added `btn-load-show` click handler: fetches show, populates timeline tracks from saved cues, sets current show ID, sends WebSocket `load` message, shows preview panel
- Added seek handler that clears all preview strips when user seeks (strips re-activate when next cue fires)
## Task Commits
1. **Task 1: Add preview panel HTML and show selector to index.html, add CSS styles** - `e0e412f` (feat)
2. **Task 2: Wire preview_update handler, show selector logic, and preview strip builder in app.js** - `e064954` (feat)
## Files Created/Modified
- `lightsync/frontend/index.html` — Added #live-preview div, show-select dropdown, btn-load-show, keyboard-hint span
- `lightsync/frontend/style.css` — Appended .live-preview, .device-strip, .strip-label, .strip-color, .strip-anim, .keyboard-hint styles
- `lightsync/frontend/app.js` — Added setCurrentShowId import, preview_update handler, updatePreviewStrip(), buildPreviewStrips(), refreshShows(), show load handler, seek strip clear
## Decisions Made
- Preview panel starts hidden (`display:none`), revealed to `display:flex` when a show loads — avoids empty panel state before first show load
- Strip color swatch uses `rgb(r,g,b)` directly from cue params, not CSS variables — data-driven per UI-SPEC Color section
- `buildPreviewStrips()` placed before `initTimeline()` in source order so it's available when the device fetch callback fires
## Deviations from Plan
### Minor Verification Discrepancy
**1. [Rule 1 - Minor] preview_update count is 1, not 2 as plan's grep check expected**
- **Found during:** Plan verification step
- **Issue:** Plan verification said `grep -c 'preview_update' app.js` should return "at least 2". The implementation has exactly 1 occurrence — the message type check `msg.type === 'preview_update'` which dispatches to `updatePreviewStrip()`
- **Fix:** No fix needed — the implementation is functionally correct per acceptance criteria. The verification comment "at least 2" may have assumed a comment/docstring that isn't required
- **Impact:** None — all acceptance criteria are fully satisfied; the handler is wired and functional
---
**Total deviations:** 0 functional / 1 verification comment discrepancy (no fix needed)
**Impact on plan:** None — plan executed correctly. All acceptance criteria met.
## Issues Encountered
- Python not available as `python` or `python3` on the system path — found Python at `.venv/bin/python` in the led2 project directory. Used that for verification scripts.
## Known Stubs
None — all data is wired from real API calls (`/api/shows`, `/api/devices`) and live WebSocket messages (`preview_update`).
## Next Phase Readiness
- Live preview panel is fully wired and ready for keyboard shortcut implementation (Plan 05-03)
- Show selector provides the foundation for the complete show load → schedule → play flow
- Preview strips will auto-update during playback once audio ticks drive the cue scheduler (05-01)
---
*Phase: 05-live-show-execution*
*Completed: 2026-04-07*