mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-10 22:20:14 +00:00
fix: keep Studio frame stepping advancing (#573)
## Problem Closes #568. Studio preview-focused frame stepping could stop advancing after a couple of ArrowLeft/ArrowRight presses. The same integer-frame stepping path also affected the K-held J/L one-frame shuttle controls. ## What this fixes - Adds a shared `stepFrameTime` helper that advances by integer frame index instead of adding fractional seconds. - Uses that helper for preview-surface keyboard shortcuts and the focused seek slider. - Adds regression coverage for truncated runtime times like `0.0333333`, which previously stepped back onto the same frame. ## Root cause The runtime seek path quantizes requested times with `Math.floor(time * fps)`. Studio was deriving the next frame from the runtime's current seconds value, which can be a truncated decimal such as `0.0333333`. Adding `1 / 30` to that value can produce `1.999998...` frames, so floor-quantization lands back on the previous frame and repeated shortcuts appear to stop responding. ## Verification ### Local checks - `bun run --filter @hyperframes/core build:hyperframes-runtime` - `bun run --filter @hyperframes/studio test -- src/player/lib/time.test.ts src/player/hooks/useTimelinePlayer.test.ts src/player/components/PlayerControls.test.ts` - `bunx oxfmt --check packages/studio/src/player/lib/time.ts packages/studio/src/player/lib/time.test.ts packages/studio/src/player/hooks/useTimelinePlayer.ts packages/studio/src/player/components/PlayerControls.tsx` - `bunx oxlint packages/studio/src/player/lib/time.ts packages/studio/src/player/lib/time.test.ts packages/studio/src/player/hooks/useTimelinePlayer.ts packages/studio/src/player/components/PlayerControls.tsx` - `bun run --filter @hyperframes/studio typecheck` - `bun run --filter @hyperframes/studio build` - `git diff --check` - Lefthook pre-commit: lint, format, typecheck - Lefthook commit-msg: commitlint ### Browser verification - Created `/tmp/hf-studio-frame-step-repro` with a 10s GSAP animation. - Started Studio preview at `http://localhost:5191/#project/hf-studio-frame-step-repro`. - Used `agent-browser` to reproduce the original stuck behavior before the fix: repeated preview-focused `ArrowRight` keydowns were handled but runtime time stayed at `0.0333333`. - Used `agent-browser` after the fix to verify preview-focused `ArrowRight` advances 10 frames to `0.3333333`. - Used `agent-browser` to verify K-held L steps forward 5 frames to `0.1666667` and K-held J steps backward from 5 frames to `0`. - Used actual Safari 18.6 with System Events key presses to verify 10 and then 20 preview-focused ArrowRight presses continue advancing visually. ## Notes - Safari WebDriver was unavailable because Safari's "Allow remote automation" setting is disabled on this machine, so the Safari check used real Safari GUI key events instead. - Local proof artifacts are intentionally not committed: - `qa-artifacts/studio-frame-step-issue-568/chrome-after-10-arrow-right.png` - `qa-artifacts/studio-frame-step-issue-568/chrome-frame-step-flow.webm` - `qa-artifacts/studio-frame-step-issue-568/safari-after-10-arrow-right.png` - `qa-artifacts/studio-frame-step-issue-568/safari-after-20-arrow-right.png`
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useRef, useCallback } from "react";
|
||||
import { usePlayerStore, liveTime, type TimelineElement } from "../store/playerStore";
|
||||
import { useMountEffect } from "../../hooks/useMountEffect";
|
||||
import { frameToSeconds, STUDIO_PREVIEW_FPS } from "../lib/time";
|
||||
import { stepFrameTime, STUDIO_PREVIEW_FPS } from "../lib/time";
|
||||
import { useCaptionStore } from "../../captions/store";
|
||||
|
||||
interface PlaybackAdapter {
|
||||
@@ -697,7 +697,7 @@ export function useTimelinePlayer() {
|
||||
(deltaFrames: number) => {
|
||||
const adapter = getAdapter();
|
||||
const currentTime = adapter?.getTime() ?? usePlayerStore.getState().currentTime;
|
||||
seek(currentTime + frameToSeconds(deltaFrames, STUDIO_PREVIEW_FPS));
|
||||
seek(stepFrameTime(currentTime, deltaFrames, STUDIO_PREVIEW_FPS));
|
||||
},
|
||||
[getAdapter, seek],
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user