Skip to content

Fix Studio timeline cutoff with many tracks#535

Merged
miguel-heygen merged 1 commit intonextfrom
fix/studio-timeline-scroll-cutoff
Apr 28, 2026
Merged

Fix Studio timeline cutoff with many tracks#535
miguel-heygen merged 1 commit intonextfrom
fix/studio-timeline-scroll-cutoff

Conversation

@miguel-heygen
Copy link
Copy Markdown
Collaborator

@miguel-heygen miguel-heygen commented Apr 28, 2026

Problem

Studio’s timeline could become hard to inspect when a composition had many tracks:

  • the track list needed vertical scrolling, but the bottom shortcut hint stayed pinned over the track canvas
  • after scrolling to the bottom, the final visible track could sit behind that overlay and look cut off
  • the hint was positioned against the nearest page-level positioning context instead of the timeline shell itself, so its placement depended on the surrounding Studio layout
  • this showed up most clearly in a local repro project with 30 separate data-track-index rows

What this fixes

  • Makes the timeline shell the positioning context for its bottom shortcut hint.
  • Adds an explicit overflow check for the timeline scroll container.
  • Hides the shortcut hint when the timeline has vertical track overflow, keeping the final track unobstructed while scrolling.
  • Keeps the shortcut hint visible for compact timelines where it does not compete with scrollable track rows.
  • Slightly tightens the timeline canvas bottom buffer so the last track can fully align inside short timeline panels.
  • Adds focused unit coverage for the hint visibility decision.

Root cause

The timeline rendered the keyboard shortcut hint as an always-visible absolute overlay near the bottom of the visible timeline area. That works for short timelines, but with many tracks the scroll container and the overlay share the same bottom region.

Because the hint did not account for vertical overflow, Studio could scroll the final row into view and then immediately cover part of it with the hint. The canvas also had a small bottom spacer that left the last row close enough to the bottom overlay to make the cutoff visible.

Verification

Local checks

  • bun run --filter @hyperframes/studio test -- Timeline.test.ts -> 33 tests pass
  • bun run --filter @hyperframes/studio typecheck
  • bunx oxlint packages/studio/src/player/components/Timeline.tsx packages/studio/src/player/components/Timeline.test.ts -> 0 warnings, 0 errors
  • bunx oxfmt --check packages/studio/src/player/components/Timeline.tsx packages/studio/src/player/components/Timeline.test.ts
  • git diff --check
  • Lefthook pre-commit -> lint, format, typecheck pass
  • Lefthook commit-msg -> commitlint pass

Browser verification

  • Created a local ignored Studio repro project at packages/studio/data/projects/timeline-scroll-cutoff-repro/index.html with 30 separate timeline tracks.
  • Started Studio locally at http://127.0.0.1:5173/#project/timeline-scroll-cutoff-repro.
  • Used agent-browser to open the repro, scroll the timeline to the bottom, and verify the measured state:
    • rowCount: 30
    • scrollTop: 2109
    • lastFullyVisible: true
    • hintVisible: false
  • Saved local browser proof under artifacts/timeline-scroll-cutoff/after-bottom.png.
  • Recorded the tested scroll flow with agent-browser at artifacts/timeline-scroll-cutoff/after-scroll-flow.webm.

Notes

  • The 30-track repro project is ignored under packages/studio/data/projects/ and intentionally not committed.
  • Browser screenshots and recordings are local-only proof artifacts under artifacts/ and intentionally not committed.
  • A clean worktree needed the ignored runtime inline artifact for the commit hook, so I ran bun run --filter @hyperframes/core build:hyperframes-runtime before committing.

@miguel-heygen miguel-heygen marked this pull request as ready for review April 28, 2026 19:39
Copy link
Copy Markdown
Collaborator

@jrusso1020 jrusso1020 left a comment

Choose a reason for hiding this comment

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

LGTM — clean fix for the timeline-overflow case.

shouldShowTimelineShortcutHint is a pure function with <= 1 slack for sub-pixel rounding and Number.isFinite guards for unmounted refs. Visibility recomputes via ResizeObserver and an effect on [timelineReady, elements.length, totalH], debounced by requestAnimationFrame and cancelled on unmount. The relative className addition on the outer container is needed for the absolute-positioned hint child to position correctly.

Test in Timeline.test.ts covers the boundary cases (220/220 → show, 220.5/220 → show, 221.5/220 → hide). @hyperframes/studio 276/276 pass locally.

— Review by Rames Jusso

Copy link
Copy Markdown
Collaborator

@vanceingalls vanceingalls left a comment

Choose a reason for hiding this comment

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

Staff review: approved.

The fix is scoped to the actual obstruction: make the timeline shell the positioning context, detect vertical overflow, and hide the shortcut hint only when it would compete with scrollable tracks. The pure helper has the right sub-pixel tolerance, and the lifecycle cleanup for the RAF/ResizeObserver path looks sound. I did not find any blocking issues.

@miguel-heygen miguel-heygen merged commit 0657d9b into next Apr 28, 2026
11 checks passed
@miguel-heygen miguel-heygen deleted the fix/studio-timeline-scroll-cutoff branch April 28, 2026 20:43
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