diff --git a/src/Expensify.tsx b/src/Expensify.tsx
index 0163dfb2438e5..9c5f021b57bb3 100644
--- a/src/Expensify.tsx
+++ b/src/Expensify.tsx
@@ -292,7 +292,12 @@ function Expensify() {
initialUrl={initialUrl}
/>
)}
- {shouldHideSplash && }
+ {(isSplashVisible || isSplashReadyToBeHidden) && (
+
+ )}
>
);
}
diff --git a/src/HybridAppHandler.tsx b/src/HybridAppHandler.tsx
index 59f76d7da3529..050ef5f261ef0 100644
--- a/src/HybridAppHandler.tsx
+++ b/src/HybridAppHandler.tsx
@@ -1,4 +1,4 @@
-import {useCallback, useEffect} from 'react';
+import {useEffect} from 'react';
import CONFIG from './CONFIG';
import CONST from './CONST';
import useOnyx from './hooks/useOnyx';
@@ -9,35 +9,25 @@ import Log from './libs/Log';
import {endSpan, startSpan} from './libs/telemetry/activeSpans';
import {addBootsplashBreadcrumb} from './libs/telemetry/bootsplashTelemetry';
import ONYXKEYS from './ONYXKEYS';
-import {useSplashScreenActions, useSplashScreenState} from './SplashScreenStateContext';
+import {useSplashScreenActions} from './SplashScreenStateContext';
import isLoadingOnyxValue from './types/utils/isLoadingOnyxValue';
function HybridAppHandler() {
- const {splashScreenState} = useSplashScreenState();
const {setSplashScreenState} = useSplashScreenActions();
const [tryNewDot, tryNewDotMetadata] = useOnyx(ONYXKEYS.NVP_TRY_NEW_DOT);
const isLoadingTryNewDot = isLoadingOnyxValue(tryNewDotMetadata);
- const finalizeTransitionFromOldDot = useCallback(
- (hybridAppSettings: HybridAppSettings) => {
- const loggedOutFromOldDot = !!hybridAppSettings.hybridApp.loggedOutFromOldDot;
+ const finalizeTransitionFromOldDot = (hybridAppSettings: HybridAppSettings) => {
+ const loggedOutFromOldDot = !!hybridAppSettings.hybridApp.loggedOutFromOldDot;
- setupNewDotAfterTransitionFromOldDot(hybridAppSettings, tryNewDot).then(() => {
- if (splashScreenState !== CONST.BOOT_SPLASH_STATE.VISIBLE) {
- addBootsplashBreadcrumb('HybridAppHandler: Splash no longer VISIBLE, skipping state transition', {splashScreenState});
- return;
- }
-
- if (loggedOutFromOldDot) {
- setSplashScreenState(CONST.BOOT_SPLASH_STATE.HIDDEN);
- endSpan(CONST.TELEMETRY.SPAN_OD_ND_TRANSITION_LOGGED_OUT);
- } else {
- setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN);
- }
- });
- },
- [setSplashScreenState, splashScreenState, tryNewDot],
- );
+ setupNewDotAfterTransitionFromOldDot(hybridAppSettings, tryNewDot).then(() => {
+ if (loggedOutFromOldDot) {
+ endSpan(CONST.TELEMETRY.SPAN_OD_ND_TRANSITION_LOGGED_OUT);
+ } else {
+ setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN);
+ }
+ });
+ };
useEffect(() => {
if (!CONFIG.IS_HYBRID_APP || isLoadingTryNewDot) {
@@ -55,6 +45,14 @@ function HybridAppHandler() {
addBootsplashBreadcrumb('HybridAppHandler: Settings received', {loggedOutFromOldDot: String(!!hybridAppSettings.hybridApp.loggedOutFromOldDot)});
+ // Resolve splash state ASAP — this is the earliest moment we know
+ // whether the native splash is on screen or not
+ if (hybridAppSettings.hybridApp.loggedOutFromOldDot) {
+ setSplashScreenState(CONST.BOOT_SPLASH_STATE.HIDDEN);
+ } else {
+ setSplashScreenState(CONST.BOOT_SPLASH_STATE.VISIBLE);
+ }
+
if (hybridAppSettings.hybridApp.loggedOutFromOldDot) {
startSpan(CONST.TELEMETRY.SPAN_OD_ND_TRANSITION_LOGGED_OUT, {
name: CONST.TELEMETRY.SPAN_OD_ND_TRANSITION_LOGGED_OUT,
@@ -71,7 +69,7 @@ function HybridAppHandler() {
finalizeTransitionFromOldDot(hybridAppSettings);
});
- }, [finalizeTransitionFromOldDot, isLoadingTryNewDot]);
+ }, [finalizeTransitionFromOldDot, isLoadingTryNewDot, setSplashScreenState]);
return null;
}
diff --git a/src/SplashScreenStateContext.tsx b/src/SplashScreenStateContext.tsx
index b07b2c068a891..272510e2b6fbb 100644
--- a/src/SplashScreenStateContext.tsx
+++ b/src/SplashScreenStateContext.tsx
@@ -1,5 +1,6 @@
import React, {useContext, useEffect, useState} from 'react';
import type {ValueOf} from 'type-fest';
+import CONFIG from './CONFIG';
import CONST from './CONST';
import {addBootsplashBreadcrumb} from './libs/telemetry/bootsplashTelemetry';
import type ChildrenProps from './types/utils/ChildrenProps';
@@ -7,7 +8,7 @@ import type ChildrenProps from './types/utils/ChildrenProps';
type SplashScreenState = ValueOf;
type SplashScreenStateContextType = {
- splashScreenState: SplashScreenState;
+ splashScreenState: SplashScreenState | undefined;
};
type SplashScreenActionsContextType = {
@@ -15,7 +16,7 @@ type SplashScreenActionsContextType = {
};
const SplashScreenStateContext = React.createContext({
- splashScreenState: CONST.BOOT_SPLASH_STATE.VISIBLE,
+ splashScreenState: undefined,
});
const SplashScreenActionsContext = React.createContext({
@@ -29,7 +30,7 @@ function loadPostSplashScreenModules() {
}
function SplashScreenStateContextProvider({children}: ChildrenProps) {
- const [splashScreenState, setSplashScreenStateRaw] = useState(CONST.BOOT_SPLASH_STATE.VISIBLE);
+ const [splashScreenState, setSplashScreenStateRaw] = useState(CONFIG.IS_HYBRID_APP ? undefined : CONST.BOOT_SPLASH_STATE.VISIBLE);
const setSplashScreenState = (state: SplashScreenState) => {
addBootsplashBreadcrumb(`splashScreenState changed to ${state}`);
diff --git a/src/libs/telemetry/bootsplashTelemetry.ts b/src/libs/telemetry/bootsplashTelemetry.ts
index 776177a99ac9c..028c84d7feb8e 100644
--- a/src/libs/telemetry/bootsplashTelemetry.ts
+++ b/src/libs/telemetry/bootsplashTelemetry.ts
@@ -16,7 +16,7 @@ function addBootsplashBreadcrumb(message: string, data?: Record,
}
type BootsplashGateStatus = {
- splashScreenState: string;
+ splashScreenState: string | undefined;
isOnyxMigrated: boolean;
isCheckingPublicRoom: boolean;
hasAttemptedToOpenPublicRoom: boolean;
@@ -35,7 +35,7 @@ function startBootsplashMonitor(gateStatusRef: React.RefObject