Handle video play() promise rejection with visible error state (closes #23)

This commit is contained in:
friday-bot 2026-07-14 11:10:21 -06:00
parent f91bbd384d
commit d3cb7795b7

View file

@ -13,6 +13,7 @@ const VideoPlayer = ({ src, poster, vttSrc }: VideoPlayerProps) => {
const [showCaptions, setShowCaptions] = useState(false) const [showCaptions, setShowCaptions] = useState(false)
const [playbackRate, setPlaybackRate] = useState(1) const [playbackRate, setPlaybackRate] = useState(1)
const [progress, setProgress] = useState(0) const [progress, setProgress] = useState(0)
const [playError, setPlayError] = useState(false)
const videoRef = useRef<HTMLVideoElement>(null) const videoRef = useRef<HTMLVideoElement>(null)
const timeoutRef = useRef<ReturnType<typeof setTimeout>>(null) const timeoutRef = useRef<ReturnType<typeof setTimeout>>(null)
@ -39,16 +40,23 @@ const VideoPlayer = ({ src, poster, vttSrc }: VideoPlayerProps) => {
}, 3000) }, 3000)
}, [isPlaying]) }, [isPlaying])
const togglePlay = useCallback(() => { const togglePlay = useCallback(async () => {
if (videoRef.current) { if (videoRef.current) {
if (isPlaying) { if (isPlaying) {
videoRef.current.pause() videoRef.current.pause()
setShowControls(true) setShowControls(true)
setIsPlaying(false)
} else { } else {
videoRef.current.play() try {
hideControlsWithDelay() await videoRef.current.play()
setPlayError(false)
setIsPlaying(true)
hideControlsWithDelay()
} catch {
setIsPlaying(false)
setPlayError(true)
}
} }
setIsPlaying(!isPlaying)
} }
}, [isPlaying, hideControlsWithDelay]) }, [isPlaying, hideControlsWithDelay])
@ -133,7 +141,15 @@ const VideoPlayer = ({ src, poster, vttSrc }: VideoPlayerProps) => {
/> />
</video> </video>
<div {playError && (
<div className="absolute inset-0 flex items-center justify-center bg-black/70">
<p className="text-white text-sm font-medium px-4 py-2 bg-red-700/80 rounded">
Video unavailable please try again later.
</p>
</div>
)}
<div
className={`absolute bottom-0 left-0 right-0 transition-opacity duration-300 ${ className={`absolute bottom-0 left-0 right-0 transition-opacity duration-300 ${
showControls ? 'opacity-100' : 'opacity-0' showControls ? 'opacity-100' : 'opacity-0'
}`} }`}