/** * useVideoTimeouts Hook * * Manages video-related timers including: * - Playback start watchdog * - Finish timer (duration-based) * - Custom timers */ import { useRef, useCallback, useEffect } from 'react'; export interface UseVideoTimeoutsResult { /** Set a named timer */ setTimer: (name: string, callback: () => void, delayMs: number) => void; /** Clear a named timer */ clearTimer: (name: string) => void; /** Clear all timers */ clearAllTimers: () => void; /** Check if a timer is active */ isTimerActive: (name: string) => boolean; } /** * Hook for managing video-related timers. * * Provides a clean API for setting, clearing, and tracking * multiple named timers. All timers are automatically cleaned * up on unmount. * * @example * const { setTimer, clearTimer, clearAllTimers } = useVideoTimeouts(); * * // Start playback watchdog * setTimer('watchdog', () => { * console.log('Playback did not start in time'); * }, 3000); * * // Clear when playback starts * clearTimer('watchdog'); */ export function useVideoTimeouts(): UseVideoTimeoutsResult { const timersRef = useRef>>(new Map()); const clearTimer = useCallback((name: string) => { const timer = timersRef.current.get(name); if (timer) { clearTimeout(timer); timersRef.current.delete(name); } }, []); const clearAllTimers = useCallback(() => { timersRef.current.forEach((timer) => { clearTimeout(timer); }); timersRef.current.clear(); }, []); const setTimer = useCallback( (name: string, callback: () => void, delayMs: number) => { // Clear existing timer with same name clearTimer(name); const timer = setTimeout(() => { timersRef.current.delete(name); callback(); }, delayMs); timersRef.current.set(name, timer); }, [clearTimer], ); const isTimerActive = useCallback((name: string) => { return timersRef.current.has(name); }, []); // Cleanup on unmount useEffect(() => { return () => { clearAllTimers(); }; }, [clearAllTimers]); return { setTimer, clearTimer, clearAllTimers, isTimerActive, }; } export default useVideoTimeouts;