Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion Mobile-Expensify
19 changes: 19 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
"@react-native-firebase/perf": "^12.3.0",
"@react-native-google-signin/google-signin": "^10.0.1",
"@react-native-picker/picker": "2.9.0",
"@react-navigation/bottom-tabs": "^6.6.1",
"@react-navigation/material-top-tabs": "^6.6.3",
"@react-navigation/native": "6.1.12",
"@react-navigation/native-stack": "^6.9.26",
Expand Down
16 changes: 15 additions & 1 deletion src/libs/Navigation/AppNavigator/AuthScreens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import Onyx, {useOnyx, withOnyx} from 'react-native-onyx';
import ComposeProviders from '@components/ComposeProviders';
import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
import OptionsListContextProvider from '@components/OptionListContextProvider';
import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
import PriorityModeController from '@components/PriorityModeController';
import {SearchContextProvider} from '@components/Search/SearchContext';
import {useSearchRouterContext} from '@components/Search/SearchRouter/SearchRouterContext';
import SearchRouterModal from '@components/Search/SearchRouter/SearchRouterModal';
import Text from '@components/Text';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useOnboardingFlowRouter from '@hooks/useOnboardingFlow';
import usePrevious from '@hooks/usePrevious';
Expand All @@ -26,7 +28,7 @@ import KeyboardShortcut from '@libs/KeyboardShortcut';
import Log from '@libs/Log';
import NavBarManager from '@libs/NavBarManager';
import getCurrentUrl from '@libs/Navigation/currentUrl';
import Navigation from '@libs/Navigation/Navigation';
import Navigation, {navigationRef} from '@libs/Navigation/Navigation';
import Animations from '@libs/Navigation/PlatformStackNavigation/navigationOptions/animation';
import Presentation from '@libs/Navigation/PlatformStackNavigation/navigationOptions/presentation';
import type {AuthScreensParamList} from '@libs/Navigation/types';
Expand Down Expand Up @@ -745,6 +747,18 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
</RootStack.Navigator>
<SearchRouterModal />
<PriorityModeController />
<PressableWithFeedback
accessible={false}
accessibilityRole="button"
onPress={() => {
navigationRef.current?.dispatch({
type: CONST.NAVIGATION.ACTION_TYPE.FLIP_ROUTES,
});
}}
style={{padding: 10, backgroundColor: 'white'}}
>
<Text style={{fontSize: 30, color: 'red'}}>Flip Routes</Text>
</PressableWithFeedback>
</ComposeProviders>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, {useState} from 'react';
import TestPressable from '@components/TestPressable';
import usePermissions from '@hooks/usePermissions';
import createSplitNavigator from '@libs/Navigation/AppNavigator/createSplitNavigator';
import FreezeWrapper from '@libs/Navigation/AppNavigator/FreezeWrapper';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React from 'react';
import FocusTrapForScreens from '@components/FocusTrap/FocusTrapForScreen';
import TestPressable from '@components/TestPressable';
import createSplitNavigator from '@libs/Navigation/AppNavigator/createSplitNavigator';
import useSplitNavigatorScreenOptions from '@libs/Navigation/AppNavigator/useSplitNavigatorScreenOptions';
import type {SettingsSplitNavigatorParamList} from '@libs/Navigation/types';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ function handlePushFullscreenAction(
}

const lastFullScreenRoute = stateWithNavigator.routes.at(-1);

// If the last full screen route has a name that is already in the routes array, replace the key with the last
if (lastFullScreenRoute?.name) {
const existingRoute = stateWithNavigator.routes.find((route) => route.name === lastFullScreenRoute.name);
if (existingRoute) {
console.log('test', existingRoute, lastFullScreenRoute);
lastFullScreenRoute.key = existingRoute.key;
}
}

const actionPayloadScreen = action.payload?.params && 'screen' in action.payload.params ? (action.payload?.params?.screen as string) : undefined;

// Transitioning to all central screens in each split should be animated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import isSideModalNavigator from '@libs/Navigation/helpers/isSideModalNavigator'
import * as Welcome from '@userActions/Welcome';
import CONST from '@src/CONST';
import NAVIGATORS from '@src/NAVIGATORS';
import SCREENS from '@src/SCREENS';
import {
handleDismissModalAction,
handleNavigatingToModalFromModal,
Expand Down Expand Up @@ -61,6 +62,14 @@ function isNavigatingToModalFromModal(state: StackNavigationState<ParamListBase>
return isSideModalNavigator(lastRoute?.name) && isSideModalNavigator(action.payload.name);
}

const TAB_ROUTES = [
NAVIGATORS.REPORTS_SPLIT_NAVIGATOR,
NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR,
SCREENS.WORKSPACES_LIST,
NAVIGATORS.WORKSPACE_SPLIT_NAVIGATOR,
NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR,
] as const;

function RootStackRouter(options: RootStackNavigatorRouterOptions) {
const stackRouter = StackRouter(options);

Expand Down
72 changes: 47 additions & 25 deletions src/libs/Navigation/AppNavigator/createRootStackNavigator/index.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,55 @@
import {createNavigatorFactory} from '@react-navigation/native';
import type {ParamListBase} from '@react-navigation/native';
import {BottomTabView} from '@react-navigation/bottom-tabs';
import type {DefaultNavigatorOptions, ParamListBase, StackActionHelpers, StackNavigationState, StackRouterOptions} from '@react-navigation/native';
import {createNavigatorFactory, useNavigationBuilder} from '@react-navigation/native';
import type {StackNavigationEventMap, StackNavigationOptions} from '@react-navigation/stack';
import type {StackNavigationConfig} from '@react-navigation/stack/lib/typescript/src/types';
import React, {useMemo} from 'react';
import RootNavigatorExtraContent from '@components/Navigation/RootNavigatorExtraContent';
import useNavigationResetOnLayoutChange from '@libs/Navigation/AppNavigator/useNavigationResetOnLayoutChange';
import {isFullScreenName} from '@libs/Navigation/helpers/isNavigatorName';
import createPlatformStackNavigatorComponent from '@libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent';
import defaultPlatformStackScreenOptions from '@libs/Navigation/PlatformStackNavigation/defaultPlatformStackScreenOptions';
import type {CustomStateHookProps, PlatformStackNavigationEventMap, PlatformStackNavigationOptions, PlatformStackNavigationState} from '@libs/Navigation/PlatformStackNavigation/types';
import RootStackRouter from './RootStackRouter';

// This is an optimization to keep mounted only last few screens in the stack.
function useCustomRootStackNavigatorState({state}: CustomStateHookProps) {
const lastSplitIndex = state.routes.findLastIndex((route) => isFullScreenName(route.name));
const routesToRender = state.routes.slice(Math.max(0, lastSplitIndex - 1), state.routes.length);
type Props = DefaultNavigatorOptions<ParamListBase, StackNavigationState<ParamListBase>, StackNavigationOptions, StackNavigationEventMap> & StackRouterOptions & StackNavigationConfig;

return {...state, routes: routesToRender, index: routesToRender.length - 1};
function transformStateForBottomTab(state: StackNavigationState<ParamListBase>) {
const lastRoute = state.routes.at(-1);

if (!lastRoute) {
return state;
}

return {
...state,
routes: [lastRoute],
index: 0,
};
}

const RootStackNavigatorComponent = createPlatformStackNavigatorComponent('RootStackNavigator', {
createRouter: RootStackRouter,
defaultScreenOptions: defaultPlatformStackScreenOptions,
useCustomEffects: useNavigationResetOnLayoutChange,
useCustomState: useCustomRootStackNavigatorState,
ExtraContent: RootNavigatorExtraContent,
});

function createRootStackNavigator<ParamList extends ParamListBase>() {
return createNavigatorFactory<PlatformStackNavigationState<ParamList>, PlatformStackNavigationOptions, PlatformStackNavigationEventMap, typeof RootStackNavigatorComponent>(
RootStackNavigatorComponent,
)<ParamList>();
function StackNavigator({id, initialRouteName, children, screenListeners, screenOptions}: Props) {
const {state, descriptors, navigation, NavigationContent} = useNavigationBuilder<
StackNavigationState<ParamListBase>,
StackRouterOptions,
StackActionHelpers<ParamListBase>,
StackNavigationOptions,
StackNavigationEventMap
>(RootStackRouter, {
id,
initialRouteName,
children,
screenListeners,
screenOptions,
});

const transformedState = useMemo(() => transformStateForBottomTab(state), [state]);

return (
<NavigationContent>
<BottomTabView
state={transformedState}
descriptors={descriptors}
navigation={navigation}
/>
<RootNavigatorExtraContent state={transformedState} />
</NavigationContent>
);
}

export default createRootStackNavigator;
export default createNavigatorFactory<StackNavigationState<ParamListBase>, StackNavigationOptions, StackNavigationEventMap, typeof StackNavigator>(StackNavigator);
1 change: 1 addition & 0 deletions src/libs/Navigation/NavigationRoot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady}: N
// We want to clean saved scroll offsets for screens that aren't anymore in the state.
cleanStaleScrollOffsets(state);
cleanPreservedNavigatorStates(state);
console.log(state);
};

return (
Expand Down
Loading