diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index e434db3ab21f..e320088f4c3a 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -33,7 +33,6 @@ import SCREENS from '@src/SCREENS'; import * as OnyxTypes from '@src/types/onyx'; import type {SelectedTimezone, Timezone} from '@src/types/onyx/PersonalDetails'; import createCustomStackNavigator from './createCustomStackNavigator'; -import CustomRouter from './createCustomStackNavigator/CustomRouter'; import defaultScreenOptions from './defaultScreenOptions'; import getRootNavigatorScreenOptions from './getRootNavigatorScreenOptions'; import CentralPaneNavigator from './Navigators/CentralPaneNavigator'; @@ -115,7 +114,7 @@ Onyx.connect({ }, }); -const RootStack = createCustomStackNavigator(CustomRouter); +const RootStack = createCustomStackNavigator(); // We want to delay the re-rendering for components(e.g. ReportActionCompose) // that depends on modal visibility until Modal is completely closed and its focused // When modal screen is focused, update modal visibility in Onyx diff --git a/src/libs/Navigation/AppNavigator/Navigators/FullScreenNavigator.tsx b/src/libs/Navigation/AppNavigator/Navigators/FullScreenNavigator.tsx index 94a7c7c02a01..635493cab2dd 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/FullScreenNavigator.tsx +++ b/src/libs/Navigation/AppNavigator/Navigators/FullScreenNavigator.tsx @@ -1,16 +1,16 @@ import React from 'react'; import {View} from 'react-native'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import createCustomStackNavigator from '@libs/Navigation/AppNavigator/createCustomStackNavigator'; -import CustomFullScreenRouter from '@libs/Navigation/AppNavigator/createCustomStackNavigator/CustomFullScreenRouter'; + import getRootNavigatorScreenOptions from '@libs/Navigation/AppNavigator/getRootNavigatorScreenOptions'; import * as ModalStackNavigators from '@libs/Navigation/AppNavigator/ModalStackNavigators'; import useThemeStyles from '@styles/useThemeStyles'; import SCREENS from '@src/SCREENS'; +import createCustomFullScreenNavigator from '@libs/Navigation/AppNavigator/createCustomFullScreenNavigator'; const loadPage = () => require('../../../../pages/settings/InitialSettingsPage').default as React.ComponentType; -const RootStack = createCustomStackNavigator(CustomFullScreenRouter); +const RootStack = createCustomFullScreenNavigator(); function FullScreenNavigator() { const styles = useThemeStyles(); diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomFullScreenRouter.tsx b/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/CustomFullScreenRouter.tsx similarity index 100% rename from src/libs/Navigation/AppNavigator/createCustomStackNavigator/CustomFullScreenRouter.tsx rename to src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/CustomFullScreenRouter.tsx diff --git a/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/index.native.tsx b/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/index.native.tsx new file mode 100644 index 000000000000..ee3291d06345 --- /dev/null +++ b/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/index.native.tsx @@ -0,0 +1,42 @@ +import {createNavigatorFactory, ParamListBase, StackActionHelpers, StackNavigationState, useNavigationBuilder} from '@react-navigation/native'; +import {StackNavigationEventMap, StackNavigationOptions, StackView} from '@react-navigation/stack'; +import React, {useRef} from 'react'; +import useWindowDimensions from '@hooks/useWindowDimensions'; +import CustomFullScreenRouter from './CustomFullScreenRouter'; +import type {ResponsiveStackNavigatorProps, ResponsiveStackNavigatorRouterOptions} from './types'; + +function ResponsiveStackNavigator(props: ResponsiveStackNavigatorProps) { + const {isSmallScreenWidth} = useWindowDimensions(); + + const isSmallScreenWidthRef = useRef(isSmallScreenWidth); + + isSmallScreenWidthRef.current = isSmallScreenWidth; + + const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder< + StackNavigationState, + ResponsiveStackNavigatorRouterOptions, + StackActionHelpers, + StackNavigationOptions, + StackNavigationEventMap + >(CustomFullScreenRouter, { + children: props.children, + screenOptions: props.screenOptions, + initialRouteName: props.initialRouteName, + }); + + return ( + + + + ); +} + +ResponsiveStackNavigator.displayName = 'ResponsiveStackNavigator'; + +export default createNavigatorFactory, StackNavigationOptions, StackNavigationEventMap, typeof ResponsiveStackNavigator>(ResponsiveStackNavigator); \ No newline at end of file diff --git a/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/index.tsx b/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/index.tsx new file mode 100644 index 000000000000..5f8056deaa92 --- /dev/null +++ b/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/index.tsx @@ -0,0 +1,75 @@ +import {createNavigatorFactory, ParamListBase, StackActionHelpers, StackNavigationState, useNavigationBuilder} from '@react-navigation/native'; +import {StackNavigationEventMap, StackNavigationOptions, StackView} from '@react-navigation/stack'; +import React, {useMemo, useRef} from 'react'; +import useWindowDimensions from '@hooks/useWindowDimensions'; +import SCREENS from '@src/SCREENS'; +import CustomFullScreenRouter from './CustomFullScreenRouter'; +import type {ResponsiveStackNavigatorProps, ResponsiveStackNavigatorRouterOptions} from './types'; + +// TODO: Extract to utils with ./createCustomStackNavigator/index.tsx +type Routes = StackNavigationState['routes']; +function reduceReportRoutes(routes: Routes): Routes { + const result: Routes = []; + let count = 0; + const reverseRoutes = [...routes].reverse(); + + reverseRoutes.forEach((route) => { + if (route.name === SCREENS.SETTINGS_CENTRAL_PANE) { + // Remove all report routes except the last 3. This will improve performance. + if (count < 3) { + result.push(route); + count++; + } + } else { + result.push(route); + } + }); + + return result.reverse(); +} + +function ResponsiveStackNavigator(props: ResponsiveStackNavigatorProps) { + const {isSmallScreenWidth} = useWindowDimensions(); + + const isSmallScreenWidthRef = useRef(isSmallScreenWidth); + + isSmallScreenWidthRef.current = isSmallScreenWidth; + + const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder< + StackNavigationState, + ResponsiveStackNavigatorRouterOptions, + StackActionHelpers, + StackNavigationOptions, + StackNavigationEventMap + >(CustomFullScreenRouter, { + children: props.children, + screenOptions: props.screenOptions, + initialRouteName: props.initialRouteName, + }); + + const stateToRender = useMemo(() => { + const result = reduceReportRoutes(state.routes); + + return { + ...state, + index: result.length - 1, + routes: [...result], + }; + }, [state]); + + return ( + + + + ); +} + +ResponsiveStackNavigator.displayName = 'ResponsiveStackNavigator'; + +export default createNavigatorFactory, StackNavigationOptions, StackNavigationEventMap, typeof ResponsiveStackNavigator>(ResponsiveStackNavigator); \ No newline at end of file diff --git a/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/types.ts b/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/types.ts new file mode 100644 index 000000000000..707a0ff4498d --- /dev/null +++ b/src/libs/Navigation/AppNavigator/createCustomFullScreenNavigator/types.ts @@ -0,0 +1,13 @@ +import {DefaultNavigatorOptions, ParamListBase, StackNavigationState, StackRouterOptions} from '@react-navigation/native'; +import {StackNavigationEventMap, StackNavigationOptions} from '@react-navigation/stack'; + +type ResponsiveStackNavigatorConfig = { + isSmallScreenWidth: boolean; +}; + +type ResponsiveStackNavigatorRouterOptions = StackRouterOptions; + +type ResponsiveStackNavigatorProps = DefaultNavigatorOptions, StackNavigationOptions, StackNavigationEventMap> & + ResponsiveStackNavigatorConfig; + +export type {ResponsiveStackNavigatorRouterOptions, ResponsiveStackNavigatorProps, ResponsiveStackNavigatorConfig}; diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.tsx b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.tsx index c3030f8d0cdd..e07bc8c79780 100644 --- a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.tsx @@ -1,50 +1,42 @@ -import {createNavigatorFactory, ParamListBase, RouterFactory, StackActionHelpers, StackNavigationState, useNavigationBuilder} from '@react-navigation/native'; +import {createNavigatorFactory, ParamListBase, StackActionHelpers, StackNavigationState, useNavigationBuilder} from '@react-navigation/native'; import {StackNavigationEventMap, StackNavigationOptions, StackView} from '@react-navigation/stack'; import React, {useRef} from 'react'; import useWindowDimensions from '@hooks/useWindowDimensions'; +import CustomRouter from './CustomRouter'; import type {ResponsiveStackNavigatorProps, ResponsiveStackNavigatorRouterOptions} from './types'; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type CustomRouterFactory = RouterFactory, any, ResponsiveStackNavigatorRouterOptions>; - -function ResponsiveStackNavigatorFactory(customRouter: CustomRouterFactory) { - function ResponsiveStackNavigator(props: ResponsiveStackNavigatorProps) { - const {isSmallScreenWidth} = useWindowDimensions(); - - const isSmallScreenWidthRef = useRef(isSmallScreenWidth); - - isSmallScreenWidthRef.current = isSmallScreenWidth; - - const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder< - StackNavigationState, - ResponsiveStackNavigatorRouterOptions, - StackActionHelpers, - StackNavigationOptions, - StackNavigationEventMap - >(customRouter, { - children: props.children, - screenOptions: props.screenOptions, - initialRouteName: props.initialRouteName, - }); - - return ( - - - - ); - } - - ResponsiveStackNavigator.displayName = 'ResponsiveStackNavigator'; - return ResponsiveStackNavigator; +function ResponsiveStackNavigator(props: ResponsiveStackNavigatorProps) { + const {isSmallScreenWidth} = useWindowDimensions(); + + const isSmallScreenWidthRef = useRef(isSmallScreenWidth); + + isSmallScreenWidthRef.current = isSmallScreenWidth; + + const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder< + StackNavigationState, + ResponsiveStackNavigatorRouterOptions, + StackActionHelpers, + StackNavigationOptions, + StackNavigationEventMap + >(CustomRouter, { + children: props.children, + screenOptions: props.screenOptions, + initialRouteName: props.initialRouteName, + }); + + return ( + + + + ); } -export default (customRouter: CustomRouterFactory) => - createNavigatorFactory, StackNavigationOptions, StackNavigationEventMap, (props: ResponsiveStackNavigatorProps) => React.JSX.Element>( - ResponsiveStackNavigatorFactory(customRouter), - )(); +ResponsiveStackNavigator.displayName = 'ResponsiveStackNavigator'; + +export default createNavigatorFactory, StackNavigationOptions, StackNavigationEventMap, typeof ResponsiveStackNavigator>(ResponsiveStackNavigator); \ No newline at end of file diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.tsx b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.tsx index f69a42072c52..01bf5adcac57 100644 --- a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.tsx @@ -1,8 +1,9 @@ -import {CommonNavigationAction, createNavigatorFactory, ParamListBase, RouterFactory, StackActionHelpers, StackActionType, StackNavigationState, useNavigationBuilder} from '@react-navigation/native'; +import {createNavigatorFactory, ParamListBase, StackActionHelpers, StackNavigationState, useNavigationBuilder} from '@react-navigation/native'; import {StackNavigationEventMap, StackNavigationOptions, StackView} from '@react-navigation/stack'; import React, {useMemo, useRef} from 'react'; import useWindowDimensions from '@hooks/useWindowDimensions'; import NAVIGATORS from '@src/NAVIGATORS'; +import CustomRouter from './CustomRouter'; import type {ResponsiveStackNavigatorProps, ResponsiveStackNavigatorRouterOptions} from './types'; type Routes = StackNavigationState['routes']; @@ -26,65 +27,48 @@ function reduceReportRoutes(routes: Routes): Routes { return result.reverse(); } -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type CustomRouterFactory = RouterFactory, CommonNavigationAction | StackActionType, ResponsiveStackNavigatorRouterOptions>; +function ResponsiveStackNavigator(props: ResponsiveStackNavigatorProps) { + const {isSmallScreenWidth} = useWindowDimensions(); -function ResponsiveStackNavigatorFactory(customRouter: CustomRouterFactory) { - function ResponsiveStackNavigator(props: ResponsiveStackNavigatorProps) { - const {isSmallScreenWidth} = useWindowDimensions(); + const isSmallScreenWidthRef = useRef(isSmallScreenWidth); - const isSmallScreenWidthRef = useRef(isSmallScreenWidth); + isSmallScreenWidthRef.current = isSmallScreenWidth; - isSmallScreenWidthRef.current = isSmallScreenWidth; - - const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder< - StackNavigationState, - ResponsiveStackNavigatorRouterOptions, - StackActionHelpers, - StackNavigationOptions, - StackNavigationEventMap - >(customRouter, { - children: props.children, - screenOptions: props.screenOptions, - initialRouteName: props.initialRouteName, - }); - - const stateToRender = useMemo(() => { - const result = reduceReportRoutes(state.routes); - - return { - ...state, - index: result.length - 1, - routes: [...result], - }; - }, [state]); - - return ( - - - - ); - } - - ResponsiveStackNavigator.displayName = 'ResponsiveStackNavigator'; - - return ResponsiveStackNavigator; -} - -function createCustomStackNavigator(customRouter: CustomRouterFactory) { - - const responsiveStackNavigator = ResponsiveStackNavigatorFactory(customRouter); + const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder< + StackNavigationState, + ResponsiveStackNavigatorRouterOptions, + StackActionHelpers, + StackNavigationOptions, + StackNavigationEventMap + >(CustomRouter, { + children: props.children, + screenOptions: props.screenOptions, + initialRouteName: props.initialRouteName, + }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const navigatorFactory = createNavigatorFactory, StackNavigationOptions, StackNavigationEventMap, any>(responsiveStackNavigator); - return navigatorFactory(); + const stateToRender = useMemo(() => { + const result = reduceReportRoutes(state.routes); + + return { + ...state, + index: result.length - 1, + routes: [...result], + }; + }, [state]); + + return ( + + + + ); } +ResponsiveStackNavigator.displayName = 'ResponsiveStackNavigator'; -export default createCustomStackNavigator; \ No newline at end of file +export default createNavigatorFactory, StackNavigationOptions, StackNavigationEventMap, typeof ResponsiveStackNavigator>(ResponsiveStackNavigator); \ No newline at end of file