diff --git a/src/components/middle/message/RoundVideo.tsx b/src/components/middle/message/RoundVideo.tsx index f85ee9a7..aa1b5fa7 100644 --- a/src/components/middle/message/RoundVideo.tsx +++ b/src/components/middle/message/RoundVideo.tsx @@ -21,6 +21,7 @@ import buildClassName from '../../../util/buildClassName'; import useHeavyAnimationCheckForVideo from '../../../hooks/useHeavyAnimationCheckForVideo'; import useVideoCleanup from '../../../hooks/useVideoCleanup'; import useBlurredMediaThumb from './hooks/useBlurredMediaThumb'; +import usePauseOnInactive from './hooks/usePauseOnInactive'; import safePlay from '../../../util/safePlay'; import ProgressSpinner from '../../ui/ProgressSpinner'; @@ -141,6 +142,8 @@ const RoundVideo: FC = ({ useHeavyAnimationCheckForVideo(playerRef, shouldPlay); + usePauseOnInactive(playerRef, Boolean(mediaData)); + useVideoCleanup(playerRef, [mediaData]); const handleClick = useCallback(() => { diff --git a/src/components/middle/message/Video.tsx b/src/components/middle/message/Video.tsx index 526e91bf..e57d3701 100644 --- a/src/components/middle/message/Video.tsx +++ b/src/components/middle/message/Video.tsx @@ -26,6 +26,7 @@ import useBuffering from '../../../hooks/useBuffering'; import useHeavyAnimationCheckForVideo from '../../../hooks/useHeavyAnimationCheckForVideo'; import useBlurredMediaThumb from './hooks/useBlurredMediaThumb'; import useVideoCleanup from '../../../hooks/useVideoCleanup'; +import usePauseOnInactive from './hooks/usePauseOnInactive'; import ProgressSpinner from '../../ui/ProgressSpinner'; @@ -109,7 +110,9 @@ const Video: FC = ({ const isForwarded = isForwardedMessage(message); const { width, height } = dimensions || calculateVideoDimensions(video, isOwn, isForwarded); - useHeavyAnimationCheckForVideo(videoRef, isInline); + useHeavyAnimationCheckForVideo(videoRef, Boolean(isInline && shouldAutoPlay)); + + usePauseOnInactive(videoRef, isPlayAllowed); useVideoCleanup(videoRef, [isInline]); diff --git a/src/components/middle/message/hooks/usePauseOnInactive.ts b/src/components/middle/message/hooks/usePauseOnInactive.ts new file mode 100644 index 00000000..db01cf55 --- /dev/null +++ b/src/components/middle/message/hooks/usePauseOnInactive.ts @@ -0,0 +1,43 @@ +import { useCallback, useRef } from '../../../../lib/teact/teact'; +import { fastRaf } from '../../../../util/schedulers'; +import useBackgroundMode from '../../../../hooks/useBackgroundMode'; +import safePlay from '../../../../util/safePlay'; + +export default (playerRef: { current: HTMLVideoElement | null }, isPlayAllowed = false) => { + const wasPlaying = useRef(false); + const isFrozen = useRef(false); + + const freezePlaying = useCallback(() => { + isFrozen.current = true; + + if (!isPlayAllowed || !playerRef.current) { + return; + } + + if (!wasPlaying.current) { + wasPlaying.current = !playerRef.current.paused; + } + + playerRef.current.pause(); + }, [isPlayAllowed, playerRef]); + + const unfreezePlaying = useCallback(() => { + // At this point HTMLVideoElement can be unmounted from the DOM + if (isPlayAllowed && playerRef.current && wasPlaying.current && document.body.contains(playerRef.current)) { + safePlay(playerRef.current); + } + + wasPlaying.current = false; + isFrozen.current = false; + }, [isPlayAllowed, playerRef]); + + const unfreezePlayingOnRaf = useCallback(() => { + fastRaf(unfreezePlaying); + }, [unfreezePlaying]); + + if (!document.hasFocus()) { + freezePlaying(); + } + + useBackgroundMode(freezePlaying, unfreezePlayingOnRaf); +};