Skip to content

feat(studio): drag automation segments - #3465

Merged
vanceingalls merged 4 commits into
mainfrom
feat/automation-segment-drag
Aug 24, 2026
Merged

feat(studio): drag automation segments#3465
vanceingalls merged 4 commits into
mainfrom
feat/automation-segment-drag

Conversation

@vanceingalls

Copy link
Copy Markdown
Collaborator

Summary

  • make the line between adjacent automation points draggable, moving both endpoints together
  • thicken automation segments on hover to communicate the drag affordance
  • preserve segment shape while clamping movement to the lane value bounds
  • clear selected clips when opening an audio group effects rack so stale clip selection cannot reclaim the panel

Validation

  • 129 focused Studio tests
  • Studio TypeScript typecheck
  • oxlint and oxfmt
  • fallow audit against main

Preview

Open the local Studio composition at http://127.0.0.1:5194/#project/automate-lineage

@somanshreddy somanshreddy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE — verified at 51d5396a. Traced both concerns to source; clean.

Concern A — segment drag (the feature)

  • Geometry refactor is behavior-preserving. envelopePath's inner loop was extracted to segmentLineCommands; the new Array.from({length: DRAW_SAMPLES}, (_, sample) => … (sample+1)) reproduces the old for k=1..DRAW_SAMPLES exactly (same sample points, same straight-line shortcut on !curve && viaX===undefined && scale==="linear", [] for the skip case matches the old continue). envelopePath is on the core render path for every lane, so this equivalence mattered — it holds.
  • Drag math reuses the proven group-move path. armSegmentDrag snapshots endpoints [i, i+1] with the pointer as anchor (no jump), then computeGroupMove does the translation + clamp. Tests cover every class that matters: equal Δt/Δv on both endpoints, viaX/viaY curve preserved through the translate, neighbor clamp stops the pair at next.t − MIN_POINT_GAP_SEC while preserving the segment's own width, preview-per-move + commit-once-on-release.
  • Precedence is right: point-grab wins over segment-grab; Alt→curve (span-wide hit), unmodified→segment (only within SEGMENT_GRAB_PX=5 of the drawn line); a press >5px off the line still falls through to a background range drag (test confirms). Read-only suppresses hover + cursor correctly.

Concern B — audio-group FX rack / stale clip reclaim

The load-bearing question was the ordering: the bus selection clears the clip selection (the new hf-audio-group branch in domSelectionTimelineMirror), and the fix relies on publishing the reveal after that clear so revealTargetsSelection (playerStore:533) doesn't nix it. That ordering is guaranteed by construction: handleTimelineElementSelect awaits the selection build, then applyDomSelectionannounceTimelineSelection → the clip-clear all run synchronously before the async fn's promise resolves (useDomSelection.ts:389‑393). openGroupFxRack's selection.then(() => revealAudioFx(…)) therefore fires on a strictly-later microtask than the clear — the fresh reveal survives. revealedAudioFxTarget has real consumers (useAudioFxRevealSection, propertyPanelAudioFxGroup), so it's a live write, not a dead one.

Non-blocking notes

  1. Test depth on the B ordering. Both new tests (TimelineGroupRow, useDomSelectionSelectionGuards) mock handleTimelineElementSelect, so the select→clip-clear→reveal microtask sequence that makes the fix correct isn't actually exercised — the guarantee rests on the sync/await structure above (which I verified) and manual validation. An integration-level test driving the real handleTimelineElementSelect → reveal-survives sequence would lock the contract against a future refactor that makes applyDomSelection async.
  2. Cosmetic: when a stretch-edge hover and a segment-grab hover coincide, laneCursor correctly shows col-resize (stretch wins), but segmentHoverIndex still thickens the segment — cursor and highlight momentarily disagree. Harmless.

Nothing blocking.

@vanceingalls
vanceingalls merged commit 7caf4b8 into main Aug 24, 2026
47 checks passed
@vanceingalls
vanceingalls deleted the feat/automation-segment-drag branch August 24, 2026 19:44
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.

2 participants