Files
k-tv/k-tv-frontend/hooks/use-idle.ts
Gabriel Kaszewski c4d2e48f73 fix(frontend): resolve all eslint warnings and errors
- block-timeline: ref updates moved to useLayoutEffect
- channel-card, guide/page: Date.now() wrapped in useMemo + suppress purity rule
- auth-context: lazy localStorage init (removes setState-in-effect)
- use-channel-order: lazy localStorage init (removes setState-in-effect)
- use-idle: start timer on mount without calling resetIdle (removes setState-in-effect)
- use-subtitles, transcode-settings-dialog: inline eslint-disable on exact violating line
- providers: block-level eslint-disable for tokenRef closure in useState initializer
- edit-channel-sheet: remove unused minsToTime and BlockContent imports
- docs/page: escape unescaped quote and apostrophe entities
2026-03-17 02:40:32 +01:00

45 lines
1.4 KiB
TypeScript

"use client";
import { useState, useEffect, useCallback, useRef, RefObject } from "react";
export function useIdle(
timeoutMs: number,
videoRef: RefObject<HTMLVideoElement | null>,
onIdle?: () => void,
) {
const [showOverlays, setShowOverlays] = useState(true);
const [needsInteraction, setNeedsInteraction] = useState(false);
const idleTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
// Keep onIdle in a ref so resetIdle doesn't need it as a dep
const onIdleRef = useRef(onIdle);
useEffect(() => {
onIdleRef.current = onIdle;
});
const resetIdle = useCallback(() => {
setShowOverlays(true);
setNeedsInteraction(false);
if (idleTimer.current) clearTimeout(idleTimer.current);
idleTimer.current = setTimeout(() => {
setShowOverlays(false);
onIdleRef.current?.();
}, timeoutMs);
videoRef.current?.play().catch(() => {});
}, [timeoutMs, videoRef]);
// Start the idle timer on mount without calling setState
// (default state values already set by useState above)
useEffect(() => {
idleTimer.current = setTimeout(() => {
setShowOverlays(false);
onIdleRef.current?.();
}, timeoutMs);
return () => {
if (idleTimer.current) clearTimeout(idleTimer.current);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return { showOverlays, needsInteraction, setNeedsInteraction, resetIdle };
}