diff --git a/src/components/HybridAppMiddleware/index.ios.tsx b/src/components/HybridAppMiddleware/index.ios.tsx index 1ea8e62ab17e..aee837e02dea 100644 --- a/src/components/HybridAppMiddleware/index.ios.tsx +++ b/src/components/HybridAppMiddleware/index.ios.tsx @@ -1,5 +1,5 @@ import type React from 'react'; -import {useContext, useEffect, useState} from 'react'; +import {useContext, useEffect, useRef, useState} from 'react'; import {NativeEventEmitter, NativeModules} from 'react-native'; import type {NativeModule} from 'react-native'; import {useOnyx} from 'react-native-onyx'; @@ -15,6 +15,7 @@ import * as Welcome from '@userActions/Welcome'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {HybridAppRoute, Route} from '@src/ROUTES'; +import ROUTES from '@src/ROUTES'; import type {TryNewDot} from '@src/types/onyx'; type HybridAppMiddlewareProps = { @@ -50,6 +51,20 @@ function HybridAppMiddleware({children, authenticated}: HybridAppMiddlewareProps const [sessionEmail] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.email}); const [completedHybridAppOnboarding] = useOnyx(ONYXKEYS.NVP_TRYNEWDOT, {selector: onboardingStatusSelector}); + const maxTimeoutRef = useRef(null); + + // We need to ensure that the BootSplash is always hidden after a certain period. + useEffect(() => { + if (!NativeModules.HybridAppModule) { + return; + } + + maxTimeoutRef.current = setTimeout(() => { + Log.info('[HybridApp] Forcing transition due to unknown problem', true); + setStartedTransition(true); + setExitTo(ROUTES.HOME); + }, 3000); + }, []); /** * This useEffect tracks changes of `nvp_tryNewDot` value. * We propagate it from OldDot to NewDot with native method due to limitations of old app. diff --git a/src/components/HybridAppMiddleware/index.tsx b/src/components/HybridAppMiddleware/index.tsx index 5a8d8d6dfebe..bb5d7803e52e 100644 --- a/src/components/HybridAppMiddleware/index.tsx +++ b/src/components/HybridAppMiddleware/index.tsx @@ -1,5 +1,5 @@ import type React from 'react'; -import {useContext, useEffect, useState} from 'react'; +import {useContext, useEffect, useRef, useState} from 'react'; import {NativeModules} from 'react-native'; import {useOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; @@ -14,6 +14,7 @@ import * as Welcome from '@userActions/Welcome'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {HybridAppRoute, Route} from '@src/ROUTES'; +import ROUTES from '@src/ROUTES'; import type {TryNewDot} from '@src/types/onyx'; type HybridAppMiddlewareProps = { @@ -49,6 +50,20 @@ function HybridAppMiddleware({children, authenticated}: HybridAppMiddlewareProps const [sessionEmail] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.email}); const [completedHybridAppOnboarding] = useOnyx(ONYXKEYS.NVP_TRYNEWDOT, {selector: onboardingStatusSelector}); + const maxTimeoutRef = useRef(null); + + // We need to ensure that the BootSplash is always hidden after a certain period. + useEffect(() => { + if (!NativeModules.HybridAppModule) { + return; + } + + maxTimeoutRef.current = setTimeout(() => { + Log.info('[HybridApp] Forcing transition due to unknown problem', true); + setStartedTransition(true); + setExitTo(ROUTES.HOME); + }, 3000); + }, []); /** * This useEffect tracks changes of `nvp_tryNewDot` value. * We propagate it from OldDot to NewDot with native method due to limitations of old app. @@ -93,13 +108,15 @@ function HybridAppMiddleware({children, authenticated}: HybridAppMiddlewareProps Navigation.isNavigationReady().then(() => { // We need to remove /transition from route history. // `useExitTo` returns undefined for routes other than /transition. - if (exitToParam) { + if (exitToParam && Navigation.getActiveRoute().includes(ROUTES.TRANSITION_BETWEEN_APPS)) { Log.info('[HybridApp] Removing /transition route from history', true); Navigation.goBack(); } - Log.info('[HybridApp] Navigating to `exitTo` route', true, {exitTo}); - Navigation.navigate(Navigation.parseHybridAppUrl(exitTo)); + if (exitTo !== ROUTES.HOME) { + Log.info('[HybridApp] Navigating to `exitTo` route', true, {exitTo}); + Navigation.navigate(Navigation.parseHybridAppUrl(exitTo)); + } setExitTo(undefined); setTimeout(() => { diff --git a/src/libs/Navigation/AppNavigator/index.native.tsx b/src/libs/Navigation/AppNavigator/index.native.tsx index e848979e6993..0da93237d617 100644 --- a/src/libs/Navigation/AppNavigator/index.native.tsx +++ b/src/libs/Navigation/AppNavigator/index.native.tsx @@ -2,6 +2,7 @@ import React, {memo, useContext, useEffect} from 'react'; import {NativeModules} from 'react-native'; import {InitialURLContext} from '@components/InitialURLContextProvider'; import Navigation from '@libs/Navigation/Navigation'; +import ROUTES from '@src/ROUTES'; import type ReactComponentModule from '@src/types/utils/ReactComponentModule'; type AppNavigatorProps = { @@ -13,7 +14,7 @@ function AppNavigator({authenticated}: AppNavigatorProps) { const initUrl = useContext(InitialURLContext); useEffect(() => { - if (!NativeModules.HybridAppModule || !initUrl) { + if (!NativeModules.HybridAppModule || !initUrl || !initUrl.includes(ROUTES.TRANSITION_BETWEEN_APPS)) { return; } diff --git a/src/libs/Navigation/AppNavigator/index.tsx b/src/libs/Navigation/AppNavigator/index.tsx index 787ede6c14f2..e0f1dae94f62 100644 --- a/src/libs/Navigation/AppNavigator/index.tsx +++ b/src/libs/Navigation/AppNavigator/index.tsx @@ -2,6 +2,7 @@ import React, {lazy, memo, Suspense, useContext, useEffect} from 'react'; import {NativeModules} from 'react-native'; import {InitialURLContext} from '@components/InitialURLContextProvider'; import Navigation from '@libs/Navigation/Navigation'; +import ROUTES from '@src/ROUTES'; import lazyRetry from '@src/utils/lazyRetry'; const AuthScreens = lazy(() => lazyRetry(() => import('./AuthScreens'))); @@ -16,7 +17,7 @@ function AppNavigator({authenticated}: AppNavigatorProps) { const initUrl = useContext(InitialURLContext); useEffect(() => { - if (!NativeModules.HybridAppModule || !initUrl) { + if (!NativeModules.HybridAppModule || !initUrl || !initUrl.includes(ROUTES.TRANSITION_BETWEEN_APPS)) { return; } diff --git a/src/libs/Notification/PushNotification/subscribePushNotification/index.ts b/src/libs/Notification/PushNotification/subscribePushNotification/index.ts index d60e66f8d535..c1a1442b1e53 100644 --- a/src/libs/Notification/PushNotification/subscribePushNotification/index.ts +++ b/src/libs/Notification/PushNotification/subscribePushNotification/index.ts @@ -1,3 +1,4 @@ +import {NativeModules} from 'react-native'; import Onyx from 'react-native-onyx'; import applyOnyxUpdatesReliably from '@libs/actions/applyOnyxUpdatesReliably'; import * as ActiveClientManager from '@libs/ActiveClientManager'; @@ -85,6 +86,10 @@ function navigateToReport({reportID, reportActionID}: ReportActionPushNotificati // The attachment modal remains open when navigating to the report so we need to close it Modal.close(() => { try { + // Get rid of the transition screen, if it is on the top of the stack + if (NativeModules.HybridAppModule && Navigation.getActiveRoute().includes(ROUTES.TRANSITION_BETWEEN_APPS)) { + Navigation.goBack(); + } // If a chat is visible other than the one we are trying to navigate to, then we need to navigate back if (Navigation.getActiveRoute().slice(1, 2) === ROUTES.REPORT && !Navigation.isActiveRoute(`r/${reportID}`)) { Navigation.goBack();