Skip to content

feat(studio): asset click policy and canvas nudge gate#2200

Open
ukimsanov wants to merge 1 commit into
studio-dnd/pr08-timeline-zonesfrom
studio-dnd/pr09-asset-click-nudge-policy
Open

feat(studio): asset click policy and canvas nudge gate#2200
ukimsanov wants to merge 1 commit into
studio-dnd/pr08-timeline-zonesfrom
studio-dnd/pr09-asset-click-nudge-policy

Conversation

@ukimsanov

@ukimsanov ukimsanov commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

What

two small pure modules with tests — assetClickBehavior (click vs double-click policy for sidebar assets) and canvasNudgeGate (debounce gate for arrow-key canvas nudges).

Why

policy dependencies of the upcoming asset card and nudge hook, reviewable as plain decision tables.

How

new files only.

Test plan

bunx vitest run on both test files; tsc --noEmit; fallow audit clean.


Stack position 9/25 — studio NLE overhaul (CapCut-parity timeline + canvas). Graphite manages bases; merge from #2192 upward. Temporary TEMP(studio-dnd) fallow entries (unwired-component windows) are all removed by #2213 (app-shell swap), whose tree is byte-identical to the fully-verified integration branch.

ukimsanov commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@ukimsanov ukimsanov force-pushed the studio-dnd/pr08-timeline-zones branch from f26cdeb to 95e9ca4 Compare July 11, 2026 00:55
@ukimsanov ukimsanov force-pushed the studio-dnd/pr09-asset-click-nudge-policy branch 2 times, most recently from af9f377 to fc4382f Compare July 11, 2026 01:15
@ukimsanov ukimsanov force-pushed the studio-dnd/pr08-timeline-zones branch from 95e9ca4 to d0aa2e0 Compare July 11, 2026 01:15

@miga-heygen miga-heygen 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.

Reviewed as part of the 25-PR NLE overhaul stack. Full stack review on #2205 (the keystone). No blockers on this PR. — Miga

@vanceingalls vanceingalls left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Verdict: LGTM (green) — small, sharp, correctly bounded

Two pure helpers plus a module-level singleton claim gate. The scope is deliberately narrow; each unit is exercised at its edges. No unit-consistency traps (both files are pixel-only or dimensionless).

The pointed queries

  • Click-vs-drag threshold (fair tie-break). packages/studio/src/utils/assetClickBehavior.ts:73–:75isPointerClick(dx, dy) = Math.abs(dx) < 4 && Math.abs(dy) < 4. Strict < at the boundary; exactly 4px is a drag, not a click. Deterministic and symmetric across axes. Test at :94–:98 pins the boundary in both directions (positive AND negative displacement); :100–:103 confirms the sign symmetry.
  • findClipForAsset — matcher normalisation. :43–:61 handles the four src shapes documented by deriveUsedPaths (absolute URL, /api/projects/.../preview/..., ./-prefixed, bare relative), plus query-string stripping and percent-decode. Every shape has a dedicated test at :26–:60. The earliest start deterministic pick at :62–:67 avoids returning an arbitrary duplicate. Robust.
  • Nudge gate — nesting semantics. packages/studio/src/utils/canvasNudgeGate.ts:10–:26 — module-level claims: number counter; acquireCanvasNudgeKeys() returns an idempotent release closure that decrements at most once. Test at :16–:24 verifies double-release is a no-op (guarded by the released flag at :16). Correct for nested overlays.
  • Wiring with #2203 (canvas nudge math). No direct import at these PR SHAs — canvasNudgeGate.ts doesn't reference domEditNudge.ts and vice versa. That's expected: this PR ships the gate, #2203 ships the delta math, and a downstream PR (per .fallowrc.jsonc markers, studio-dnd/pr22) wires both into DomEditOverlay. As long as the eventual consumer acquires the gate BEFORE binding its arrow-key listener and releases it on unmount, the ownership arbitration between DomEditOverlay and usePlaybackKeyboard (documented at :5–:8) will hold. No coupling to inspect here.

Nits (non-blocking)

  • The module-level claims counter in canvasNudgeGate.ts persists across tests within a Vitest worker. Currently both tests clean up to zero, but there is no beforeEach(() => { /* reset */ }) — if a future test throws mid-way and leaks a claim, the next test's initial expect(claimed()).toBe(false) would fail without an obvious signal. A beforeEach guard, or exposing a __resetForTests() helper, would future-proof this. Cosmetic — the current tests happen to be well-behaved.

R1 by Via

@ukimsanov ukimsanov force-pushed the studio-dnd/pr08-timeline-zones branch from d0aa2e0 to b3f0ed0 Compare July 11, 2026 02:56
@ukimsanov ukimsanov force-pushed the studio-dnd/pr09-asset-click-nudge-policy branch 2 times, most recently from 8e77fb1 to ba28195 Compare July 11, 2026 08:18
@ukimsanov ukimsanov force-pushed the studio-dnd/pr08-timeline-zones branch from b3f0ed0 to 41f7e1d Compare July 11, 2026 08:18
@ukimsanov ukimsanov marked this pull request as ready for review July 11, 2026 09:06
@ukimsanov ukimsanov force-pushed the studio-dnd/pr09-asset-click-nudge-policy branch from ba28195 to ab2e3db Compare July 11, 2026 10:49
What: two small pure modules with tests — assetClickBehavior (click vs
double-click policy for sidebar assets) and canvasNudgeGate (debounce gate
for arrow-key canvas nudges).

Why: policy dependencies of the upcoming asset card and nudge hook,
reviewable as plain decision tables.

How: new files only.

Test plan: bunx vitest run on both test files; tsc --noEmit; fallow audit
clean.
@ukimsanov ukimsanov force-pushed the studio-dnd/pr09-asset-click-nudge-policy branch from ab2e3db to b88fb09 Compare July 11, 2026 12:51
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.

3 participants