Skip to content

refactor(studio): simplify preview workspace layout#2756

Open
ukimsanov wants to merge 1 commit into
feat/media-treatment-studiofrom
feat/studio-preview-layout
Open

refactor(studio): simplify preview workspace layout#2756
ukimsanov wants to merge 1 commit into
feat/media-treatment-studiofrom
feat/studio-preview-layout

Conversation

@ukimsanov

Copy link
Copy Markdown
Collaborator

What

Updates Studio preview ergonomics: Design opens by default, large-screen panel proportions match the reviewed layout, resized widths persist, the timeline gets more default height, and preview transport controls are simplified.

Why

The preview had two competing seek surfaces and cramped default proportions. The timeline should own seeking while the preview keeps a compact transport bar.

How

Removes the duplicate preview seekbar and its dead drag helper, keeps play centered with unboxed utilities, and derives responsive panel defaults from viewport width while preserving existing narrow-screen minimums.

Test plan

  • Preferences, panel-layout, and NLE focused tests: 17/17
  • Complete Studio suite: 2734/2734 runnable tests, 18 existing todos
  • Studio typecheck, format, lint, tracked-artifact, file-size, and Fallow gates pass
  • Manual wide and narrow viewport checks performed
  • Exact six-PR stack passes the complete workspace build

Stack 6/6. Base: #2755. This PR contains only Studio workspace/chrome changes.

@ukimsanov
ukimsanov marked this pull request as ready for review July 24, 2026 03:43
Copilot AI review requested due to automatic review settings July 24, 2026 03:43

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Refactors Studio’s preview/workspace chrome to reduce duplicated transport/seek UI and improve default panel ergonomics, while persisting user panel width adjustments via UI preferences.

Changes:

  • Persist left/right panel widths in studioUiPreferences and initialize default widths responsively from viewport size.
  • Simplify preview transport controls by removing the preview seekbar + drag helper, and adjusting control layout/styling.
  • Adjust default UI ergonomics (Design tab opens by default; increased default timeline height; minor panel styling tweaks).

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/studio/src/utils/studioUiPreferences.ts Adds stored preference fields for leftWidth / rightWidth and reads them from storage.
packages/studio/src/utils/studioUiPreferences.test.ts Extends preference merge/malformed-value tests to cover persisted panel widths.
packages/studio/src/player/components/useSeekBarDrag.ts Removes now-dead seekbar drag helper (preview seekbar removed).
packages/studio/src/player/components/SpeedMenu.tsx Updates speed menu button styling to match simplified transport chrome.
packages/studio/src/player/components/ShortcutsPanel.tsx Updates shortcuts toggle button styling to match simplified transport chrome.
packages/studio/src/player/components/PlayerControls.tsx Removes preview seekbar UI; reworks transport layout; keeps time display updated via liveTime.
packages/studio/src/player/components/PlayerControls.test.ts Deletes tests tied to the removed resolveSeekPercent/seekbar logic.
packages/studio/src/hooks/usePanelLayout.ts Computes initial panel widths from viewport + preferences; defaults right panel to open + Design tab; persists widths on resize end.
packages/studio/src/hooks/usePanelLayout.test.ts Adds test coverage for viewport-scaled default widths and updated right-panel defaults.
packages/studio/src/components/StudioRightPanel.tsx Tweaks right panel background to match updated chrome.
packages/studio/src/components/nle/NLEContext.tsx Increases default timeline height to give the timeline more space by default.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/studio/src/hooks/usePanelLayout.ts

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

Reviewed exact head 4178332c8c29c100133c3388695ce90a0aeb3278.

The layout refactor is a real simplification: it removes the duplicate seekbar/drag implementation, retains global keyboard seeking, and the remaining panel composition is easier to follow. I found no blocking behavior loss.

Important follow-up

packages/studio/src/components/StudioLeftSidebar.tsx:172-178 and packages/studio/src/components/StudioRightPanel.tsx:462-468

Pointer resizing is persisted through handlePanelResizeEnd, but the keyboard-accessible separator handlers call setLeftWidth / setRightWidth directly and never write preferences. A keyboard resize therefore appears to work, then is lost on reload. Centralizing a clamped set-and-persist/commitPanelWidth(side, width) path for both pointer completion and key handlers would fix this and likely give Copilot's already-reported pointer-up stale-state race one clean home too.

Ponytail review

Lean already. Ship.

CI is green at this exact head. Approve.

@jrusso1020 jrusso1020 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.

Additive review at 4178332c. @Copilot commented (the panel-resize-end persist can read stale width during fast pointer interactions, usePanelLayout.ts:96); @magi reviewing in parallel. Weighted to Ular's ask + REVIEW_DISCIPLINE: does this actually simplify without dropping behavior or shuffling bytes?

Behavior-preservation — verified: a real simplification (net −304), not a byte-shuffle and not a silent behavior drop. The removed PlayerControls surface is exactly the duplicate seek path: SeekBar / SeekBarMarker / WorkAreaOverlay, the useSeekBarDrag hook (deleted — no remaining references anywhere in packages/studio/src), and the seekbar's local handleKeyDown. Everything else on the transport bar stays — play/pause (PlayPauseMorphIcon, onTogglePlay), speed (SpeedMenu), loop, mute, fullscreen, and in/out points are all still wired through usePlayerStore. Crucially the arrow-key frame-stepping the removed handleKeyDown provided is not lost: it's owned by usePlaybackKeyboard.ts (:103-110, ArrowLeft/ArrowRightseek(stepFrameTime(...))) and playbackShortcuts.ts (PLAYBACK_FRAME_STEP_CODES), a document-level handler independent of the seekbar. So keyboard seek survives; only the redundant click/drag bar in the preview goes away — the stated intent (timeline owns seeking).

Verified — the responsive-defaults claim holds. getInitialPanelWidths (usePanelLayout.ts:21) derives left/right from viewport width but still floors both at 160 (:27-31), and handlePanelResizeMove re-clamps to [160, …] (:81-87), so "preserving existing narrow-screen minimums" is accurate.

Verdict: COMMENT — Ready on the merits. Genuine deletion-driven simplification with transport behavior verified intact; the one open item is Copilot's resize-persist staleness. (Deferring the stamp to the maintainer.)

Review by Jerrai (hyperframes)

@ukimsanov
ukimsanov force-pushed the feat/media-treatment-studio branch from 9b2a1a7 to a473c41 Compare July 24, 2026 06:30
@ukimsanov
ukimsanov force-pushed the feat/studio-preview-layout branch from 4178332 to 4bd03cb Compare July 24, 2026 06:30
@ukimsanov
ukimsanov force-pushed the feat/media-treatment-studio branch from a473c41 to 3237565 Compare July 24, 2026 16:20
@ukimsanov
ukimsanov force-pushed the feat/studio-preview-layout branch from 4bd03cb to de48eae Compare July 24, 2026 16:26

@jrusso1020 jrusso1020 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.

Re-review at de48eae3. @magi re-reviewing in parallel; independent verdict.

Copilot's resize-persist staleness note is addressed. usePanelLayout.ts now keeps panel widths in a panelWidthsRef that's updated synchronously on every resize step (updatePanelWidth writes panelWidthsRef.current[side] before/with the React state), and commitPanelWidth persists from that ref (writeStudioUiPreferences({ leftWidth / rightWidth: next })) rather than from a closure-captured state value — so a fast pointer drag can no longer persist a stale width. It also consolidates the bounds into clampPanelWidth(side, width) (left [160, innerWidth*0.5], right [160, 600]).

My prior Rule-7 behavior-preservation check still holds — this remains a genuine simplification (the duplicate preview seekbar + useSeekBarDrag removal, with arrow-key frame-seek preserved in usePlaybackKeyboard.ts), and the 160px panel minimums are still enforced (now in clampPanelWidth alongside getInitialPanelWidths). CI is CLEAN at de48eae3.

Verdict: COMMENT — ready on the merits; Copilot's note is resolved and the simplification is intact. Deferring the stamp; happy to APPROVE on @jrusso1020's go.

Review by Jerrai (hyperframes)

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

Exact-head delta re-review at de48eae3a30fcb745ba7b5404b4365066b489769.

The prior non-blocking persistence gaps are both cleanly resolved through one shared path:

  • usePanelLayout.ts:63-84 centralizes clamping, ref synchronization, React state updates, and persistence.
  • Pointer movement updates panelWidthsRef, so pointer-up persists the actual final width rather than potentially stale React state (usePanelLayout.ts:94-118).
  • Keyboard resizing now calls the same adjustPanelWidth path from both separators, so rapid steps accumulate and survive reload.
  • usePanelLayout.test.ts:77-109 pins both the pointer-up race and rapid keyboard persistence.

This preserves the original deletion-driven simplification while closing the only follow-ups from the first pass. Exact-head check-runs are complete with no failures or pending jobs.

Verdict: APPROVE
Reasoning: The corrective delta removes the stale-state race and unifies pointer/keyboard persistence without reintroducing duplicate resize logic.

— Magi

@ukimsanov
ukimsanov force-pushed the feat/media-treatment-studio branch from 3237565 to 188be7b Compare July 24, 2026 16:54
@ukimsanov
ukimsanov force-pushed the feat/studio-preview-layout branch from de48eae to 085c638 Compare July 24, 2026 16:54
@ukimsanov
ukimsanov force-pushed the feat/media-treatment-studio branch from 188be7b to 38e21ea Compare July 24, 2026 18:20
@ukimsanov
ukimsanov force-pushed the feat/studio-preview-layout branch from 085c638 to 02efd40 Compare July 24, 2026 18:20
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.

4 participants