From 773b3aa95e9ea3a91be5210a3599d509103797fc Mon Sep 17 00:00:00 2001
From: kubabutkiewicz <jakub.butkiewicz94@gmail.com>
Date: Thu, 2 Oct 2025 10:03:49 +0200
Subject: [PATCH 1/3] recreated a previous Pr and attempt to fix the issue with
 redirecting to inbox

---
 src/CONST/index.ts                            |  2 +-
 src/libs/Navigation/NavigationRoot.tsx        | 28 ++++++++++-------
 src/libs/actions/App.ts                       | 30 ++++++++++++++++++-
 .../shouldOpenLastVisitedPath/index.native.ts |  3 +-
 .../step/IOURequestStepScan/index.native.tsx  | 18 +++++++++--
 5 files changed, 64 insertions(+), 17 deletions(-)

diff --git a/src/CONST/index.ts b/src/CONST/index.ts
index b52f7bc9bb79..096dfee12ade 100755
--- a/src/CONST/index.ts
+++ b/src/CONST/index.ts
@@ -6801,7 +6801,7 @@ const CONST = {
         CASH_BACK: 'earnedCashback',
     },
 
-    EXCLUDE_FROM_LAST_VISITED_PATH: [SCREENS.NOT_FOUND, SCREENS.SAML_SIGN_IN, SCREENS.VALIDATE_LOGIN, SCREENS.MIGRATED_USER_WELCOME_MODAL.ROOT] as string[],
+    EXCLUDE_FROM_LAST_VISITED_PATH: [SCREENS.NOT_FOUND, SCREENS.SAML_SIGN_IN, SCREENS.VALIDATE_LOGIN, SCREENS.MIGRATED_USER_WELCOME_MODAL.ROOT, SCREENS.MONEY_REQUEST.STEP_SCAN] as string[],
 
     CANCELLATION_TYPE: {
         MANUAL: 'manual',
diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx
index dc5c3a2c385a..f25fb2d23695 100644
--- a/src/libs/Navigation/NavigationRoot.tsx
+++ b/src/libs/Navigation/NavigationRoot.tsx
@@ -131,6 +131,12 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady}: N
 
         const isTransitioning = path?.includes(ROUTES.TRANSITION_BETWEEN_APPS);
 
+        // If we have a transition URL, don't restore last visited path - let React Navigation handle it
+        // This prevents reusing deep links after logout regardless of authentication status
+        if (isTransitioning) {
+            return undefined;
+        }
+
         // If the user haven't completed the flow, we want to always redirect them to the onboarding flow.
         // We also make sure that the user is authenticated, isn't part of a group workspace, isn't in the transition flow & wasn't invited to NewDot.
         if (!CONFIG.IS_HYBRID_APP && !hasNonPersonalPolicy && !isOnboardingCompleted && !wasInvitedToNewDot && authenticated && !isTransitioning) {
@@ -146,20 +152,20 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady}: N
             );
         }
 
-        // If there is no lastVisitedPath, we can do early return. We won't modify the default behavior.
-        // The same applies to HybridApp, as we always define the route to which we want to transition.
-        if (!shouldOpenLastVisitedPath(lastVisitedPath) || CONFIG.IS_HYBRID_APP) {
-            return undefined;
-        }
+        if (shouldOpenLastVisitedPath(lastVisitedPath) && authenticated) {
+            // Only skip restoration if there's a specific deep link that's not the root
+            // This allows restoration when app is killed and reopened without a deep link
+            const isRootPath = !path || path === '' || path === '/';
+            const isSpecificDeepLink = path && !isRootPath;
 
-        // If the user opens the root of app "/" it will be parsed to empty string "".
-        // If the path is defined and different that empty string we don't want to modify the default behavior.
-        if (path) {
-            return;
+            if (!isSpecificDeepLink) {
+                Log.info('Restoring last visited path on app startup', false, {lastVisitedPath, initialUrl, path});
+                return getAdaptedStateFromPath(lastVisitedPath, linkingConfig.config);
+            }
         }
 
-        // Otherwise we want to redirect the user to the last visited path.
-        return getAdaptedStateFromPath(lastVisitedPath, linkingConfig.config);
+        // Default behavior - let React Navigation handle the initial state
+        return undefined;
 
         // The initialState value is relevant only on the first render.
         // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
diff --git a/src/libs/actions/App.ts b/src/libs/actions/App.ts
index 37ebc4ffe2dd..f108929ec5e7 100644
--- a/src/libs/actions/App.ts
+++ b/src/libs/actions/App.ts
@@ -1,4 +1,5 @@
 // Issue - https://github.com/Expensify/App/issues/26719
+import {getPathFromState} from '@react-navigation/native';
 import {Str} from 'expensify-common';
 import type {AppStateStatus} from 'react-native';
 import {AppState} from 'react-native';
@@ -11,7 +12,8 @@ import * as Browser from '@libs/Browser';
 import DateUtils from '@libs/DateUtils';
 import Log from '@libs/Log';
 import getCurrentUrl from '@libs/Navigation/currentUrl';
-import Navigation from '@libs/Navigation/Navigation';
+import {linkingConfig} from '@libs/Navigation/linkingConfig';
+import Navigation, {navigationRef} from '@libs/Navigation/Navigation';
 import Performance from '@libs/Performance';
 import {isPublicRoom, isValidReport} from '@libs/ReportUtils';
 import {isLoggingInAsNewUser as isLoggingInAsNewUserSessionUtils} from '@libs/SessionUtils';
@@ -207,10 +209,36 @@ function setAppLoading(isLoading: boolean) {
     Onyx.set(ONYXKEYS.IS_LOADING_APP, isLoading);
 }
 
+/**
+ * Saves the current navigation path to lastVisitedPath before app goes to background
+ */
+function saveCurrentPathBeforeBackground() {
+    try {
+        if (!navigationRef.isReady()) {
+            return;
+        }
+
+        const currentState = navigationRef.getRootState();
+        if (!currentState) {
+            return;
+        }
+
+        const currentPath = getPathFromState(currentState, linkingConfig.config);
+
+        if (currentPath) {
+            Log.info('Saving current path before background', false, {currentPath});
+            updateLastVisitedPath(currentPath);
+        }
+    } catch (error) {
+        Log.warn('Failed to save current path before background', {error});
+    }
+}
+
 let appState: AppStateStatus;
 AppState.addEventListener('change', (nextAppState) => {
     if (nextAppState.match(/inactive|background/) && appState === 'active') {
         Log.info('Flushing logs as app is going inactive', true, {}, true);
+        saveCurrentPathBeforeBackground();
     }
     appState = nextAppState;
 });
diff --git a/src/libs/shouldOpenLastVisitedPath/index.native.ts b/src/libs/shouldOpenLastVisitedPath/index.native.ts
index c63444aaeeb7..e73603714264 100644
--- a/src/libs/shouldOpenLastVisitedPath/index.native.ts
+++ b/src/libs/shouldOpenLastVisitedPath/index.native.ts
@@ -1,6 +1,5 @@
-import {getReportIDFromLink} from '@libs/ReportUtils';
 import type {Route} from '@src/ROUTES';
 
 export default function shouldOpenLastVisitedPath(lastVisitedPath: Route) {
-    return !!lastVisitedPath && !!getReportIDFromLink(lastVisitedPath);
+    return !!lastVisitedPath;
 }
diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx
index 4300c3738958..eff8d94f86a9 100644
--- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx
+++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx
@@ -48,6 +48,7 @@ import HapticFeedback from '@libs/HapticFeedback';
 import {navigateToParticipantPage} from '@libs/IOUUtils';
 import Log from '@libs/Log';
 import Navigation from '@libs/Navigation/Navigation';
+import navigationRef from '@libs/Navigation/navigationRef';
 import {getManagerMcTestParticipant, getParticipantsOption, getReportOption} from '@libs/OptionsListUtils';
 import {isPaidGroupPolicy} from '@libs/PolicyUtils';
 import {findSelfDMReportID, generateReportID, getPolicyExpenseChat, isArchivedReport, isPolicyExpenseChat} from '@libs/ReportUtils';
@@ -72,6 +73,7 @@ import type {GpsPoint} from '@userActions/IOU';
 import {buildOptimisticTransactionAndCreateDraft, removeDraftTransactions, removeTransactionReceipt} from '@userActions/TransactionEdit';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
+import type {Route} from '@src/ROUTES';
 import ROUTES from '@src/ROUTES';
 import type {Policy} from '@src/types/onyx';
 import type {Participant} from '@src/types/onyx/IOU';
@@ -527,10 +529,22 @@ function IOURequestStepScan({
 
     const updateScanAndNavigate = useCallback(
         (file: FileObject, source: string) => {
-            navigateBack();
+            // Fix for the issue where the navigation state is lost after returning from device settings https://github.com/Expensify/App/issues/65992
+            const navigationState = navigationRef.current?.getState();
+            const reportsSplitNavigator = navigationState?.routes?.find((route) => route.name === 'ReportsSplitNavigator');
+            const hasLostNavigationsState = reportsSplitNavigator && !reportsSplitNavigator.state;
+            if (hasLostNavigationsState) {
+                if (backTo) {
+                    Navigation.navigate(backTo as Route);
+                } else {
+                    Navigation.navigate(ROUTES.HOME);
+                }
+            } else {
+                navigateBack();
+            }
             replaceReceipt({transactionID: initialTransactionID, file: file as File, source});
         },
-        [initialTransactionID],
+        [initialTransactionID, backTo],
     );
 
     /**

From 2d6c9e28f51e2e450c431ae1671f6bb8ac658982 Mon Sep 17 00:00:00 2001
From: kubabutkiewicz <jakub.butkiewicz94@gmail.com>
Date: Thu, 9 Oct 2025 17:16:14 +0200
Subject: [PATCH 2/3] fix: update navigation state handling in
 IOURequestStepScan to use findLast for ReportsSplitNavigator

---
 src/pages/iou/request/step/IOURequestStepScan/index.native.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx
index 16dc87afe2df..078e5a2660b5 100644
--- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx
+++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx
@@ -532,7 +532,7 @@ function IOURequestStepScan({
         (file: FileObject, source: string) => {
             // Fix for the issue where the navigation state is lost after returning from device settings https://github.com/Expensify/App/issues/65992
             const navigationState = navigationRef.current?.getState();
-            const reportsSplitNavigator = navigationState?.routes?.find((route) => route.name === 'ReportsSplitNavigator');
+            const reportsSplitNavigator = navigationState?.routes?.findLast((route) => route.name === 'ReportsSplitNavigator');
             const hasLostNavigationsState = reportsSplitNavigator && !reportsSplitNavigator.state;
             if (hasLostNavigationsState) {
                 if (backTo) {

From 98ce64561416a1c664f355bd677aef9dfb9db9cf Mon Sep 17 00:00:00 2001
From: kubabutkiewicz <jakub.butkiewicz94@gmail.com>
Date: Tue, 14 Oct 2025 12:36:36 +0200
Subject: [PATCH 3/3] remove native file for shouldOpenLastVisitedPath as its
 the same as index now

---
 src/libs/shouldOpenLastVisitedPath/index.native.ts | 5 -----
 1 file changed, 5 deletions(-)
 delete mode 100644 src/libs/shouldOpenLastVisitedPath/index.native.ts

diff --git a/src/libs/shouldOpenLastVisitedPath/index.native.ts b/src/libs/shouldOpenLastVisitedPath/index.native.ts
deleted file mode 100644
index e73603714264..000000000000
--- a/src/libs/shouldOpenLastVisitedPath/index.native.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import type {Route} from '@src/ROUTES';
-
-export default function shouldOpenLastVisitedPath(lastVisitedPath: Route) {
-    return !!lastVisitedPath;
-}
