diff --git a/src/hooks/useIntersectionObserver.ts b/src/hooks/useIntersectionObserver.ts index 8bb94095..71591dad 100644 --- a/src/hooks/useIntersectionObserver.ts +++ b/src/hooks/useIntersectionObserver.ts @@ -22,6 +22,8 @@ interface Response { unfreeze: NoneToVoidFunction; } +const AUTO_UNFREEZE_TIMEOUT = 2000; + export function useIntersectionObserver({ rootRef, throttleMs, @@ -42,14 +44,11 @@ export function useIntersectionObserver({ const controllerRef = useRef(); const rootCallbackRef = useRef(); const freezeFlagsRef = useRef(0); + const autoUnfreezeTimeoutRef = useRef(); const onUnfreezeRef = useRef(); rootCallbackRef.current = rootCallback; - const freeze = useCallback(() => { - freezeFlagsRef.current++; - }, []); - const unfreeze = useCallback(() => { if (!freezeFlagsRef.current) { return; @@ -63,6 +62,27 @@ export function useIntersectionObserver({ } }, []); + const freeze = useCallback(() => { + freezeFlagsRef.current++; + + if (autoUnfreezeTimeoutRef.current) { + clearTimeout(autoUnfreezeTimeoutRef.current); + autoUnfreezeTimeoutRef.current = undefined; + } + + // Make sure to unfreeze even if unfreeze callback was not called (which was some hardly-reproducible bug) + autoUnfreezeTimeoutRef.current = window.setTimeout(() => { + autoUnfreezeTimeoutRef.current = undefined; + + if (!freezeFlagsRef.current) { + return; + } + + freezeFlagsRef.current = 1; + unfreeze(); + }, AUTO_UNFREEZE_TIMEOUT); + }, [unfreeze]); + useHeavyAnimationCheck(freeze, unfreeze); useEffect(() => {