Commit Graph

7 Commits

Author SHA1 Message Date
Claude
48e15ee013 feat(06-02): add segment overlay canvas rendering and click interaction
- Create lightsync/frontend/timeline/segments.js with SegmentOverlay class
- Integrate SegmentOverlay into timeline.js render pipeline (between row banding and waveform)
- Add loadSegments method to TimelineCanvas
- Wire loadSegments call in app.js loadedmetadata handler
2026-04-07 11:41:41 +00:00
Claude
8e084ca8dc feat(04-04): wire BlockInspector into timeline and app.js
- app.js imports BlockInspector and DeleteBlockCommand
- Inspector created with #block-inspector element and timeline.history
- timeline._onSelectBlock callback shows/hides inspector on block select
- inspector._onDelete fires DeleteBlockCommand and hides inspector
- inspector.tracks kept in sync after loadTracks() resolves
- timeline.js block rendering uses blockColor + '1a' for color accent fill
- undo/redo handlers re-trigger _onSelectBlock to refresh inspector values
2026-04-06 23:54:22 +00:00
Claude
e82fc4a775 feat(04-04): add UpdateParamsCommand + BlockInspector module
- UpdateParamsCommand with execute/undo for color/speed/direction/length
- Uses module-level currentShowId (not this._showId) matching existing pattern
- BlockInspector renders compact strip with animation label, color swatch,
  speed input, direction select, length input, and remove button
- Color change committed on 'change' event (not 'input') to avoid command flood
- _onDelete callback wired to remove button for app.js to handle
2026-04-06 23:51:48 +00:00
Claude
287fe16a56 feat(04-03): BeatGrid module + enhanced beat rendering + loading states
- Create beats.js with BeatGrid class: load(), getCalibratedBeats(), getCalibratedOnsets(), snap(), hasBeats getter
- BeatGrid manages calibrationOffset and snapEnabled state
- snap() uses 100ms threshold against calibrated beat positions
- Handles API field variants: beats/beat_times, tempo/tempo_bpm
- Refactor timeline.js: replace beatTimes/calibrationOffset/snapEnabled with this.beatGrid
- Add getters/setters for calibrationOffset and snapEnabled (backward compat with app.js)
- render() now shows DETECTING BEATS... loading indicator and error state
- render() draws beat marks via getCalibratedBeats(), onset ticks via getCalibratedOnsets()
- snapToBeat() delegates to beatGrid.snap()
- app.js chains BPM label update after loadBeats() resolves
2026-04-06 23:48:27 +00:00
Claude
7e18ac6c84 feat(04-02): wire block interactions into TimelineCanvas
- Import CommandHistory and all 4 command classes from new modules
- hitTest() with 8px EDGE for resize-left/resize-right/move zones
- _hasOverlap() check for time range collision on same track
- snapToBeat() with 0.1s threshold and calibrationOffset
- _setupInteractions() with mousedown/mousemove/keydown listeners
- _startMove(): live drag preview, snap on mouseup, overlap rejection
- _startResize(): left/right edge handles, 0.5s min duration, snap
- handleDrop(): place block from palette with crypto.randomUUID()
- Keyboard: Delete, Ctrl+Z (undo), Ctrl+Shift+Z / Ctrl+Y (redo)
- app.js: dragstart on palette, dragover/dragleave/drop on canvas
- Ghost block rendered during dragover for visual feedback
- Resize handle indicators drawn on selected block
2026-04-06 23:44:45 +00:00
Claude
658c92f94d feat(04-02): command pattern + CommandHistory + block CRUD backend
- CommandHistory class with execute/undo/redo, 50-step max, redo-clear on new action
- PlaceBlockCommand, MoveBlockCommand, ResizeBlockCommand, DeleteBlockCommand
- setCurrentShowId() module-level function for backend sync routing
- syncBlock() fire-and-forget fetch helper for backend sync
- POST/PATCH/DELETE /api/shows/{show_id}/tracks/{device_id}/blocks endpoints
- timeline router registered in main.py with prefix=/api
2026-04-06 23:37:29 +00:00
Claude
efa612380c feat(04-01): TimelineCanvas class + CSS + app.js wiring
- Create lightsync/frontend/timeline/timeline.js with TimelineCanvas class
  - Per-device horizontal tracks with track headers and time axis
  - HiDPI canvas rendering with devicePixelRatio handling
  - Waveform peaks background layer, beat marks overlay, cue block rendering
  - Playback cursor synced to audio.currentTime via requestAnimationFrame
  - Auto-scroll when cursor approaches right edge
  - Mouse wheel scrolling on timeline canvas
  - loadTracks(), loadWaveform(), loadBeats() data loading methods
  - Empty state messages when no devices or audio loaded
- Add timeline CSS to style.css (toolbar, canvas, inspector strip, snap button)
- Wire timeline into app.js: import, initTimeline(), zoom/beat-offset/snap controls
- Remove old animation-grid click listener (element no longer exists in main-area)
- Populate animation palette dynamically in sidebar with 7 animation types
2026-04-06 23:34:32 +00:00