diff options
Diffstat (limited to 'src/view/com/util/post-embeds/VideoEmbedInner/web-controls/utils.tsx')
-rw-r--r-- | src/view/com/util/post-embeds/VideoEmbedInner/web-controls/utils.tsx | 240 |
1 files changed, 0 insertions, 240 deletions
diff --git a/src/view/com/util/post-embeds/VideoEmbedInner/web-controls/utils.tsx b/src/view/com/util/post-embeds/VideoEmbedInner/web-controls/utils.tsx deleted file mode 100644 index 108814ea2..000000000 --- a/src/view/com/util/post-embeds/VideoEmbedInner/web-controls/utils.tsx +++ /dev/null @@ -1,240 +0,0 @@ -import React, {useCallback, useEffect, useRef, useState} from 'react' - -import {isSafari} from '#/lib/browser' -import {useVideoVolumeState} from '../../VideoVolumeContext' - -export function useVideoElement(ref: React.RefObject<HTMLVideoElement>) { - const [playing, setPlaying] = useState(false) - const [muted, setMuted] = useState(true) - const [currentTime, setCurrentTime] = useState(0) - const [volume, setVolume] = useVideoVolumeState() - const [duration, setDuration] = useState(0) - const [buffering, setBuffering] = useState(false) - const [error, setError] = useState(false) - const [canPlay, setCanPlay] = useState(false) - const playWhenReadyRef = useRef(false) - - useEffect(() => { - if (!ref.current) return - ref.current.volume = volume - }, [ref, volume]) - - useEffect(() => { - if (!ref.current) return - - let bufferingTimeout: ReturnType<typeof setTimeout> | undefined - - function round(num: number) { - return Math.round(num * 100) / 100 - } - - // Initial values - setCurrentTime(round(ref.current.currentTime) || 0) - setDuration(round(ref.current.duration) || 0) - setMuted(ref.current.muted) - setPlaying(!ref.current.paused) - setVolume(ref.current.volume) - - const handleTimeUpdate = () => { - if (!ref.current) return - setCurrentTime(round(ref.current.currentTime) || 0) - // HACK: Safari randomly fires `stalled` events when changing between segments - // let's just clear the buffering state if the video is still progressing -sfn - if (isSafari) { - if (bufferingTimeout) clearTimeout(bufferingTimeout) - setBuffering(false) - } - } - - const handleDurationChange = () => { - if (!ref.current) return - setDuration(round(ref.current.duration) || 0) - } - - const handlePlay = () => { - setPlaying(true) - } - - const handlePause = () => { - setPlaying(false) - } - - const handleVolumeChange = () => { - if (!ref.current) return - setMuted(ref.current.muted) - } - - const handleError = () => { - setError(true) - } - - const handleCanPlay = async () => { - if (bufferingTimeout) clearTimeout(bufferingTimeout) - setBuffering(false) - setCanPlay(true) - - if (!ref.current) return - if (playWhenReadyRef.current) { - try { - await ref.current.play() - } catch (e: any) { - if ( - !e.message?.includes(`The request is not allowed by the user agent`) - ) { - throw e - } - } - playWhenReadyRef.current = false - } - } - - const handleCanPlayThrough = () => { - if (bufferingTimeout) clearTimeout(bufferingTimeout) - setBuffering(false) - } - - const handleWaiting = () => { - if (bufferingTimeout) clearTimeout(bufferingTimeout) - bufferingTimeout = setTimeout(() => { - setBuffering(true) - }, 500) // Delay to avoid frequent buffering state changes - } - - const handlePlaying = () => { - if (bufferingTimeout) clearTimeout(bufferingTimeout) - setBuffering(false) - setError(false) - } - - const handleStalled = () => { - if (bufferingTimeout) clearTimeout(bufferingTimeout) - bufferingTimeout = setTimeout(() => { - setBuffering(true) - }, 500) // Delay to avoid frequent buffering state changes - } - - const handleEnded = () => { - setPlaying(false) - setBuffering(false) - setError(false) - } - - const abortController = new AbortController() - - ref.current.addEventListener('timeupdate', handleTimeUpdate, { - signal: abortController.signal, - }) - ref.current.addEventListener('durationchange', handleDurationChange, { - signal: abortController.signal, - }) - ref.current.addEventListener('play', handlePlay, { - signal: abortController.signal, - }) - ref.current.addEventListener('pause', handlePause, { - signal: abortController.signal, - }) - ref.current.addEventListener('volumechange', handleVolumeChange, { - signal: abortController.signal, - }) - ref.current.addEventListener('error', handleError, { - signal: abortController.signal, - }) - ref.current.addEventListener('canplay', handleCanPlay, { - signal: abortController.signal, - }) - ref.current.addEventListener('canplaythrough', handleCanPlayThrough, { - signal: abortController.signal, - }) - ref.current.addEventListener('waiting', handleWaiting, { - signal: abortController.signal, - }) - ref.current.addEventListener('playing', handlePlaying, { - signal: abortController.signal, - }) - ref.current.addEventListener('stalled', handleStalled, { - signal: abortController.signal, - }) - ref.current.addEventListener('ended', handleEnded, { - signal: abortController.signal, - }) - - return () => { - abortController.abort() - clearTimeout(bufferingTimeout) - } - }, [ref, setVolume]) - - const play = useCallback(() => { - if (!ref.current) return - - if (ref.current.ended) { - ref.current.currentTime = 0 - } - - if (ref.current.readyState < HTMLMediaElement.HAVE_FUTURE_DATA) { - playWhenReadyRef.current = true - } else { - const promise = ref.current.play() - if (promise !== undefined) { - promise.catch(err => { - console.error('Error playing video:', err) - }) - } - } - }, [ref]) - - const pause = useCallback(() => { - if (!ref.current) return - - ref.current.pause() - playWhenReadyRef.current = false - }, [ref]) - - const togglePlayPause = useCallback(() => { - if (!ref.current) return - - if (ref.current.paused) { - play() - } else { - pause() - } - }, [ref, play, pause]) - - const changeMuted = useCallback( - (newMuted: boolean | ((prev: boolean) => boolean)) => { - if (!ref.current) return - - const value = - typeof newMuted === 'function' ? newMuted(ref.current.muted) : newMuted - ref.current.muted = value - }, - [ref], - ) - - return { - play, - pause, - togglePlayPause, - duration, - currentTime, - playing, - muted, - changeMuted, - buffering, - error, - canPlay, - } -} - -export function formatTime(time: number) { - if (isNaN(time)) { - return '--' - } - - time = Math.round(time) - - const minutes = Math.floor(time / 60) - const seconds = String(time % 60).padStart(2, '0') - - return `${minutes}:${seconds}` -} |