refactor(studio): extract live timeline clock (#2711)

This commit is contained in:
Miguel Ángel
2026-08-04 16:27:41 -07:00
committed by GitHub
parent ebdd1893c4
commit 19b8a1f3c5
2 changed files with 12 additions and 13 deletions
@@ -0,0 +1,11 @@
// ponytail: Playback RAF updates the playhead/time display without per-frame React renders.
type TimeListener = (time: number) => void;
const timeListeners = new Set<TimeListener>();
export const liveTime = {
notify: (time: number) => timeListeners.forEach((listener) => listener(time)),
subscribe: (listener: TimeListener) => {
timeListeners.add(listener);
return () => timeListeners.delete(listener);
},
};
@@ -12,6 +12,7 @@ import { clampTimelineZoomPercent, computePinnedZoomPercent } from "../component
import { createKeyframeSlice, type KeyframeCacheEntry, type KeyframeSlice } from "./keyframeSlice"; import { createKeyframeSlice, type KeyframeCacheEntry, type KeyframeSlice } from "./keyframeSlice";
export type { KeyframeCacheEntry } from "./keyframeSlice"; export type { KeyframeCacheEntry } from "./keyframeSlice";
export { liveTime } from "./liveTime";
export interface TimelineElement { export interface TimelineElement {
id: string; id: string;
@@ -279,19 +280,6 @@ interface BeatHistoryEntry {
label: string; label: string;
} }
// Lightweight pub-sub for current time during playback.
// Bypasses React state so the RAF loop can update the playhead/time display
// without triggering re-renders on every frame.
type TimeListener = (time: number) => void;
const _timeListeners = new Set<TimeListener>();
export const liveTime = {
notify: (t: number) => _timeListeners.forEach((cb) => cb(t)),
subscribe: (cb: TimeListener) => {
_timeListeners.add(cb);
return () => _timeListeners.delete(cb);
},
};
export function createTimelineResetState() { export function createTimelineResetState() {
return { return {
isPlaying: false, isPlaying: false,