diff --git a/src/libs/Navigation/AppNavigator/getPartialStateDiff.ts b/src/libs/Navigation/AppNavigator/getPartialStateDiff.ts index b0825b4b2991..5732cb93f19c 100644 --- a/src/libs/Navigation/AppNavigator/getPartialStateDiff.ts +++ b/src/libs/Navigation/AppNavigator/getPartialStateDiff.ts @@ -1,5 +1,6 @@ import getTopmostBottomTabRoute from '@libs/Navigation/getTopmostBottomTabRoute'; import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRoute'; +import getTopmostFullScreenRoute from '@libs/Navigation/getTopmostFullScreenRoute'; import type {Metainfo} from '@libs/Navigation/linkingConfig/getAdaptedStateFromPath'; import type {NavigationPartialRoute, RootStackParamList, State} from '@libs/Navigation/types'; import NAVIGATORS from '@src/NAVIGATORS'; @@ -73,10 +74,19 @@ function getPartialStateDiff(state: State, templateState: St // This one is heuristic and may need to be improved if we will be able to navigate from modal screen with full screen in background to another modal screen with full screen in background. // For now this simple check is enough. if (metainfo.isFullScreenNavigatorMandatory) { - const stateTopmostFullScreen = state.routes.filter((route) => route.name === NAVIGATORS.FULL_SCREEN_NAVIGATOR).at(-1); - const templateStateTopmostFullScreen = templateState.routes.filter((route) => route.name === NAVIGATORS.FULL_SCREEN_NAVIGATOR).at(-1) as NavigationPartialRoute; - if (!stateTopmostFullScreen && templateStateTopmostFullScreen) { - diff[NAVIGATORS.FULL_SCREEN_NAVIGATOR] = templateStateTopmostFullScreen; + const stateTopmostFullScreen = getTopmostFullScreenRoute(state); + const templateStateTopmostFullScreen = getTopmostFullScreenRoute(templateState); + const fullScreenDiff = templateState.routes.filter((route) => route.name === NAVIGATORS.FULL_SCREEN_NAVIGATOR).at(-1) as NavigationPartialRoute; + + if ( + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + (!stateTopmostFullScreen && templateStateTopmostFullScreen) || + (stateTopmostFullScreen && + templateStateTopmostFullScreen && + stateTopmostFullScreen.name !== templateStateTopmostFullScreen.name && + !shallowCompare(stateTopmostFullScreen.params, templateStateTopmostFullScreen.params)) + ) { + diff[NAVIGATORS.FULL_SCREEN_NAVIGATOR] = fullScreenDiff; } } diff --git a/src/libs/Navigation/getTopmostFullScreenRoute.ts b/src/libs/Navigation/getTopmostFullScreenRoute.ts new file mode 100644 index 000000000000..25c74ea0ce6b --- /dev/null +++ b/src/libs/Navigation/getTopmostFullScreenRoute.ts @@ -0,0 +1,30 @@ +import NAVIGATORS from '@src/NAVIGATORS'; +import type {FullScreenName, NavigationPartialRoute, RootStackParamList, State} from './types'; + +// Get the name of topmost fullscreen route in the navigation stack. +function getTopmostFullScreenRoute(state: State): NavigationPartialRoute | undefined { + if (!state) { + return; + } + + const topmostFullScreenRoute = state.routes.filter((route) => route.name === NAVIGATORS.FULL_SCREEN_NAVIGATOR).at(-1); + + if (!topmostFullScreenRoute) { + return; + } + + if (!!topmostFullScreenRoute.params && 'screen' in topmostFullScreenRoute.params) { + return {name: topmostFullScreenRoute.params.screen as FullScreenName, params: topmostFullScreenRoute.params.params}; + } + + if (!topmostFullScreenRoute.state) { + return; + } + + // There will be at least one route in the fullscreen navigator. + const {name, params} = topmostFullScreenRoute.state.routes.at(-1) as NavigationPartialRoute; + + return {name, params}; +} + +export default getTopmostFullScreenRoute;