diff --git a/src/Expensify.js b/src/Expensify.js index 0707ba069241..f1d14dd59613 100644 --- a/src/Expensify.js +++ b/src/Expensify.js @@ -64,6 +64,9 @@ const propTypes = { /** Tells us if the sidebar has rendered */ isSidebarLoaded: PropTypes.bool, + /** Tells us if the boot splash is auto hide */ + isBootSplashAutoHide: PropTypes.bool, + /** Information about a screen share call requested by a GuidesPlus agent */ screenShareRequest: PropTypes.shape({ /** Access token required to join a screen share room, generated by the backend */ @@ -89,6 +92,7 @@ const defaultProps = { }, updateAvailable: false, isSidebarLoaded: false, + isBootSplashAutoHide: true, screenShareRequest: null, isCheckingPublicRoom: true, focusModeNotification: false, @@ -121,7 +125,7 @@ function Expensify(props) { ); const shouldInit = isNavigationReady && (!isAuthenticated || props.isSidebarLoaded) && hasAttemptedToOpenPublicRoom; - const shouldHideSplash = shouldInit && !isSplashHidden; + const shouldHideSplash = shouldInit && !isSplashHidden && props.isBootSplashAutoHide; const initializeClient = () => { if (!Visibility.isVisible()) { @@ -265,6 +269,9 @@ export default compose( isSidebarLoaded: { key: ONYXKEYS.IS_SIDEBAR_LOADED, }, + isBootSplashAutoHide: { + key: ONYXKEYS.IS_BOOT_SPLASH_AUTO_HIDE, + }, screenShareRequest: { key: ONYXKEYS.SCREEN_SHARE_REQUEST, }, diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 26424af8056c..4ca278e2aa8b 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -27,6 +27,9 @@ const ONYXKEYS = { /** Boolean flag set whenever the sidebar has loaded */ IS_SIDEBAR_LOADED: 'isSidebarLoaded', + /** Boolean flag set whenever the sidebar has loaded */ + IS_BOOT_SPLASH_AUTO_HIDE: 'isBootSplashAutoHide', + /** Boolean flag set whenever we are searching for reports in the server */ IS_SEARCHING_FOR_REPORTS: 'isSearchingForReports', @@ -373,6 +376,7 @@ type OnyxValues = { [ONYXKEYS.ACTIVE_CLIENTS]: string[]; [ONYXKEYS.DEVICE_ID]: string; [ONYXKEYS.IS_SIDEBAR_LOADED]: boolean; + [ONYXKEYS.IS_BOOT_SPLASH_AUTO_HIDE]: boolean; [ONYXKEYS.PERSISTED_REQUESTS]: OnyxTypes.Request[]; [ONYXKEYS.CURRENT_DATE]: string; [ONYXKEYS.CREDENTIALS]: OnyxTypes.Credentials; diff --git a/src/libs/actions/App.ts b/src/libs/actions/App.ts index 768dc530cc51..8e17c1700e1e 100644 --- a/src/libs/actions/App.ts +++ b/src/libs/actions/App.ts @@ -48,6 +48,13 @@ Onyx.connect({ initWithStoredValues: false, }); +let isBootSplashAutoHide: boolean | null; +Onyx.connect({ + key: ONYXKEYS.IS_BOOT_SPLASH_AUTO_HIDE, + callback: (val) => (isBootSplashAutoHide = val), + initWithStoredValues: true, +}); + let preferredLocale: string | null; Onyx.connect({ key: ONYXKEYS.NVP_PREFERRED_LOCALE, @@ -129,6 +136,22 @@ function setSidebarLoaded() { Performance.markStart(CONST.TIMING.REPORT_INITIAL_RENDER); } +function preventBootSplashAutoHide() { + if (!isBootSplashAutoHide) { + return; + } + + Onyx.set(ONYXKEYS.IS_BOOT_SPLASH_AUTO_HIDE, false); +} + +function resetBootSplashAutoHide() { + if (isBootSplashAutoHide) { + return; + } + + Onyx.set(ONYXKEYS.IS_BOOT_SPLASH_AUTO_HIDE, true); +} + let appState: AppStateStatus; AppState.addEventListener('change', (nextAppState) => { if (nextAppState.match(/inactive|background/) && appState === 'active') { @@ -531,6 +554,8 @@ export { setLocale, setLocaleAndNavigate, setSidebarLoaded, + preventBootSplashAutoHide, + resetBootSplashAutoHide, setUpPoliciesAndNavigate, openProfile, redirectThirdPartyDesktopSignIn, diff --git a/src/pages/signin/SignInPageLayout/BackgroundImage/index.android.js b/src/pages/signin/SignInPageLayout/BackgroundImage/index.android.js index 717f9a3e718c..3d3adb0a6683 100644 --- a/src/pages/signin/SignInPageLayout/BackgroundImage/index.android.js +++ b/src/pages/signin/SignInPageLayout/BackgroundImage/index.android.js @@ -1,9 +1,21 @@ import {Image} from 'expo-image'; +import PropTypes from 'prop-types'; import React from 'react'; import AndroidBackgroundImage from '@assets/images/home-background--android.svg'; import useThemeStyles from '@hooks/useThemeStyles'; import defaultPropTypes from './propTypes'; +const defaultProps = { + onLoadEnd: () => {}, +}; + +const propTypes = { + /** Called when the image load either succeeds or fails. */ + onLoadEnd: PropTypes.func, + + ...defaultPropTypes, +}; + function BackgroundImage(props) { const styles = useThemeStyles(); return ( @@ -11,11 +23,13 @@ function BackgroundImage(props) { source={AndroidBackgroundImage} pointerEvents={props.pointerEvents} style={[styles.signInBackground, {width: props.width}]} + onLoadEnd={props.onLoadEnd} /> ); } BackgroundImage.displayName = 'BackgroundImage'; -BackgroundImage.propTypes = defaultPropTypes; +BackgroundImage.propTypes = propTypes; +BackgroundImage.defaultProps = defaultProps; export default BackgroundImage; diff --git a/src/pages/signin/SignInPageLayout/BackgroundImage/index.ios.js b/src/pages/signin/SignInPageLayout/BackgroundImage/index.ios.js index da6a6b9ee4fb..bf65f1f3fdf6 100644 --- a/src/pages/signin/SignInPageLayout/BackgroundImage/index.ios.js +++ b/src/pages/signin/SignInPageLayout/BackgroundImage/index.ios.js @@ -9,14 +9,19 @@ import defaultPropTypes from './propTypes'; const defaultProps = { isSmallScreen: false, + onLoadEnd: () => {}, }; const propTypes = { /** Is the window width narrow, like on a mobile device */ isSmallScreen: PropTypes.bool, + /** Called when the image load either succeeds or fails. */ + onLoadEnd: PropTypes.func, + ...defaultPropTypes, }; + function BackgroundImage(props) { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); @@ -26,6 +31,7 @@ function BackgroundImage(props) { ); } diff --git a/src/pages/signin/SignInPageLayout/BackgroundImage/index.js b/src/pages/signin/SignInPageLayout/BackgroundImage/index.js index ac93ceeb4e2c..151f83f61809 100644 --- a/src/pages/signin/SignInPageLayout/BackgroundImage/index.js +++ b/src/pages/signin/SignInPageLayout/BackgroundImage/index.js @@ -1,5 +1,5 @@ import PropTypes from 'prop-types'; -import React from 'react'; +import React, {useEffect} from 'react'; import DesktopBackgroundImage from '@assets/images/home-background--desktop.svg'; import MobileBackgroundImage from '@assets/images/home-background--mobile.svg'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -7,16 +7,27 @@ import defaultPropTypes from './propTypes'; const defaultProps = { isSmallScreen: false, + onLoadEnd: () => {}, }; const propTypes = { /** Is the window width narrow, like on a mobile device */ isSmallScreen: PropTypes.bool, + /** Called when the image load either succeeds or fails. */ + onLoadEnd: PropTypes.func, + ...defaultPropTypes, }; + function BackgroundImage(props) { const styles = useThemeStyles(); + + useEffect(() => { + props.onLoadEnd(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + return props.isSmallScreen ? ( { + App.preventBootSplashAutoHide(); + }, []); + useEffect(() => { if (prevPreferredLocale !== props.preferredLocale) { return; @@ -99,6 +106,7 @@ function SignInPageLayout(props) { return ( + {isLoading && } {!props.shouldShowSmallScreen ? ( { + setIsLoading(false); + App.resetBootSplashAutoHide(); + }} /> @@ -166,6 +178,10 @@ function SignInPageLayout(props) { isSmallScreen pointerEvents="none" width={variables.signInHeroBackgroundWidthMobile} + onLoadEnd={() => { + setIsLoading(false); + App.resetBootSplashAutoHide(); + }} />