Optimized Video, Animtated Sticker: Unsubscribe from auto-pause when is not played

This commit is contained in:
Alexander Zinchuk 2023-03-30 20:29:03 -05:00
parent 61a5ea2466
commit fc5686bb43
3 changed files with 17 additions and 12 deletions

View File

@ -13,6 +13,7 @@ import generateIdFor from '../../util/generateIdFor';
import useHeavyAnimationCheck from '../../hooks/useHeavyAnimationCheck'; import useHeavyAnimationCheck from '../../hooks/useHeavyAnimationCheck';
import useBackgroundMode from '../../hooks/useBackgroundMode'; import useBackgroundMode from '../../hooks/useBackgroundMode';
import useSyncEffect from '../../hooks/useSyncEffect'; import useSyncEffect from '../../hooks/useSyncEffect';
import { useStateRef } from '../../hooks/useStateRef';
export type OwnProps = { export type OwnProps = {
ref?: RefObject<HTMLDivElement>; ref?: RefObject<HTMLDivElement>;
@ -94,10 +95,9 @@ const AnimatedSticker: FC<OwnProps> = ({
const isFrozen = useRef(false); const isFrozen = useRef(false);
const isFirstRender = useRef(true); const isFirstRender = useRef(true);
const playRef = useRef(); const canPlay = play || playSegment;
playRef.current = play; const playRef = useStateRef(play);
const playSegmentRef = useRef<[number, number]>(); const playSegmentRef = useStateRef(playSegment);
playSegmentRef.current = playSegment;
const isUnmountedRef = useRef(); const isUnmountedRef = useRef();
useEffect(() => { useEffect(() => {
@ -189,7 +189,7 @@ const AnimatedSticker: FC<OwnProps> = ({
animation.play(shouldRestart, viewId); animation.play(shouldRestart, viewId);
} }
} }
}, [animation, viewId]); }, [animation, playRef, playSegmentRef, viewId]);
const pauseAnimation = useCallback(() => { const pauseAnimation = useCallback(() => {
if (!animation) { if (!animation) {
@ -242,7 +242,7 @@ const AnimatedSticker: FC<OwnProps> = ({
if (!animation) { if (!animation) {
return; return;
} }
if (play || playSegment) { if (canPlay) {
if (isFrozen.current) { if (isFrozen.current) {
wasPlaying.current = true; wasPlaying.current = true;
} else { } else {
@ -256,7 +256,7 @@ const AnimatedSticker: FC<OwnProps> = ({
pauseAnimation(); pauseAnimation();
} }
} }
}, [animation, play, playSegment, noLoop, playAnimation, pauseAnimation]); }, [animation, canPlay, noLoop, playAnimation, pauseAnimation]);
useEffect(() => { useEffect(() => {
if (animation) { if (animation) {
@ -269,11 +269,11 @@ const AnimatedSticker: FC<OwnProps> = ({
} }
}, [playAnimation, animation, tgsUrl]); }, [playAnimation, animation, tgsUrl]);
useHeavyAnimationCheck(freezeAnimation, unfreezeAnimation, forceOnHeavyAnimation); useHeavyAnimationCheck(freezeAnimation, unfreezeAnimation, !canPlay || forceOnHeavyAnimation);
// Pausing frame may not happen in background, // Pausing frame may not happen in background,
// so we need to make sure it happens right after focusing, // so we need to make sure it happens right after focusing,
// then we can play again. // then we can play again.
useBackgroundMode(freezeAnimation, unfreezeAnimationOnRaf); useBackgroundMode(freezeAnimation, unfreezeAnimationOnRaf, !canPlay);
if (sharedCanvas) { if (sharedCanvas) {
return undefined; return undefined;

View File

@ -31,8 +31,8 @@ export default function useVideoAutoPause(playerRef: { current: HTMLVideoElement
fastRaf(unfreezePlaying); fastRaf(unfreezePlaying);
}, [unfreezePlaying]); }, [unfreezePlaying]);
useBackgroundMode(freezePlaying, unfreezePlayingOnRaf); useBackgroundMode(freezePlaying, unfreezePlayingOnRaf, !canPlay);
useHeavyAnimationCheck(freezePlaying, unfreezePlaying); useHeavyAnimationCheck(freezePlaying, unfreezePlaying, !canPlay);
const handlePlaying = useCallback(() => { const handlePlaying = useCallback(() => {
if (!canPlayRef.current || isFrozenRef.current) { if (!canPlayRef.current || isFrozenRef.current) {

View File

@ -3,6 +3,7 @@ import { useCallback, useEffect, useRef } from '../lib/teact/teact';
export default function useBackgroundMode( export default function useBackgroundMode(
onBlur?: AnyToVoidFunction, onBlur?: AnyToVoidFunction,
onFocus?: AnyToVoidFunction, onFocus?: AnyToVoidFunction,
isDisabled = false,
) { ) {
const wasBlurred = useRef<boolean>(false); const wasBlurred = useRef<boolean>(false);
const handleBlur = useCallback(() => { const handleBlur = useCallback(() => {
@ -19,6 +20,10 @@ export default function useBackgroundMode(
}, [onFocus]); }, [onFocus]);
useEffect(() => { useEffect(() => {
if (isDisabled) {
return undefined;
}
if (onBlur && !document.hasFocus()) { if (onBlur && !document.hasFocus()) {
handleBlur(); handleBlur();
} }
@ -40,5 +45,5 @@ export default function useBackgroundMode(
window.removeEventListener('blur', handleBlur); window.removeEventListener('blur', handleBlur);
} }
}; };
}, [handleBlur, handleFocus, onBlur, onFocus]); }, [handleBlur, handleFocus, isDisabled, onBlur, onFocus]);
} }