import { useEffect, useMemo, useRef, useState } from 'react'; import { ipcChannels } from '../../../shared/ipc/contracts'; import type { VideoPlaybackEvent, VideoPlaybackState } from '../../../shared/types'; import { getDndApi } from '../dndApi'; export function useVideoPlaybackState(): readonly [ VideoPlaybackState | null, { dispatch: (event: VideoPlaybackEvent) => Promise }, ] { const api = getDndApi(); const [playback, setPlayback] = useState(null); /** serverNowMs − Date.now() at last IPC sync; lets us compute a live clock without React timers. */ const timeOffsetMsRef = useRef(0); useEffect(() => { void api.invoke(ipcChannels.video.getState, {}).then((r) => { timeOffsetMsRef.current = r.state.serverNowMs - Date.now(); setPlayback(r.state); }); return api.on(ipcChannels.video.stateChanged, ({ state: next }) => { timeOffsetMsRef.current = next.serverNowMs - Date.now(); setPlayback((prev) => { if (prev?.revision === next.revision) return prev; return next; }); }); }, [api]); const state = useMemo((): VideoPlaybackState | null => { if (!playback) return null; return { ...playback, get serverNowMs(): number { return Date.now() + timeOffsetMsRef.current; }, }; }, [playback]); return [ state, { dispatch: async (event) => { await api.invoke(ipcChannels.video.dispatch, { event }); }, }, ] as const; }