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();
+ }}
/>