Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify the RootNavigator structure #42582

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
fb87e2e
Move settings to AuthScreens
WojtekBoman May 22, 2024
1411be4
Remove CentralPane
WojtekBoman May 22, 2024
aa779db
Add adjustments for new nav structure
WojtekBoman May 23, 2024
87ccd3e
Add CENTRAL_PANE_SCREENS
WojtekBoman May 24, 2024
a381924
Rename CentralPaneScreen to CentralPaneName
WojtekBoman May 24, 2024
da6c4fb
Adjust switchPolicyID to new nav structure
WojtekBoman May 24, 2024
43d4ca0
Remove getTopmostRoute
WojtekBoman May 24, 2024
7eef033
Add withPrepareCentralPaneScreen
WojtekBoman May 28, 2024
5410620
Merge branch 'main' into nav/flatten-central-pane
WojtekBoman Jun 3, 2024
eb2473d
Add ts fixes
WojtekBoman Jun 3, 2024
118c049
Merge branch 'main' into nav/flatten-central-pane
WojtekBoman Jun 3, 2024
e87c30a
AuthScreens and CENTRAL_PANE_SCREENS cleanup
WojtekBoman Jun 3, 2024
ca681c7
Merge branch 'main' into nav/flatten-central-pane
WojtekBoman Jun 4, 2024
c06c5dc
Fix storybook tests
WojtekBoman Jun 4, 2024
09ba271
Add docs for withPrepareCentralPaneScreen
WojtekBoman Jun 4, 2024
28c7a3f
Rename CentralPaneNameOptions
WojtekBoman Jun 4, 2024
99d5523
fix tests
adamgrzybowski Jun 5, 2024
a7a288a
Merge branch 'main' into nav/flatten-central-pane
adamgrzybowski Jun 5, 2024
64d29a7
Merge branch 'main' into nav/flatten-central-pane
adamgrzybowski Jun 7, 2024
19e05dd
fix types
adamgrzybowski Jun 7, 2024
3fc2ede
Merge branch 'main' into nav/flatten-central-pane
adamgrzybowski Jun 7, 2024
5a133a7
Merge branch 'main' into nav/flatten-central-pane
WojtekBoman Jun 10, 2024
9bc1bec
Merge branch 'main' into nav/flatten-central-pane
WojtekBoman Jun 12, 2024
be4d349
Fix types for central pane screens
WojtekBoman Jun 12, 2024
baaf214
fix central pane blinking on android
adamgrzybowski Jun 12, 2024
e92622a
fix accessing route params object in report screen
adamgrzybowski Jun 13, 2024
0698b3f
Merge branch 'main' into nav/flatten-central-pane
adamgrzybowski Jun 14, 2024
73721e3
Merge branch 'main' into nav/flatten-central-pane
WojtekBoman Jun 19, 2024
9d137bd
Merge branch 'main' into nav/flatten-central-pane
WojtekBoman Jun 21, 2024
70254e5
Cleaunp flatten central pane code
WojtekBoman Jun 21, 2024
c905a4c
Merge branch 'main' into nav/flatten-central-pane
WojtekBoman Jun 24, 2024
38c21a0
Merge branch 'main' into nav/flatten-central-pane
WojtekBoman Jun 25, 2024
0efb9f0
Merge branch 'main' into nav/flatten-central-pane
WojtekBoman Jun 25, 2024
becff51
Fix lint in switchPolicyID
WojtekBoman Jun 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/ScreenWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import useTackInputFocus from '@hooks/useTackInputFocus';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as Browser from '@libs/Browser';
import type {CentralPaneNavigatorParamList, RootStackParamList} from '@libs/Navigation/types';
import type {AuthScreensParamList, RootStackParamList} from '@libs/Navigation/types';
import toggleTestToolsModal from '@userActions/TestTool';
import CONST from '@src/CONST';
import CustomDevMenu from './CustomDevMenu';
Expand Down Expand Up @@ -93,7 +93,7 @@ type ScreenWrapperProps = {
*
* This is required because transitionEnd event doesn't trigger in the testing environment.
*/
navigation?: StackNavigationProp<RootStackParamList> | StackNavigationProp<CentralPaneNavigatorParamList>;
navigation?: StackNavigationProp<RootStackParamList> | StackNavigationProp<AuthScreensParamList>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
navigation?: StackNavigationProp<RootStackParamList> | StackNavigationProp<AuthScreensParamList>;
navigation?: StackNavigationProp<RootStackParamList> | StackNavigationProp<CentralPaneScreensParamList>;

Is it more correct if we use type CentralPaneScreensParamList here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CentralPaneScreensParamList is a subset of AuthScreens and it has been added to increase code readability and handle types correctly in the getCentralPaneScreenInitialParams function. For screens, I believe we should rely on the main set of screens.
cc: @adamgrzybowski

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the navigation object should be typed with all the screens from AuthNavigator | RootStack


/** Whether to show offline indicator on wide screens */
shouldShowOfflineIndicatorInWideScreen?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/useActiveRoute.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {useContext} from 'react';
import ActiveRouteContext from '@libs/Navigation/AppNavigator/Navigators/ActiveRouteContext';
import type {CentralPaneNavigatorParamList, NavigationPartialRoute} from '@libs/Navigation/types';
import type {AuthScreensParamList, NavigationPartialRoute} from '@libs/Navigation/types';

function useActiveRoute(): NavigationPartialRoute<keyof CentralPaneNavigatorParamList> | undefined {
function useActiveRoute(): NavigationPartialRoute<keyof AuthScreensParamList> | undefined {
return useContext(ActiveRouteContext);
}

Expand Down
35 changes: 28 additions & 7 deletions src/libs/Navigation/AppNavigator/AuthScreens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ import ROUTES from '@src/ROUTES';
import SCREENS from '@src/SCREENS';
import type * as OnyxTypes from '@src/types/onyx';
import type {SelectedTimezone, Timezone} from '@src/types/onyx/PersonalDetails';
import {CENTRAL_PANE_SCREENS} from './CENTRAL_PANE_SCREENS';
import type {CentralPaneName} from './CENTRAL_PANE_SCREENS';
import createCustomStackNavigator from './createCustomStackNavigator';
import defaultScreenOptions from './defaultScreenOptions';
import getRootNavigatorScreenOptions from './getRootNavigatorScreenOptions';
import BottomTabNavigator from './Navigators/BottomTabNavigator';
import CentralPaneNavigator from './Navigators/CentralPaneNavigator';
import FeatureTrainingModalNavigator from './Navigators/FeatureTrainingModalNavigator';
import FullScreenNavigator from './Navigators/FullScreenNavigator';
import LeftModalNavigator from './Navigators/LeftModalNavigator';
Expand Down Expand Up @@ -157,6 +158,9 @@ const modalScreenListeners = {
},
};

const url = getCurrentUrl();
const openOnAdminRoom = url ? new URL(url).searchParams.get('openOnAdminRoom') : undefined;

function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDAppliedToClient}: AuthScreensProps) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
Expand Down Expand Up @@ -273,20 +277,28 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const CentralPaneNameOptions = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering if this name is good for this structure

headerShown: false,
title: 'New Expensify',

// Prevent unnecessary scrolling
cardStyle: styles.cardStyleNavigator,
};

// @TODO: Check whether CENTRAL_PANE_SCREENS should be wrapped by FreezeWrapper on native platforms

return (
<OptionsListContextProvider>
<View style={styles.rootNavigatorContainerStyles(isSmallScreenWidth)}>
<RootStack.Navigator isSmallScreenWidth={isSmallScreenWidth}>
<RootStack.Navigator
screenOptions={screenOptions.centralPaneNavigator}
isSmallScreenWidth={isSmallScreenWidth}
>
<RootStack.Screen
name={NAVIGATORS.BOTTOM_TAB_NAVIGATOR}
options={screenOptions.bottomTab}
component={BottomTabNavigator}
/>
<RootStack.Screen
name={NAVIGATORS.CENTRAL_PANE_NAVIGATOR}
options={screenOptions.centralPaneNavigator}
component={CentralPaneNavigator}
/>
<RootStack.Screen
name={SCREENS.VALIDATE_LOGIN}
options={{
Expand Down Expand Up @@ -408,6 +420,15 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
options={defaultScreenOptions}
component={ConnectionCompletePage}
/>
{Object.entries(CENTRAL_PANE_SCREENS).map(([screenName, componentGetter]) => (
<RootStack.Screen
key={screenName}
name={screenName as CentralPaneName}
initialParams={{openOnAdminRoom: (screenName === SCREENS.REPORT && openOnAdminRoom === 'true') || undefined}}
getComponent={componentGetter}
options={CentralPaneNameOptions}
/>
))}
</RootStack.Navigator>
</View>
</OptionsListContextProvider>
Expand Down
25 changes: 25 additions & 0 deletions src/libs/Navigation/AppNavigator/CENTRAL_PANE_SCREENS.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type {AuthScreensParamList} from '@libs/Navigation/types';
import SCREENS from '@src/SCREENS';

type Screens = Partial<Record<keyof AuthScreensParamList, () => React.ComponentType>>;

const CENTRAL_PANE_SCREENS = {
[SCREENS.SETTINGS.WORKSPACES]: () => require('../../../pages/workspace/WorkspacesListPage').default as React.ComponentType,
[SCREENS.SETTINGS.PREFERENCES.ROOT]: () => require('../../../pages/settings/Preferences/PreferencesPage').default as React.ComponentType,
[SCREENS.SETTINGS.SECURITY]: () => require('../../../pages/settings/Security/SecuritySettingsPage').default as React.ComponentType,
[SCREENS.SETTINGS.PROFILE.ROOT]: () => require('../../../pages/settings/Profile/ProfilePage').default as React.ComponentType,
[SCREENS.SETTINGS.WALLET.ROOT]: () => require('../../../pages/settings/Wallet/WalletPage').default as React.ComponentType,
[SCREENS.SETTINGS.ABOUT]: () => require('../../../pages/settings/AboutPage/AboutPage').default as React.ComponentType,
[SCREENS.SETTINGS.TROUBLESHOOT]: () => require('../../../pages/settings/Troubleshoot/TroubleshootPage').default as React.ComponentType,
[SCREENS.SETTINGS.SAVE_THE_WORLD]: () => require('../../../pages/TeachersUnite/SaveTheWorldPage').default as React.ComponentType,
[SCREENS.SEARCH.CENTRAL_PANE]: () => require('../../../pages/Search/SearchPage').default as React.ComponentType,
[SCREENS.REPORT]: () => require('./ReportScreenWrapper').default as React.ComponentType,
} satisfies Screens;

const CENTRAL_PANE_SCREEN_NAMES = Object.keys(CENTRAL_PANE_SCREENS);

type CentralPaneName = keyof typeof CENTRAL_PANE_SCREENS;

export type {CentralPaneName};

export {CENTRAL_PANE_SCREENS, CENTRAL_PANE_SCREEN_NAMES};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import type {CentralPaneNavigatorParamList, NavigationPartialRoute} from '@libs/Navigation/types';
import type {AuthScreensParamList, NavigationPartialRoute} from '@libs/Navigation/types';

const ActiveRouteContext = React.createContext<NavigationPartialRoute<keyof CentralPaneNavigatorParamList> | undefined>(undefined);
const ActiveRouteContext = React.createContext<NavigationPartialRoute<keyof AuthScreensParamList> | undefined>(undefined);

export default ActiveRouteContext;
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import {useNavigationState} from '@react-navigation/native';
import type {StackNavigationOptions} from '@react-navigation/stack';
import React from 'react';
import type {CentralPaneName} from '@libs/Navigation/AppNavigator/CENTRAL_PANE_SCREENS';
import createCustomBottomTabNavigator from '@libs/Navigation/AppNavigator/createCustomBottomTabNavigator';
import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRoute';
import type {BottomTabNavigatorParamList, CentralPaneName, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types';
import type {BottomTabNavigatorParamList, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types';
import SidebarScreen from '@pages/home/sidebar/SidebarScreen';
import SearchPageBottomTab from '@pages/Search/SearchPageBottomTab';
import SCREENS from '@src/SCREENS';
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

4 changes: 2 additions & 2 deletions src/libs/Navigation/AppNavigator/ReportScreenWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React from 'react';
import type {CentralPaneNavigatorParamList} from '@navigation/types';
import type {AuthScreensParamList} from '@navigation/types';
import ReportScreen from '@pages/home/ReportScreen';
import type SCREENS from '@src/SCREENS';
import ReportScreenIDSetter from './ReportScreenIDSetter';

type ReportScreenWrapperProps = StackScreenProps<CentralPaneNavigatorParamList, typeof SCREENS.REPORT>;
type ReportScreenWrapperProps = StackScreenProps<AuthScreensParamList, typeof SCREENS.REPORT>;

function ReportScreenWrapper({route, navigation}: ReportScreenWrapperProps) {
// The ReportScreen without the reportID set will display a skeleton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import getTopmostBottomTabRoute from '@libs/Navigation/getTopmostBottomTabRoute'
import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRoute';
import Navigation from '@libs/Navigation/Navigation';
import type {RootStackParamList, State} from '@libs/Navigation/types';
import isCentralPaneName from '@libs/NavigationUtils';
import {getChatTabBrickRoad} from '@libs/WorkspacesSettingsUtils';
import BottomTabAvatar from '@pages/home/sidebar/BottomTabAvatar';
import BottomTabBarFloatingActionButton from '@pages/home/sidebar/BottomTabBarFloatingActionButton';
Expand Down Expand Up @@ -46,7 +47,7 @@ function BottomTabBar({isLoadingApp = false}: PurposeForUsingExpensifyModalProps
const currentRoute = routes?.[navigationState?.index ?? 0];
// When we are redirected to the Settings tab from the OldDot, we don't want to call the Welcome.show() method.
// To prevent this, the value of the bottomTabRoute?.name is checked here
if (Boolean(currentRoute && currentRoute.name !== NAVIGATORS.BOTTOM_TAB_NAVIGATOR && currentRoute.name !== NAVIGATORS.CENTRAL_PANE_NAVIGATOR) || Session.isAnonymousUser()) {
if (Boolean(currentRoute && currentRoute.name !== NAVIGATORS.BOTTOM_TAB_NAVIGATOR && !isCentralPaneName(currentRoute.name)) || Session.isAnonymousUser()) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRo
import linkingConfig from '@libs/Navigation/linkingConfig';
import getAdaptedStateFromPath from '@libs/Navigation/linkingConfig/getAdaptedStateFromPath';
import type {NavigationPartialRoute, RootStackParamList, State} from '@libs/Navigation/types';
import isCentralPaneName from '@libs/NavigationUtils';
import NAVIGATORS from '@src/NAVIGATORS';
import SCREENS from '@src/SCREENS';
import type {ResponsiveStackNavigatorRouterOptions} from './types';
Expand Down Expand Up @@ -66,8 +67,8 @@ function compareAndAdaptState(state: StackNavigationState<RootStackParamList>) {
return;
}

const topmostCentralPaneRoute = state.routes.filter((route) => route.name === NAVIGATORS.CENTRAL_PANE_NAVIGATOR).at(-1);
const templateCentralPaneRoute = templateState.routes.find((route) => route.name === NAVIGATORS.CENTRAL_PANE_NAVIGATOR);
const topmostCentralPaneRoute = state.routes.filter((route) => isCentralPaneName(route.name)).at(-1);
const templateCentralPaneRoute = templateState.routes.find((route) => isCentralPaneName(route.name));

const topmostCentralPaneRouteExtracted = getTopmostCentralPaneRoute(state);
const templateCentralPaneRouteExtracted = getTopmostCentralPaneRoute(templateState as State<RootStackParamList>);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import useWindowDimensions from '@hooks/useWindowDimensions';
import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRoute';
import navigationRef from '@libs/Navigation/navigationRef';
import type {RootStackParamList, State} from '@libs/Navigation/types';
import NAVIGATORS from '@src/NAVIGATORS';
import isCentralPaneName from '@libs/NavigationUtils';
import SCREENS from '@src/SCREENS';
import CustomRouter from './CustomRouter';
import type {ResponsiveStackNavigatorProps, ResponsiveStackNavigatorRouterOptions} from './types';
Expand All @@ -21,7 +21,7 @@ function reduceCentralPaneRoutes(routes: Routes): Routes {
const reverseRoutes = [...routes].reverse();

reverseRoutes.forEach((route) => {
if (route.name === NAVIGATORS.CENTRAL_PANE_NAVIGATOR) {
if (isCentralPaneName(route.name)) {
// Remove all central pane routes except the last 3. This will improve performance.
if (count < 3) {
result.push(route);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,7 @@ function getActionsFromPartialDiff(diff: GetPartialStateDiffReturnType): Navigat

if (centralPaneDiff) {
// In this case we have to wrap the inner central pane route with central pane navigator.
actions.push(
StackActions.push(NAVIGATORS.CENTRAL_PANE_NAVIGATOR, {
screen: centralPaneDiff.name,
params: centralPaneDiff.params,
}),
);
actions.push(StackActions.push(centralPaneDiff.name, centralPaneDiff.params));
}

if (fullScreenDiff) {
Expand Down
3 changes: 2 additions & 1 deletion src/libs/Navigation/Navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {findFocusedRoute} from '@react-navigation/core';
import type {EventArg, NavigationContainerEventMap} from '@react-navigation/native';
import {CommonActions, getPathFromState, StackActions} from '@react-navigation/native';
import Log from '@libs/Log';
import isCentralPaneName from '@libs/NavigationUtils';
import * as ReportUtils from '@libs/ReportUtils';
import {getReport} from '@libs/ReportUtils';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -220,7 +221,7 @@ function goBack(fallbackRoute?: Route, shouldEnforceFallback = false, shouldPopT
return;
}

const isCentralPaneFocused = findFocusedRoute(navigationRef.current.getState())?.name === NAVIGATORS.CENTRAL_PANE_NAVIGATOR;
const isCentralPaneFocused = isCentralPaneName(findFocusedRoute(navigationRef.current.getState())?.name);
const distanceFromPathInRootNavigator = getDistanceFromPathInRootNavigator(fallbackRoute ?? '');

// Allow CentralPane to use UP with fallback route if the path is not found in root navigator.
Expand Down
3 changes: 2 additions & 1 deletion src/libs/Navigation/dismissModalWithReport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {NavigationContainerRef} from '@react-navigation/native';
import {StackActions} from '@react-navigation/native';
import {findLastIndex} from 'lodash';
import Log from '@libs/Log';
import isCentralPaneName from '@libs/NavigationUtils';
import getPolicyEmployeeAccountIDs from '@libs/PolicyEmployeeListUtils';
import {doesReportBelongToWorkspace} from '@libs/ReportUtils';
import NAVIGATORS from '@src/NAVIGATORS';
Expand Down Expand Up @@ -64,7 +65,7 @@ function dismissModalWithReport(targetReport: Report | EmptyObject, navigationRe
// If not-found page is in the route stack, we need to close it
} else if (state.routes.some((route) => route.name === SCREENS.NOT_FOUND)) {
const lastRouteIndex = state.routes.length - 1;
const centralRouteIndex = findLastIndex(state.routes, (route) => route.name === NAVIGATORS.CENTRAL_PANE_NAVIGATOR);
const centralRouteIndex = findLastIndex(state.routes, (route) => isCentralPaneName(route.name));
navigationRef.dispatch({...StackActions.pop(lastRouteIndex - centralRouteIndex), target: state.key});
} else {
navigationRef.dispatch({...StackActions.pop(), target: state.key});
Expand Down
Loading
Loading