mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
## Problem HyperFrames Studio made frame-accurate playback review slower than expected for editor-style workflows. Issue #527 called out missing loop playback, frame display/jump controls, preview-focused Space handling, frame stepping, and NLE-style J/K/L shuttle controls. ## What this fixes - Adds a persistent Studio loop toggle and makes the playback loop restart when enabled. - Adds a time/frame display toggle plus a jump-to-frame input in the player controls. - Adds frame math helpers and frame-step behavior at the Studio preview frame rate. - Expands keyboard handling so preview-focused Space toggles playback, ArrowLeft/ArrowRight step frames, Shift+Arrow steps 10 frames, and J/K/L shuttle controls work from the preview/timeline surface while ignoring form/button/slider targets. - Adds J/K/L shuttle behavior: J plays backward, K pauses, L plays forward, repeated J/L ramps 1x -> 2x -> 4x, and K-held J/L frame-steps. - Makes the preview wrapper focusable so keyboard playback shortcuts work after focusing the preview area. ## Root cause The Studio playback layer only exposed mouse scrubbing, basic play/pause, a seconds-based readout, and slider-local arrow-key nudges. The global Space shortcut was also gated to `document.body`, so it stopped working once the actual preview/editor surface had focus. Studio needed a single playback-control layer above the runtime adapter that could translate editor keyboard intent into deterministic seek/play/pause operations. ## Verification ### Local checks - `bun install` - `bun run --filter @hyperframes/core build:hyperframes-runtime` - `bunx oxfmt --check packages/studio/src/player/lib/time.ts packages/studio/src/player/lib/time.test.ts packages/studio/src/player/store/playerStore.ts packages/studio/src/player/store/playerStore.test.ts packages/studio/src/player/hooks/useTimelinePlayer.ts packages/studio/src/player/components/PlayerControls.tsx packages/studio/src/player/components/PlayerControls.test.ts packages/studio/src/components/nle/NLEPreview.tsx` - `bunx oxlint packages/studio/src/player/lib/time.ts packages/studio/src/player/lib/time.test.ts packages/studio/src/player/store/playerStore.ts packages/studio/src/player/store/playerStore.test.ts packages/studio/src/player/hooks/useTimelinePlayer.ts packages/studio/src/player/components/PlayerControls.tsx packages/studio/src/player/components/PlayerControls.test.ts packages/studio/src/components/nle/NLEPreview.tsx` - `bun run --filter @hyperframes/studio test -- src/player/lib/time.test.ts src/player/store/playerStore.test.ts src/player/components/PlayerControls.test.ts src/player/hooks/useTimelinePlayer.test.ts` -> 4 files passed, 52 tests passed - `bun run --filter @hyperframes/studio typecheck` - `bun run --filter @hyperframes/studio build` - `git diff --check` - Lefthook during commit -> lint, format, typecheck, commitlint pass ### Browser verification - Created a temp project at `/tmp/hf-studio-nle-controls` with an animated 10s GSAP timeline. - Started local Studio preview via `bun run --filter @hyperframes/cli dev -- preview /tmp/hf-studio-nle-controls` at `http://localhost:5194`. - Used `agent-browser` to verify: - loop toggle changes to active state - frame display shows `current / total` frames - jump-to-frame input moves the seek position to frame 45 / frame 150 - focused preview accepts Space play/pause - ArrowRight advances one frame from preview focus - J plays backward from frame 150 to a lower frame, then K stops - agent-browser-driven recording of the tested flow completed ## Notes - Local proof artifacts are intentionally not committed: - `qa-artifacts/studio-nle-controls/frame-controls.png` - `qa-artifacts/studio-nle-controls/playback-controls.webm` - Closes #527.