Skip to content

Commit 5bab2f1

Browse files
committed
browser support for fullscreen
1 parent 4bf5474 commit 5bab2f1

File tree

1 file changed

+94
-18
lines changed

1 file changed

+94
-18
lines changed

src/ui/video/useVideoPlayer.ts

+94-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
import { useCallback, useEffect, useRef, useState } from 'react'
22

3+
interface DocumentWithFullscreen extends Document {
4+
webkitFullscreenElement?: Element | null
5+
mozFullScreenElement?: Element | null
6+
msFullscreenElement?: Element | null
7+
webkitExitFullscreen?: () => Promise<void>
8+
mozCancelFullScreen?: () => Promise<void>
9+
msExitFullscreen?: () => Promise<void>
10+
}
11+
12+
interface HTMLElementWithFullscreen extends HTMLElement {
13+
webkitRequestFullscreen?: () => Promise<void>
14+
mozRequestFullScreen?: () => Promise<void>
15+
msRequestFullscreen?: () => Promise<void>
16+
}
17+
18+
interface HTMLVideoElementWithFullscreen extends HTMLVideoElement {
19+
webkitEnterFullscreen?: () => void
20+
webkitExitFullscreen?: () => void
21+
}
22+
323
export function useVideoPlayer(videoRef: React.RefObject<HTMLVideoElement>) {
424
// Core state
525
const [status, setStatus] = useState<'loading' | 'playing' | 'playing-with-sound'>('loading')
@@ -65,27 +85,59 @@ export function useVideoPlayer(videoRef: React.RefObject<HTMLVideoElement>) {
6585

6686
// Toggle fullscreen
6787
const toggleFullscreen = useCallback(() => {
68-
const container = videoRef.current?.closest('.video-inner-container') as HTMLElement
88+
const container = videoRef.current?.closest('.video-inner-container') as HTMLElementWithFullscreen
6989
if (!container) return
7090

71-
if (!document.fullscreenElement) {
72-
container
73-
.requestFullscreen()
74-
.then(() => {
75-
setIsFullscreen(true)
76-
})
77-
.catch(err => {
78-
console.log(`Error attempting to enable fullscreen: ${err.message}`)
79-
})
91+
// Check if we're already in fullscreen mode
92+
const isFullscreen =
93+
document.fullscreenElement ||
94+
(document as DocumentWithFullscreen).webkitFullscreenElement ||
95+
(document as DocumentWithFullscreen).mozFullScreenElement ||
96+
(document as DocumentWithFullscreen).msFullscreenElement
97+
98+
if (!isFullscreen) {
99+
// Try different fullscreen methods
100+
if (container.requestFullscreen) {
101+
container.requestFullscreen()
102+
} else if (container.webkitRequestFullscreen) {
103+
container.webkitRequestFullscreen()
104+
} else if (container.mozRequestFullScreen) {
105+
container.mozRequestFullScreen()
106+
} else if (container.msRequestFullscreen) {
107+
container.msRequestFullscreen()
108+
} else if ((videoRef.current as HTMLVideoElementWithFullscreen)?.webkitEnterFullscreen) {
109+
// iOS Safari specific method
110+
const video = videoRef.current as HTMLVideoElementWithFullscreen
111+
if (video.webkitEnterFullscreen) {
112+
video.webkitEnterFullscreen()
113+
}
114+
}
80115
} else {
81-
document
82-
.exitFullscreen()
83-
.then(() => {
84-
setIsFullscreen(false)
85-
})
86-
.catch(err => {
87-
console.log(`Error attempting to exit fullscreen: ${err.message}`)
88-
})
116+
// Exit fullscreen
117+
if (document.exitFullscreen) {
118+
document.exitFullscreen()
119+
} else if ((document as DocumentWithFullscreen).webkitExitFullscreen) {
120+
const doc = document as DocumentWithFullscreen
121+
if (doc.webkitExitFullscreen) {
122+
doc.webkitExitFullscreen()
123+
}
124+
} else if ((document as DocumentWithFullscreen).mozCancelFullScreen) {
125+
const doc = document as DocumentWithFullscreen
126+
if (doc.mozCancelFullScreen) {
127+
doc.mozCancelFullScreen()
128+
}
129+
} else if ((document as DocumentWithFullscreen).msExitFullscreen) {
130+
const doc = document as DocumentWithFullscreen
131+
if (doc.msExitFullscreen) {
132+
doc.msExitFullscreen()
133+
}
134+
} else if ((videoRef.current as HTMLVideoElementWithFullscreen)?.webkitExitFullscreen) {
135+
// iOS Safari specific method
136+
const video = videoRef.current as HTMLVideoElementWithFullscreen
137+
if (video.webkitExitFullscreen) {
138+
video.webkitExitFullscreen()
139+
}
140+
}
89141
}
90142
}, [videoRef])
91143

@@ -193,6 +245,30 @@ export function useVideoPlayer(videoRef: React.RefObject<HTMLVideoElement>) {
193245
}
194246
}, [status, videoRef])
195247

248+
// Add fullscreen change event listeners
249+
useEffect(() => {
250+
const handleFullscreenChange = () => {
251+
const isFullscreen =
252+
document.fullscreenElement ||
253+
(document as DocumentWithFullscreen).webkitFullscreenElement ||
254+
(document as DocumentWithFullscreen).mozFullScreenElement ||
255+
(document as DocumentWithFullscreen).msFullscreenElement
256+
setIsFullscreen(!!isFullscreen)
257+
}
258+
259+
document.addEventListener('fullscreenchange', handleFullscreenChange)
260+
document.addEventListener('webkitfullscreenchange', handleFullscreenChange)
261+
document.addEventListener('mozfullscreenchange', handleFullscreenChange)
262+
document.addEventListener('MSFullscreenChange', handleFullscreenChange)
263+
264+
return () => {
265+
document.removeEventListener('fullscreenchange', handleFullscreenChange)
266+
document.removeEventListener('webkitfullscreenchange', handleFullscreenChange)
267+
document.removeEventListener('mozfullscreenchange', handleFullscreenChange)
268+
document.removeEventListener('MSFullscreenChange', handleFullscreenChange)
269+
}
270+
}, [])
271+
196272
// Return the state and handlers
197273
return {
198274
status,

0 commit comments

Comments
 (0)