Skip to content

feat: sortable asset panel with droppable timeline lanes - #77

Merged
thisiscsim merged 2 commits into
mainfrom
feat/panel-sortable-assets
Aug 7, 2026
Merged

thisiscsim merged 2 commits into
mainfrom
feat/panel-sortable-assets

Conversation

@thisiscsim

Copy link
Copy Markdown
Owner

Summary

  • Assets-tab clip cells and audio rows are now dnd-kit Sortable items (useSortable, per-family groups panel-clips / panel-audio, keyboard plugin kept) — drag over a sibling to reorder, drag onto the timeline to insert. Timeline lanes stay plain Droppable targets.
  • OptimisticSortingPlugin is deliberately omitted after reading its source: it physically reorders sibling DOM nodes whenever the pointer crosses a cell (which the drag-out-to-timeline gesture always does) and only restores those mutations on canceled drags — a successful lane drop would leave the grid visually shuffled against React state. Without it, React state is the single source of order and there is exactly one commit point (dragend on a same-group sibling).
  • Reorders resolve by asset id rather than captured indices, so a live EDL reload mid-drag (agent write, undo) can't misplace anything; the commit goes through updateEdl, so panel order persists to edl.json and participates in undo.
  • New pure helper reorderAssets re-fills only the moved family's slots in the interleaved edl.assets array (audio positions untouched when reordering clips, and vice versa), with arrayMove semantics and unit tests.
  • The two dragend monitors are disjoint by construction: lanes aren't sortable (panel handler returns), sortable targets carry no trackId (timeline handler returns). Cross-family drops are rejected via type/accept (clips accept video/image, audio rows accept audio).
  • @dnd-kit/dom added as an explicit app dependency (previously reached transitively) for the SortableKeyboardPlugin import; hovered reorder targets get an accent outline.

Test plan

  • npm run typecheck && npm test && npm run build green (150 tests, 4 new for reorderAssets)
  • Drag a clip cell over a sibling → accent outline on target, order commits on drop, undo reverts it
  • Drag a clip cell across siblings onto a video lane → inserts at pointer position, panel order unchanged
  • Reorder audio rows; drag an audio row onto the audio lane
  • Drag a clip over the audio list (and vice versa) → no drop affordance, no-op

Renderer-only change — HMR covers it, no dev restart needed.

Made with Cursor

thisiscsim and others added 2 commits August 7, 2026 12:26
… lanes

Panel clip cells and audio rows become useSortable items (per-family groups,
keyboard plugin kept) so they reorder within the panel and remain the drag
sources the droppable lanes accept. OptimisticSortingPlugin is deliberately
omitted: it shuffles sibling DOM nodes whenever a drag-out sweeps across the
grid and only restores them on *canceled* drags, so state stays the single
source of order and reorders commit once on drop — resolved by asset id
(live-reload safe) and persisted through updateEdl (undo + edl.json).

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@thisiscsim
thisiscsim merged commit 8037647 into main Aug 7, 2026
1 check passed
@thisiscsim
thisiscsim deleted the feat/panel-sortable-assets branch August 7, 2026 19:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant