From 210003ca2465a5205bc20c673ab953f4618400df Mon Sep 17 00:00:00 2001 From: staszekscp Date: Tue, 23 Jul 2024 13:22:34 +0200 Subject: [PATCH 1/4] fix transitions from notifications on android hybrid app --- src/components/HybridAppMiddleware/index.tsx | 19 +++++++++++++++++-- .../subscribePushNotification/index.ts | 5 +++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/components/HybridAppMiddleware/index.tsx b/src/components/HybridAppMiddleware/index.tsx index 5a8d8d6dfebe..64cbce5197e1 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'; @@ -15,6 +15,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {HybridAppRoute, Route} from '@src/ROUTES'; import type {TryNewDot} from '@src/types/onyx'; +import ROUTES from '@src/ROUTES'; type HybridAppMiddlewareProps = { authenticated: boolean; @@ -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,7 +108,7 @@ 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(); } diff --git a/src/libs/Notification/PushNotification/subscribePushNotification/index.ts b/src/libs/Notification/PushNotification/subscribePushNotification/index.ts index d60e66f8d535..c9fbab54d5ab 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(); From aab2091af6f832c8604bdf374982e17e9b5cbee0 Mon Sep 17 00:00:00 2001 From: staszekscp Date: Wed, 24 Jul 2024 08:34:39 +0200 Subject: [PATCH 2/4] fix unreliable navigation --- src/components/HybridAppMiddleware/index.tsx | 6 ++++-- src/libs/Navigation/AppNavigator/index.native.tsx | 3 ++- src/libs/Navigation/AppNavigator/index.tsx | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/HybridAppMiddleware/index.tsx b/src/components/HybridAppMiddleware/index.tsx index 64cbce5197e1..26d88ca14619 100644 --- a/src/components/HybridAppMiddleware/index.tsx +++ b/src/components/HybridAppMiddleware/index.tsx @@ -113,8 +113,10 @@ function HybridAppMiddleware({children, authenticated}: HybridAppMiddlewareProps 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..e50b635eaf98 100644 --- a/src/libs/Navigation/AppNavigator/index.native.tsx +++ b/src/libs/Navigation/AppNavigator/index.native.tsx @@ -3,6 +3,7 @@ import {NativeModules} from 'react-native'; import {InitialURLContext} from '@components/InitialURLContextProvider'; import Navigation from '@libs/Navigation/Navigation'; import type ReactComponentModule from '@src/types/utils/ReactComponentModule'; +import ROUTES from '@src/ROUTES'; type AppNavigatorProps = { /** If we have an authToken this is true */ @@ -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 f8b14781a5ec..ab6c3f4ac902 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'; const AuthScreens = lazy(() => import('./AuthScreens')); const PublicScreens = lazy(() => import('./PublicScreens')); @@ -15,7 +16,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; } From 8675ceec0ba60b69d705cb3b2fac9ea36d3fe90d Mon Sep 17 00:00:00 2001 From: staszekscp Date: Wed, 24 Jul 2024 09:23:02 +0200 Subject: [PATCH 3/4] prettier --- src/components/HybridAppMiddleware/index.tsx | 2 +- src/libs/Navigation/AppNavigator/index.native.tsx | 2 +- .../PushNotification/subscribePushNotification/index.ts | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/HybridAppMiddleware/index.tsx b/src/components/HybridAppMiddleware/index.tsx index 26d88ca14619..bb5d7803e52e 100644 --- a/src/components/HybridAppMiddleware/index.tsx +++ b/src/components/HybridAppMiddleware/index.tsx @@ -14,8 +14,8 @@ import * as Welcome from '@userActions/Welcome'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {HybridAppRoute, Route} from '@src/ROUTES'; -import type {TryNewDot} from '@src/types/onyx'; import ROUTES from '@src/ROUTES'; +import type {TryNewDot} from '@src/types/onyx'; type HybridAppMiddlewareProps = { authenticated: boolean; diff --git a/src/libs/Navigation/AppNavigator/index.native.tsx b/src/libs/Navigation/AppNavigator/index.native.tsx index e50b635eaf98..0da93237d617 100644 --- a/src/libs/Navigation/AppNavigator/index.native.tsx +++ b/src/libs/Navigation/AppNavigator/index.native.tsx @@ -2,8 +2,8 @@ import React, {memo, useContext, useEffect} from 'react'; import {NativeModules} from 'react-native'; import {InitialURLContext} from '@components/InitialURLContextProvider'; import Navigation from '@libs/Navigation/Navigation'; -import type ReactComponentModule from '@src/types/utils/ReactComponentModule'; import ROUTES from '@src/ROUTES'; +import type ReactComponentModule from '@src/types/utils/ReactComponentModule'; type AppNavigatorProps = { /** If we have an authToken this is true */ diff --git a/src/libs/Notification/PushNotification/subscribePushNotification/index.ts b/src/libs/Notification/PushNotification/subscribePushNotification/index.ts index c9fbab54d5ab..c1a1442b1e53 100644 --- a/src/libs/Notification/PushNotification/subscribePushNotification/index.ts +++ b/src/libs/Notification/PushNotification/subscribePushNotification/index.ts @@ -1,4 +1,4 @@ -import { NativeModules } from 'react-native'; +import {NativeModules} from 'react-native'; import Onyx from 'react-native-onyx'; import applyOnyxUpdatesReliably from '@libs/actions/applyOnyxUpdatesReliably'; import * as ActiveClientManager from '@libs/ActiveClientManager'; @@ -87,8 +87,8 @@ function navigateToReport({reportID, reportActionID}: ReportActionPushNotificati 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 (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}`)) { From c88769d2ed69905a79df609e9990506ce779df8a Mon Sep 17 00:00:00 2001 From: staszekscp Date: Fri, 26 Jul 2024 08:15:49 +0200 Subject: [PATCH 4/4] add timeout to ios --- .../HybridAppMiddleware/index.ios.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) 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.