feat(tv): enhance fullscreen functionality for iOS Safari with video element events
This commit is contained in:
@@ -98,6 +98,21 @@ function TvPageContent() {
|
|||||||
return () => document.removeEventListener("fullscreenchange", handler);
|
return () => document.removeEventListener("fullscreenchange", handler);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// iOS Safari: track fullscreen state via webkit video element events.
|
||||||
|
// Re-run when streamUrl changes so we catch the video element after it mounts.
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
}, [streamUrl]);
|
||||||
|
|
||||||
// Hide the shared nav bar in fullscreen; reveal it when overlays are shown
|
// Hide the shared nav bar in fullscreen; reveal it when overlays are shown
|
||||||
// (mouse move / key press). Classes are cleaned up on unmount.
|
// (mouse move / key press). Classes are cleaned up on unmount.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -105,12 +120,30 @@ function TvPageContent() {
|
|||||||
document.body.classList.toggle("tv-overlays", isFullscreen && showOverlays);
|
document.body.classList.toggle("tv-overlays", isFullscreen && showOverlays);
|
||||||
return () => document.body.classList.remove("tv-fullscreen", "tv-overlays");
|
return () => document.body.classList.remove("tv-fullscreen", "tv-overlays");
|
||||||
}, [isFullscreen, showOverlays]);
|
}, [isFullscreen, showOverlays]);
|
||||||
|
|
||||||
const toggleFullscreen = useCallback(() => {
|
const toggleFullscreen = useCallback(() => {
|
||||||
|
// Standard Fullscreen API (Chrome, Firefox, Safari desktop)
|
||||||
|
if (document.fullscreenEnabled) {
|
||||||
if (!document.fullscreenElement) {
|
if (!document.fullscreenElement) {
|
||||||
document.documentElement.requestFullscreen().catch(() => {});
|
document.documentElement.requestFullscreen().catch(() => {});
|
||||||
} else {
|
} else {
|
||||||
document.exitFullscreen().catch(() => {});
|
document.exitFullscreen().catch(() => {});
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// iOS Safari: requestFullscreen is not supported. Fall back to the video
|
||||||
|
// element's proprietary webkit API instead.
|
||||||
|
const video = videoRef.current as HTMLVideoElement & {
|
||||||
|
webkitEnterFullscreen?: () => void;
|
||||||
|
webkitExitFullscreen?: () => void;
|
||||||
|
webkitDisplayingFullscreen?: boolean;
|
||||||
|
};
|
||||||
|
if (!video?.webkitEnterFullscreen) return;
|
||||||
|
if (video.webkitDisplayingFullscreen) {
|
||||||
|
video.webkitExitFullscreen?.();
|
||||||
|
} else {
|
||||||
|
video.webkitEnterFullscreen();
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Volume control
|
// Volume control
|
||||||
|
|||||||
Reference in New Issue
Block a user