1- import type { NavigationState , PartialState , Route } from '@react-navigation/native' ;
2- import { findFocusedRoute , getStateFromPath } from '@react-navigation/native' ;
1+ import type { NavigationState , PartialState , getStateFromPath as RNGetStateFromPath , Route } from '@react-navigation/native' ;
2+ import { findFocusedRoute } from '@react-navigation/native' ;
33import pick from 'lodash/pick' ;
44import type { OnyxCollection } from 'react-native-onyx' ;
55import Onyx from 'react-native-onyx' ;
66import getInitialSplitNavigatorState from '@libs/Navigation/AppNavigator/createSplitNavigator/getInitialSplitNavigatorState' ;
7- import { config } from '@libs/Navigation/linkingConfig/config' ;
87import { RHP_TO_DOMAIN , RHP_TO_SEARCH , RHP_TO_SETTINGS , RHP_TO_SIDEBAR , RHP_TO_WORKSPACE , RHP_TO_WORKSPACES_LIST } from '@libs/Navigation/linkingConfig/RELATIONS' ;
98import type { NavigationPartialRoute , RootNavigatorParamList } from '@libs/Navigation/types' ;
109import CONST from '@src/CONST' ;
1110import NAVIGATORS from '@src/NAVIGATORS' ;
1211import ONYXKEYS from '@src/ONYXKEYS' ;
1312import ROUTES from '@src/ROUTES' ;
13+ import type { Route as RoutePath } from '@src/ROUTES' ;
1414import SCREENS from '@src/SCREENS' ;
1515import type { Report } from '@src/types/onyx' ;
16+ import getLastSuffixFromPath from './getLastSuffixFromPath' ;
1617import getMatchingNewRoute from './getMatchingNewRoute' ;
1718import getParamsFromRoute from './getParamsFromRoute' ;
19+ import getStateFromPath from './getStateFromPath' ;
20+ import isDynamicRouteSuffix from './isDynamicRouteSuffix' ;
1821import { isFullScreenName } from './isNavigatorName' ;
1922import normalizePath from './normalizePath' ;
2023import replacePathInNestedState from './replacePathInNestedState' ;
@@ -30,7 +33,7 @@ Onyx.connect({
3033
3134type GetAdaptedStateReturnType = ReturnType < typeof getStateFromPath > ;
3235
33- type GetAdaptedStateFromPath = ( ...args : [ ...Parameters < typeof getStateFromPath > , shouldReplacePathInNestedState ?: boolean ] ) => GetAdaptedStateReturnType ;
36+ type GetAdaptedStateFromPath = ( ...args : [ ...Parameters < typeof RNGetStateFromPath > , shouldReplacePathInNestedState ?: boolean ] ) => GetAdaptedStateReturnType ;
3437
3538// The function getPathFromState that we are using in some places isn't working correctly without defined index.
3639const getRoutesWithIndex = ( routes : NavigationPartialRoute [ ] ) : PartialState < NavigationState > => ( { routes, index : routes . length - 1 } ) ;
@@ -63,7 +66,7 @@ function getSearchScreenNameForRoute(route: NavigationPartialRoute): string {
6366function getMatchingFullScreenRoute ( route : NavigationPartialRoute ) {
6467 // Check for backTo param. One screen with different backTo value may need different screens visible under the overlay.
6568 if ( isRouteWithBackToParam ( route ) ) {
66- const stateForBackTo = getStateFromPath ( route . params . backTo , config ) ;
69+ const stateForBackTo = getStateFromPath ( route . params . backTo as RoutePath ) ;
6770
6871 // This may happen if the backTo url is invalid.
6972 const lastRoute = stateForBackTo ?. routes . at ( - 1 ) ;
@@ -86,6 +89,37 @@ function getMatchingFullScreenRoute(route: NavigationPartialRoute) {
8689 // If not, get the matching full screen route for the back to state.
8790 return getMatchingFullScreenRoute ( focusedStateForBackToRoute ) ;
8891 }
92+
93+ // Handle dynamic routes: find the appropriate full screen route
94+ const dynamicRouteSuffix = getLastSuffixFromPath ( route . path ) ;
95+ if ( isDynamicRouteSuffix ( dynamicRouteSuffix ) ) {
96+ // Remove dynamic suffix to get the base path
97+ const pathWithoutDynamicSuffix = route . path ?. replace ( `/${ dynamicRouteSuffix } ` , '' ) ;
98+
99+ // Get navigation state for the base path without dynamic suffix
100+ const stateUnderDynamicRoute = getStateFromPath ( pathWithoutDynamicSuffix as RoutePath ) ;
101+ const lastRoute = stateUnderDynamicRoute ?. routes . at ( - 1 ) ;
102+
103+ if ( ! stateUnderDynamicRoute || ! lastRoute || lastRoute . name === SCREENS . NOT_FOUND ) {
104+ return undefined ;
105+ }
106+
107+ const isLastRouteFullScreen = isFullScreenName ( lastRoute . name ) ;
108+
109+ if ( isLastRouteFullScreen ) {
110+ return lastRoute ;
111+ }
112+
113+ const focusedStateForDynamicRoute = findFocusedRoute ( stateUnderDynamicRoute ) ;
114+
115+ if ( ! focusedStateForDynamicRoute ) {
116+ return undefined ;
117+ }
118+
119+ // Recursively find the matching full screen route for the focused dynamic route
120+ return getMatchingFullScreenRoute ( focusedStateForDynamicRoute ) ;
121+ }
122+
89123 const routeNameForLookup = getSearchScreenNameForRoute ( route ) ;
90124 if ( RHP_TO_SEARCH [ routeNameForLookup ] ) {
91125 const paramsFromRoute = getParamsFromRoute ( RHP_TO_SEARCH [ routeNameForLookup ] ) ;
@@ -277,7 +311,7 @@ const getAdaptedStateFromPath: GetAdaptedStateFromPath = (path, options, shouldR
277311 normalizedPath = '/' ;
278312 }
279313
280- const state = getStateFromPath ( normalizedPath , options ) as PartialState < NavigationState < RootNavigatorParamList > > ;
314+ const state = getStateFromPath ( normalizedPath as RoutePath ) as PartialState < NavigationState < RootNavigatorParamList > > ;
281315 if ( shouldReplacePathInNestedState ) {
282316 replacePathInNestedState ( state , normalizedPath ) ;
283317 }
0 commit comments