"use client"; import { useState, useEffect, useCallback, RefObject } from "react"; export function useFullscreen( videoRef: RefObject, showOverlays: boolean, streamUrl?: string | null, ) { const [isFullscreen, setIsFullscreen] = useState(false); // Standard fullscreenchange useEffect(() => { const handler = () => setIsFullscreen(!!document.fullscreenElement); document.addEventListener("fullscreenchange", handler); return () => document.removeEventListener("fullscreenchange", handler); }, []); // Body classes for nav hiding useEffect(() => { document.body.classList.toggle("tv-fullscreen", isFullscreen); document.body.classList.toggle("tv-overlays", isFullscreen && showOverlays); return () => document.body.classList.remove("tv-fullscreen", "tv-overlays"); }, [isFullscreen, showOverlays]); // iOS Safari webkit events — re-attach when stream URL changes (new video element) useEffect(() => { const video = videoRef.current; if (!video) return; const onBegin = () => setIsFullscreen(true); const onEnd = () => setIsFullscreen(false); video.addEventListener("webkitbeginfullscreen", onBegin); video.addEventListener("webkitendfullscreen", onEnd); return () => { video.removeEventListener("webkitbeginfullscreen", onBegin); video.removeEventListener("webkitendfullscreen", onEnd); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [streamUrl]); const toggleFullscreen = useCallback(() => { if (document.fullscreenEnabled) { if (!document.fullscreenElement) { document.documentElement.requestFullscreen().catch(() => {}); } else { document.exitFullscreen().catch(() => {}); } return; } const video = videoRef.current as HTMLVideoElement & { webkitEnterFullscreen?: () => void; webkitExitFullscreen?: () => void; webkitDisplayingFullscreen?: boolean; }; if (!video?.webkitEnterFullscreen) return; if (video.webkitDisplayingFullscreen) { video.webkitExitFullscreen?.(); } else { video.webkitEnterFullscreen(); } }, [videoRef]); return { isFullscreen, toggleFullscreen }; }