From 88cc5f949ab89ebea323c402e369e0059105e62c Mon Sep 17 00:00:00 2001 From: Adam Grzybowski Date: Tue, 19 Dec 2023 19:20:13 +0100 Subject: [PATCH] fix crash after loggin in --- .../BottomTabBar.tsx | 7 ++++- .../CustomRouter.ts | 28 +++++++++++-------- .../getMatchingCentralPaneRouteForState.ts | 6 +++- .../Navigation/getTopmostBottomTabRoute.ts | 5 ++-- src/libs/Navigation/linkTo.ts | 6 ++-- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx index e8e6a8a5c4d5..b7e4a7cfd613 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx @@ -19,7 +19,12 @@ function BottomTabBar() { const styles = useThemeStyles(); // Parent navigator of the bottom tab bar is the root navigator. - const currentTabName = useNavigationState((state) => getTopmostBottomTabRoute(state).name); + const currentTabName = useNavigationState((state) => { + const topmostBottomTabRoute = getTopmostBottomTabRoute(state); + if (topmostBottomTabRoute) { + return topmostBottomTabRoute.name; + } + }); return ( diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts index 21f64835ccfc..a00489fbe8be 100644 --- a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomRouter.ts @@ -19,7 +19,9 @@ const isAtLeastOneInState = (state: State, screenName: string): boolean => !!sta * @param state - react-navigation state */ const addCentralPaneNavigatorRoute = (state: State) => { - const matchingCentralPaneRoute = getMatchingCentralPaneRouteForState(state); + // We only add the route if the bottom tab state is defined therefore matchingCentralPaneRoute will be defined. + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const matchingCentralPaneRoute = getMatchingCentralPaneRouteForState(state)!; const bottomTabRoute = state.routes.filter((route) => route.name === NAVIGATORS.BOTTOM_TAB_NAVIGATOR); const centralPaneRoutes = state.routes.filter((route) => route.name === NAVIGATORS.CENTRAL_PANE_NAVIGATOR); @@ -105,19 +107,23 @@ function CustomRouter(options: ResponsiveStackNavigatorRouterOptions) { return { ...stackRouter, getRehydratedState(partialState: StackNavigationState, {routeNames, routeParamList, routeGetIdList}: RouterConfigOptions): StackNavigationState { - const isSmallScreenWidth = getIsSmallScreenWidth(); // Make sure that there is at least one CentralPaneNavigator (ReportScreen by default) in the state if this is a wide layout - const topmostCentralPaneRoute = getTopmostCentralPaneRoute(partialState); const topmostBottomTabRoute = getTopmostBottomTabRoute(partialState); + const isSmallScreenWidth = getIsSmallScreenWidth(); - const isBottomTabMatchingCentralPane = topmostCentralPaneRoute && TAB_TO_CENTRAL_PANE_MAPPING[topmostBottomTabRoute.name].includes(topmostCentralPaneRoute.name); - - if (!isSmallScreenWidth && !isBottomTabMatchingCentralPane) { - // If we added a route we need to make sure that the state.stale is true to generate new key for this route - // @ts-expect-error Updating read only property - // noinspection JSConstantReassignment - partialState.stale = true; // eslint-disable-line - addCentralPaneNavigatorRoute(partialState); + // If we log in there is a few rehydrations where the state for the bottomTab doesn't exist yet. + // isSmallScreen is checked here to avoid calling check functions for optimazation purposes. + if (topmostBottomTabRoute && !isSmallScreenWidth) { + const topmostCentralPaneRoute = getTopmostCentralPaneRoute(partialState); + const isBottomTabMatchingCentralPane = topmostCentralPaneRoute && TAB_TO_CENTRAL_PANE_MAPPING[topmostBottomTabRoute.name].includes(topmostCentralPaneRoute.name); + + if (!isSmallScreenWidth && !isBottomTabMatchingCentralPane) { + // If we added a route we need to make sure that the state.stale is true to generate new key for this route + // @ts-expect-error Updating read only property + // noinspection JSConstantReassignment + partialState.stale = true; // eslint-disable-line + addCentralPaneNavigatorRoute(partialState); + } } handleSettingsOpened(partialState); const state = stackRouter.getRehydratedState(partialState, {routeNames, routeParamList, routeGetIdList}); diff --git a/src/libs/Navigation/getMatchingCentralPaneRouteForState.ts b/src/libs/Navigation/getMatchingCentralPaneRouteForState.ts index f00107308b2d..ab04bdb3bff6 100644 --- a/src/libs/Navigation/getMatchingCentralPaneRouteForState.ts +++ b/src/libs/Navigation/getMatchingCentralPaneRouteForState.ts @@ -32,9 +32,13 @@ const getTopMostReportIDFromRHP = (state: State): string => { }; // Get matching central pane route for bottom tab navigator. e.g HOME -> REPORT -function getMatchingCentralPaneRouteForState(state: State): NavigationPartialRoute { +function getMatchingCentralPaneRouteForState(state: State): NavigationPartialRoute | undefined { const topmostBottomTabRoute = getTopmostBottomTabRoute(state); + if (!topmostBottomTabRoute) { + return; + } + const centralPaneName = TAB_TO_CENTRAL_PANE_MAPPING[topmostBottomTabRoute.name][0]; if (topmostBottomTabRoute.name === SCREENS.WORKSPACE.INITIAL) { diff --git a/src/libs/Navigation/getTopmostBottomTabRoute.ts b/src/libs/Navigation/getTopmostBottomTabRoute.ts index 053f866bc3b5..47dd22886346 100644 --- a/src/libs/Navigation/getTopmostBottomTabRoute.ts +++ b/src/libs/Navigation/getTopmostBottomTabRoute.ts @@ -1,10 +1,11 @@ import {BottomTabName, NavigationPartialRoute, RootStackParamList, State} from './types'; -function getTopmostBottomTabRoute(state: State): NavigationPartialRoute { +function getTopmostBottomTabRoute(state: State): NavigationPartialRoute | undefined { const bottomTabNavigatorRoute = state.routes[0]; + // The bottomTabNavigatorRoute state may be empty if we just logged in. if (!bottomTabNavigatorRoute || bottomTabNavigatorRoute.name !== 'BottomTabNavigator' || bottomTabNavigatorRoute.state === undefined) { - throw new Error('There is no bottomTabNavigator route mounted as the first route in the root state.'); + return undefined; } const topmostBottomTabRoute = bottomTabNavigatorRoute.state.routes.at(-1); diff --git a/src/libs/Navigation/linkTo.ts b/src/libs/Navigation/linkTo.ts index 75bd2a5d02b4..debcba81cd01 100644 --- a/src/libs/Navigation/linkTo.ts +++ b/src/libs/Navigation/linkTo.ts @@ -124,7 +124,7 @@ export default function linkTo(navigation: NavigationContainerRef