diff --git a/src/components/middle/message/hooks/useVideoAutoPause.ts b/src/components/middle/message/hooks/useVideoAutoPause.ts index 56eeb5490..f2ed86539 100644 --- a/src/components/middle/message/hooks/useVideoAutoPause.ts +++ b/src/components/middle/message/hooks/useVideoAutoPause.ts @@ -1,33 +1,31 @@ import { useCallback, useEffect, useRef } from '../../../../lib/teact/teact'; import { fastRaf } from '../../../../util/schedulers'; -import safePlay from '../../../../util/safePlay'; import useBackgroundMode from '../../../../hooks/useBackgroundMode'; import useHeavyAnimationCheck from '../../../../hooks/useHeavyAnimationCheck'; +import usePlayPause from '../../../../hooks/usePlayPause'; export default function useVideoAutoPause(playerRef: { current: HTMLVideoElement | null }, canPlay: boolean) { const canPlayRef = useRef(); canPlayRef.current = canPlay; + const { play, pause } = usePlayPause(playerRef); + const isFrozenRef = useRef(); const freezePlaying = useCallback(() => { isFrozenRef.current = true; - playerRef.current?.pause(); - }, [playerRef]); + pause(); + }, [pause]); const unfreezePlaying = useCallback(() => { isFrozenRef.current = false; - if ( - playerRef.current && canPlayRef.current - // At this point `HTMLVideoElement` can be unmounted from the DOM - && document.body.contains(playerRef.current) - ) { - safePlay(playerRef.current); + if (canPlayRef.current) { + play(); } - }, [playerRef]); + }, [play]); const unfreezePlayingOnRaf = useCallback(() => { fastRaf(unfreezePlaying); @@ -38,23 +36,19 @@ export default function useVideoAutoPause(playerRef: { current: HTMLVideoElement const handlePlaying = useCallback(() => { if (!canPlayRef.current || isFrozenRef.current) { - playerRef.current!.pause(); + pause(); } - }, [playerRef]); + }, [pause]); useEffect(() => { - if (!playerRef.current) { - return; - } - if (canPlay) { if (!isFrozenRef.current) { - safePlay(playerRef.current); + play(); } } else { - playerRef.current!.pause(); + pause(); } - }, [canPlay, playerRef]); + }, [canPlay, play, pause]); return { handlePlaying }; } diff --git a/src/hooks/usePlayPause.ts b/src/hooks/usePlayPause.ts new file mode 100644 index 000000000..dd4f6a97a --- /dev/null +++ b/src/hooks/usePlayPause.ts @@ -0,0 +1,33 @@ +import { useCallback, useRef } from '../lib/teact/teact'; + +export default function usePlayPause(mediaRef: React.RefObject) { + const shouldPauseRef = useRef(false); + const isLoadingPlayRef = useRef(false); + + const play = useCallback(() => { + shouldPauseRef.current = false; + if (mediaRef.current && !isLoadingPlayRef.current && document.body.contains(mediaRef.current)) { + isLoadingPlayRef.current = true; + mediaRef.current.play().then(() => { + isLoadingPlayRef.current = false; + if (shouldPauseRef.current) { + mediaRef.current?.pause(); + shouldPauseRef.current = false; + } + }).catch((e) => { + // eslint-disable-next-line no-console + console.warn(e); + }); + } + }, [mediaRef]); + + const pause = useCallback(() => { + if (isLoadingPlayRef.current) { + shouldPauseRef.current = true; + } else { + mediaRef.current?.pause(); + } + }, [mediaRef]); + + return { play, pause }; +}