From 8e763e9954a141f2d9328472da4346dccfb3967b Mon Sep 17 00:00:00 2001 From: layacat Date: Fri, 4 Oct 2024 09:50:15 +0700 Subject: [PATCH] fix: Book travel - Book travel animation becomes blank while RHP is dismissed --- src/components/Lottie/index.tsx | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/components/Lottie/index.tsx b/src/components/Lottie/index.tsx index eee037e083f7..6bec356009fd 100644 --- a/src/components/Lottie/index.tsx +++ b/src/components/Lottie/index.tsx @@ -1,8 +1,7 @@ import {NavigationContainerRefContext, NavigationContext} from '@react-navigation/native'; import type {AnimationObject, LottieViewProps} from 'lottie-react-native'; import LottieView from 'lottie-react-native'; -import type {ForwardedRef} from 'react'; -import React, {forwardRef, useContext, useEffect, useState} from 'react'; +import React, {forwardRef, useContext, useEffect, useRef, useState} from 'react'; import {InteractionManager, View} from 'react-native'; import type DotLottieAnimation from '@components/LottieAnimations/types'; import useAppState from '@hooks/useAppState'; @@ -18,7 +17,8 @@ type Props = { shouldLoadAfterInteractions?: boolean; } & Omit; -function Lottie({source, webStyle, shouldLoadAfterInteractions, ...props}: Props, ref: ForwardedRef) { +function Lottie({source, webStyle, shouldLoadAfterInteractions, ...props}: Props) { + const animationRef = useRef(null); const appState = useAppState(); const {splashScreenState} = useSplashScreenStateContext(); const styles = useThemeStyles(); @@ -79,19 +79,20 @@ function Lottie({source, webStyle, shouldLoadAfterInteractions, ...props}: Props return unsubscribeNavigationBlur; }, [browser, navigationContainerRef, navigator]); + // If user is being navigated away, let pause the animation to prevent memory leak. + useEffect(() => { + if (!animationRef || !hasNavigatedAway) { + return; + } + animationRef?.current?.pause(); + }, [hasNavigatedAway]); + // If the page navigates to another screen, the image fails to load, app is in background state, animation file isn't ready, or the splash screen isn't hidden yet, // we'll just render an empty view as the fallback to prevent // 1. memory leak, see issue: https://github.com/Expensify/App/issues/36645 // 2. heavy rendering, see issues: https://github.com/Expensify/App/issues/34696 and https://github.com/Expensify/App/issues/47273 // 3. lag on react navigation transitions, see issue: https://github.com/Expensify/App/issues/44812 - if ( - hasNavigatedAway || - isError || - appState.isBackground || - !animationFile || - splashScreenState !== CONST.BOOT_SPLASH_STATE.HIDDEN || - (!isInteractionComplete && shouldLoadAfterInteractions) - ) { + if (isError || appState.isBackground || !animationFile || splashScreenState !== CONST.BOOT_SPLASH_STATE.HIDDEN || (!isInteractionComplete && shouldLoadAfterInteractions)) { return ; } @@ -100,7 +101,7 @@ function Lottie({source, webStyle, shouldLoadAfterInteractions, ...props}: Props // eslint-disable-next-line react/jsx-props-no-spreading {...props} source={animationFile} - ref={ref} + ref={animationRef} style={[aspectRatioStyle, props.style]} webStyle={{...aspectRatioStyle, ...webStyle}} onAnimationFailure={() => setIsError(true)}