Skip to content

Commit 59fe031

Browse files
authored
Merge pull request #86676 from software-mansion-labs/war-in/fix-OD-signout-bootsplash
fix: start HybridApp splashScreenState as undefined until native settings arrive
2 parents a718167 + 490a3c5 commit 59fe031

7 files changed

Lines changed: 58 additions & 39 deletions

File tree

src/Expensify.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,12 @@ function Expensify() {
292292
initialUrl={initialUrl}
293293
/>
294294
)}
295-
{shouldHideSplash && <SplashScreenHider onHide={onSplashHide} />}
295+
{(isSplashVisible || isSplashReadyToBeHidden) && (
296+
<SplashScreenHider
297+
shouldHideSplash={shouldHideSplash}
298+
onHide={onSplashHide}
299+
/>
300+
)}
296301
</>
297302
);
298303
}

src/HybridAppHandler.tsx

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {useCallback, useEffect} from 'react';
1+
import {useEffect} from 'react';
22
import CONFIG from './CONFIG';
33
import CONST from './CONST';
44
import useOnyx from './hooks/useOnyx';
@@ -9,35 +9,25 @@ import Log from './libs/Log';
99
import {endSpan, startSpan} from './libs/telemetry/activeSpans';
1010
import {addBootsplashBreadcrumb} from './libs/telemetry/bootsplashTelemetry';
1111
import ONYXKEYS from './ONYXKEYS';
12-
import {useSplashScreenActions, useSplashScreenState} from './SplashScreenStateContext';
12+
import {useSplashScreenActions} from './SplashScreenStateContext';
1313
import isLoadingOnyxValue from './types/utils/isLoadingOnyxValue';
1414

1515
function HybridAppHandler() {
16-
const {splashScreenState} = useSplashScreenState();
1716
const {setSplashScreenState} = useSplashScreenActions();
1817
const [tryNewDot, tryNewDotMetadata] = useOnyx(ONYXKEYS.NVP_TRY_NEW_DOT);
1918
const isLoadingTryNewDot = isLoadingOnyxValue(tryNewDotMetadata);
2019

21-
const finalizeTransitionFromOldDot = useCallback(
22-
(hybridAppSettings: HybridAppSettings) => {
23-
const loggedOutFromOldDot = !!hybridAppSettings.hybridApp.loggedOutFromOldDot;
20+
const finalizeTransitionFromOldDot = (hybridAppSettings: HybridAppSettings) => {
21+
const loggedOutFromOldDot = !!hybridAppSettings.hybridApp.loggedOutFromOldDot;
2422

25-
setupNewDotAfterTransitionFromOldDot(hybridAppSettings, tryNewDot).then(() => {
26-
if (splashScreenState !== CONST.BOOT_SPLASH_STATE.VISIBLE) {
27-
addBootsplashBreadcrumb('HybridAppHandler: Splash no longer VISIBLE, skipping state transition', {splashScreenState});
28-
return;
29-
}
30-
31-
if (loggedOutFromOldDot) {
32-
setSplashScreenState(CONST.BOOT_SPLASH_STATE.HIDDEN);
33-
endSpan(CONST.TELEMETRY.SPAN_OD_ND_TRANSITION_LOGGED_OUT);
34-
} else {
35-
setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN);
36-
}
37-
});
38-
},
39-
[setSplashScreenState, splashScreenState, tryNewDot],
40-
);
23+
setupNewDotAfterTransitionFromOldDot(hybridAppSettings, tryNewDot).then(() => {
24+
if (loggedOutFromOldDot) {
25+
endSpan(CONST.TELEMETRY.SPAN_OD_ND_TRANSITION_LOGGED_OUT);
26+
} else {
27+
setSplashScreenState(CONST.BOOT_SPLASH_STATE.READY_TO_BE_HIDDEN);
28+
}
29+
});
30+
};
4131

4232
useEffect(() => {
4333
if (!CONFIG.IS_HYBRID_APP || isLoadingTryNewDot) {
@@ -55,6 +45,14 @@ function HybridAppHandler() {
5545

5646
addBootsplashBreadcrumb('HybridAppHandler: Settings received', {loggedOutFromOldDot: String(!!hybridAppSettings.hybridApp.loggedOutFromOldDot)});
5747

48+
// Resolve splash state ASAP — this is the earliest moment we know
49+
// whether the native splash is on screen or not
50+
if (hybridAppSettings.hybridApp.loggedOutFromOldDot) {
51+
setSplashScreenState(CONST.BOOT_SPLASH_STATE.HIDDEN);
52+
} else {
53+
setSplashScreenState(CONST.BOOT_SPLASH_STATE.VISIBLE);
54+
}
55+
5856
if (hybridAppSettings.hybridApp.loggedOutFromOldDot) {
5957
startSpan(CONST.TELEMETRY.SPAN_OD_ND_TRANSITION_LOGGED_OUT, {
6058
name: CONST.TELEMETRY.SPAN_OD_ND_TRANSITION_LOGGED_OUT,
@@ -71,7 +69,7 @@ function HybridAppHandler() {
7169

7270
finalizeTransitionFromOldDot(hybridAppSettings);
7371
});
74-
}, [finalizeTransitionFromOldDot, isLoadingTryNewDot]);
72+
}, [finalizeTransitionFromOldDot, isLoadingTryNewDot, setSplashScreenState]);
7573

7674
return null;
7775
}

src/SplashScreenStateContext.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
import React, {useContext, useEffect, useState} from 'react';
22
import type {ValueOf} from 'type-fest';
3+
import CONFIG from './CONFIG';
34
import CONST from './CONST';
45
import {addBootsplashBreadcrumb} from './libs/telemetry/bootsplashTelemetry';
56
import type ChildrenProps from './types/utils/ChildrenProps';
67

78
type SplashScreenState = ValueOf<typeof CONST.BOOT_SPLASH_STATE>;
89

910
type SplashScreenStateContextType = {
10-
splashScreenState: SplashScreenState;
11+
splashScreenState: SplashScreenState | undefined;
1112
};
1213

1314
type SplashScreenActionsContextType = {
1415
setSplashScreenState: (state: SplashScreenState) => void;
1516
};
1617

1718
const SplashScreenStateContext = React.createContext<SplashScreenStateContextType>({
18-
splashScreenState: CONST.BOOT_SPLASH_STATE.VISIBLE,
19+
splashScreenState: undefined,
1920
});
2021

2122
const SplashScreenActionsContext = React.createContext<SplashScreenActionsContextType>({
@@ -29,7 +30,7 @@ function loadPostSplashScreenModules() {
2930
}
3031

3132
function SplashScreenStateContextProvider({children}: ChildrenProps) {
32-
const [splashScreenState, setSplashScreenStateRaw] = useState<SplashScreenState>(CONST.BOOT_SPLASH_STATE.VISIBLE);
33+
const [splashScreenState, setSplashScreenStateRaw] = useState<SplashScreenState | undefined>(CONFIG.IS_HYBRID_APP ? undefined : CONST.BOOT_SPLASH_STATE.VISIBLE);
3334

3435
const setSplashScreenState = (state: SplashScreenState) => {
3536
addBootsplashBreadcrumb(`splashScreenState changed to ${state}`);

src/components/SplashScreenHider/index.native.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {useCallback, useRef} from 'react';
1+
import {useEffect, useEffectEvent, useRef} from 'react';
22
import type {ViewStyle} from 'react-native';
33
import {StyleSheet} from 'react-native';
44
import Reanimated, {Easing, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
@@ -9,7 +9,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
99
import BootSplash from '@libs/BootSplash';
1010
import type {SplashScreenHiderProps, SplashScreenHiderReturnType} from './types';
1111

12-
function SplashScreenHider({onHide = () => {}}: SplashScreenHiderProps): SplashScreenHiderReturnType {
12+
function SplashScreenHider({onHide, shouldHideSplash}: SplashScreenHiderProps): SplashScreenHiderReturnType {
1313
const styles = useThemeStyles();
1414
const logoSizeRatio = BootSplash.logoSizeRatio || 1;
1515

@@ -24,8 +24,7 @@ function SplashScreenHider({onHide = () => {}}: SplashScreenHiderProps): SplashS
2424
}));
2525

2626
const hideHasBeenCalled = useRef(false);
27-
28-
const hide = useCallback(() => {
27+
const hide = useEffectEvent(() => {
2928
// hide can only be called once
3029
if (hideHasBeenCalled.current) {
3130
return;
@@ -52,13 +51,19 @@ function SplashScreenHider({onHide = () => {}}: SplashScreenHiderProps): SplashS
5251
),
5352
);
5453
});
55-
}, [opacity, scale, onHide]);
54+
});
55+
56+
useEffect(() => {
57+
if (!shouldHideSplash) {
58+
return;
59+
}
60+
hide();
61+
}, [shouldHideSplash]);
5662

5763
return (
5864
<Reanimated.View style={[StyleSheet.absoluteFill, styles.splashScreenHider, opacityStyle]}>
5965
<Reanimated.View style={scaleStyle}>
6066
<ImageSVG
61-
onLoadEnd={hide}
6267
contentFit="fill"
6368
style={{width: 100 * logoSizeRatio, height: 100 * logoSizeRatio}}
6469
src={Logo}

src/components/SplashScreenHider/index.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1-
import {useEffect} from 'react';
1+
import {useEffect, useEffectEvent} from 'react';
22
import BootSplash from '@libs/BootSplash';
33
import type {SplashScreenHiderProps, SplashScreenHiderReturnType} from './types';
44

5-
function SplashScreenHider({onHide = () => {}}: SplashScreenHiderProps): SplashScreenHiderReturnType {
6-
useEffect(() => {
5+
function SplashScreenHider({onHide, shouldHideSplash}: SplashScreenHiderProps): SplashScreenHiderReturnType {
6+
const hide = useEffectEvent(() => {
77
BootSplash.hide().then(() => onHide());
8-
}, [onHide]);
8+
});
9+
10+
useEffect(() => {
11+
if (!shouldHideSplash) {
12+
return;
13+
}
14+
hide();
15+
}, [shouldHideSplash]);
916

1017
return null;
1118
}

src/components/SplashScreenHider/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import type {ReactNode} from 'react';
33
type SplashScreenHiderProps = {
44
/** Splash screen has been hidden */
55
onHide: () => void;
6+
7+
/** Whether the splash screen should be hidden */
8+
shouldHideSplash: boolean;
69
};
710

811
type SplashScreenHiderReturnType = ReactNode;

src/libs/telemetry/bootsplashTelemetry.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function addBootsplashBreadcrumb(message: string, data?: Record<string, string>,
1616
}
1717

1818
type BootsplashGateStatus = {
19-
splashScreenState: string;
19+
splashScreenState: string | undefined;
2020
isOnyxMigrated: boolean;
2121
isCheckingPublicRoom: boolean;
2222
hasAttemptedToOpenPublicRoom: boolean;
@@ -35,7 +35,7 @@ function startBootsplashMonitor(gateStatusRef: React.RefObject<BootsplashGateSta
3535
const appState = AppState.currentState;
3636
Log.info('[BootSplash] splash screen status', false, {appState, splashScreenState: currentGateStatus?.splashScreenState});
3737

38-
if (currentGateStatus?.splashScreenState !== CONST.BOOT_SPLASH_STATE.VISIBLE) {
38+
if (currentGateStatus?.splashScreenState !== CONST.BOOT_SPLASH_STATE.VISIBLE && currentGateStatus?.splashScreenState !== undefined) {
3939
clearInterval(intervalId);
4040
return;
4141
}

0 commit comments

Comments
 (0)