From 49210d131df8e512ae9ebca1638b48e5686fcba5 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Mon, 30 Sep 2024 15:11:17 +0200 Subject: [PATCH] Handle navigating back to sidebar screen --- .../SplitStackRouter.ts | 2 +- src/libs/Navigation/Navigation.ts | 87 +++++++------------ src/libs/Navigation/types.ts | 3 + 3 files changed, 35 insertions(+), 57 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/createSplitStackNavigator/SplitStackRouter.ts b/src/libs/Navigation/AppNavigator/createSplitStackNavigator/SplitStackRouter.ts index 4811b8451c80..b42c91721444 100644 --- a/src/libs/Navigation/AppNavigator/createSplitStackNavigator/SplitStackRouter.ts +++ b/src/libs/Navigation/AppNavigator/createSplitStackNavigator/SplitStackRouter.ts @@ -20,7 +20,7 @@ function adaptStateIfNecessary({state, options: {sidebarScreen, defaultCentralSc const workspaceCentralPane = state.routes.at(-1); // There should always be sidebarScreen screen in the state to make sure go back works properly if we deeplinkg to a subpage of settings. - if (!isAtLeastOneInState(state, sidebarScreen)) { + if (!isAtLeastOneInState(state, sidebarScreen) && !isNarrowLayout) { // @ts-expect-error Updating read only property // noinspection JSConstantReassignment state.stale = true; // eslint-disable-line diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index aa62b5a2b03a..5d3db800c545 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -27,7 +27,21 @@ import navigationRef from './navigationRef'; import linkTo from './newLinkTo'; import getMinimalAction from './newLinkTo/getMinimalAction'; import setNavigationActionToMicrotaskQueue from './setNavigationActionToMicrotaskQueue'; -import type {NavigationStateRoute, RootStackParamList, StackNavigationAction, State, StateOrRoute} from './types'; +import type {NavigationStateRoute, RootStackParamList, SplitNavigatorLHNScreen, SplitNavigatorName, SplitNavigatorParamListType, StackNavigationAction, State, StateOrRoute} from './types'; + +const SPLIT_NAVIGATOR_TO_SIDEBAR_MAP: Record = { + [NAVIGATORS.REPORTS_SPLIT_NAVIGATOR]: SCREENS.HOME, + [NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR]: SCREENS.SETTINGS.ROOT, + [NAVIGATORS.WORKSPACE_SPLIT_NAVIGATOR]: SCREENS.WORKSPACE.INITIAL, +}; + +function getSidebarScreenParams(splitNavigatorRoute: NavigationStateRoute) { + if (splitNavigatorRoute.name === NAVIGATORS.WORKSPACE_SPLIT_NAVIGATOR) { + return splitNavigatorRoute.state?.routes?.at(0)?.params; + } + + return undefined; +} let resolveNavigationIsReadyPromise: () => void; const navigationIsReadyPromise = new Promise((resolve) => { @@ -273,66 +287,27 @@ function goBack(fallbackRoute?: Route, shouldEnforceFallback = false, shouldPopT return; } + const rootState = navigationRef.current?.getRootState(); + const lastRoute = rootState?.routes.at(-1); + + if (lastRoute?.name.endsWith('SplitNavigator') && lastRoute?.state?.routes?.length === 1) { + const name = SPLIT_NAVIGATOR_TO_SIDEBAR_MAP[lastRoute?.name as SplitNavigatorName]; + const params = getSidebarScreenParams(lastRoute); + navigationRef.dispatch({ + type: 'REPLACE', + payload: { + name, + params, + }, + }); + return; + } + if (!navigationRef.current?.canGoBack()) { Log.hmmm('[Navigation] Unable to go back'); return; } - // const isFirstRouteInNavigator = !getActiveRouteIndex(navigationRef.current.getState()); - // if (isFirstRouteInNavigator) { - // const rootState = navigationRef.getRootState(); - // const lastRoute = rootState.routes.at(-1); - // // If the user comes from a different flow (there is more than one route in ModalNavigator) we should go back to the previous flow on UP button press instead of using the fallbackRoute. - // if ((lastRoute?.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR || lastRoute?.name === NAVIGATORS.LEFT_MODAL_NAVIGATOR) && (lastRoute.state?.index ?? 0) > 0) { - // navigationRef.current.goBack(); - // return; - // } - // } - - // if (shouldEnforceFallback || (isFirstRouteInNavigator && fallbackRoute)) { - // navigate(fallbackRoute, 'REPLACE'); - // return; - // } - - // const isCentralPaneFocused = isCentralPaneName(findFocusedRoute(navigationRef.current.getState())?.name); - // const distanceFromPathInRootNavigator = getDistanceFromPathInRootNavigator(navigationRef.getRootState(), fallbackRoute ?? ''); - - // if (isCentralPaneFocused && fallbackRoute) { - // // Allow CentralPane to use UP with fallback route if the path is not found in root navigator. - // if (distanceFromPathInRootNavigator === -1) { - // navigate(fallbackRoute, 'REPLACE'); - // return; - // } - - // // Add possibility to go back more than one screen in root navigator if that screen is on the stack. - // if (distanceFromPathInRootNavigator > 0) { - // navigationRef.current.dispatch(StackActions.pop(distanceFromPathInRootNavigator)); - // return; - // } - // } - - // // If the central pane is focused, it's possible that we navigated from other central pane with different matching bottom tab. - // if (isCentralPaneFocused) { - // const rootState = navigationRef.getRootState(); - // const stateAfterPop = {routes: rootState.routes.slice(0, -1)} as State; - // const topmostCentralPaneRouteAfterPop = getTopmostCentralPaneRoute(stateAfterPop); - - // const topmostBottomTabRoute = getTopmostBottomTabRoute(rootState as State); - // const matchingBottomTabRoute = getMatchingBottomTabRouteForState(stateAfterPop); - - // // If the central pane is defined after the pop action, we need to check if it's synced with the bottom tab screen. - // // If not, we need to pop to the bottom tab screen/screens to sync it with the new central pane. - // if (topmostCentralPaneRouteAfterPop && topmostBottomTabRoute?.name !== matchingBottomTabRoute.name) { - // const bottomTabNavigator = rootState.routes.find((item: NavigationStateRoute) => item.name === NAVIGATORS.BOTTOM_TAB_NAVIGATOR)?.state; - - // if (bottomTabNavigator && bottomTabNavigator.index) { - // const matchingIndex = bottomTabNavigator.routes.findLastIndex((item) => item.name === matchingBottomTabRoute.name); - // const indexToPop = matchingIndex !== -1 ? bottomTabNavigator.index - matchingIndex : undefined; - // navigationRef.current.dispatch({...StackActions.pop(indexToPop), target: bottomTabNavigator?.key}); - // } - // } - // } - navigationRef.current.goBack(); } diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 95befe5ded74..20137dd2e2cd 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -60,6 +60,8 @@ type SplitNavigatorParamListType = { [NAVIGATORS.WORKSPACE_SPLIT_NAVIGATOR]: WorkspaceSplitNavigatorParamList; }; +type SplitNavigatorName = keyof SplitNavigatorParamListType; + type SplitNavigatorByLHN = (typeof LHN_TO_SPLIT_NAVIGATOR_NAME)[T]; type CentralPaneScreensParamList = { @@ -1645,4 +1647,5 @@ export type { SplitNavigatorLHNScreen, SplitNavigatorParamListType, SplitNavigatorByLHN, + SplitNavigatorName, };