From 87f60149c8b3540a06d9b51f67e6f77110b42b2f Mon Sep 17 00:00:00 2001 From: Adam Grzybowski Date: Tue, 24 Oct 2023 18:25:05 +0200 Subject: [PATCH 1/2] limit report routes in customStackNavigator --- .../createCustomStackNavigator/index.js | 36 ++++++++++- .../index.native.js | 60 +++++++++++++++++++ 2 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.js diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js index 58be3d2af3da..bfc56cf171c0 100644 --- a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.js @@ -1,9 +1,10 @@ -import React, {useRef} from 'react'; +import React, {useRef, useMemo} from 'react'; import PropTypes from 'prop-types'; import {useNavigationBuilder, createNavigatorFactory} from '@react-navigation/native'; import {StackView} from '@react-navigation/stack'; import CustomRouter from './CustomRouter'; import useWindowDimensions from '../../../../hooks/useWindowDimensions'; +import NAVIGATORS from '../../../../NAVIGATORS'; const propTypes = { /* Determines if the navigator should render the StackView (narrow) or ThreePaneView (wide) */ @@ -25,6 +26,24 @@ const defaultProps = { screenOptions: undefined, }; +function splitRoutes(routes) { + const reportRoutes = []; + const rhpRoutes = []; + const otherRoutes = []; + + routes.forEach((route) => { + if (route.name === NAVIGATORS.CENTRAL_PANE_NAVIGATOR) { + reportRoutes.push(route); + } else if (route.name === NAVIGATORS.RIGHT_MODAL_NAVIGATOR) { + rhpRoutes.push(route); + } else { + otherRoutes.push(route); + } + }); + + return {reportRoutes, rhpRoutes, otherRoutes}; +} + function ResponsiveStackNavigator(props) { const {isSmallScreenWidth} = useWindowDimensions(); @@ -40,12 +59,25 @@ function ResponsiveStackNavigator(props) { getIsSmallScreenWidth: () => isSmallScreenWidthRef.current, }); + const stateToRender = useMemo(() => { + const {reportRoutes, rhpRoutes, otherRoutes} = splitRoutes(state.routes); + + // Remove all report routes except the last 3. This will improve performance. + const limitedReportRoutes = reportRoutes.slice(-3); + + return { + ...state, + index: otherRoutes.length + limitedReportRoutes.length + rhpRoutes.length - 1, + routes: [...otherRoutes, ...limitedReportRoutes, ...rhpRoutes], + }; + }, [state]); + return ( diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.js b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.js new file mode 100644 index 000000000000..58be3d2af3da --- /dev/null +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.native.js @@ -0,0 +1,60 @@ +import React, {useRef} from 'react'; +import PropTypes from 'prop-types'; +import {useNavigationBuilder, createNavigatorFactory} from '@react-navigation/native'; +import {StackView} from '@react-navigation/stack'; +import CustomRouter from './CustomRouter'; +import useWindowDimensions from '../../../../hooks/useWindowDimensions'; + +const propTypes = { + /* Determines if the navigator should render the StackView (narrow) or ThreePaneView (wide) */ + isSmallScreenWidth: PropTypes.bool.isRequired, + + /* Children for the useNavigationBuilder hook */ + children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]).isRequired, + + /* initialRouteName for this navigator */ + initialRouteName: PropTypes.oneOf([PropTypes.string, PropTypes.undefined]), + + /* Screen options defined for this navigator */ + // eslint-disable-next-line react/forbid-prop-types + screenOptions: PropTypes.object, +}; + +const defaultProps = { + initialRouteName: undefined, + screenOptions: undefined, +}; + +function ResponsiveStackNavigator(props) { + const {isSmallScreenWidth} = useWindowDimensions(); + + const isSmallScreenWidthRef = useRef(isSmallScreenWidth); + + isSmallScreenWidthRef.current = isSmallScreenWidth; + + const {navigation, state, descriptors, NavigationContent} = useNavigationBuilder(CustomRouter, { + children: props.children, + screenOptions: props.screenOptions, + initialRouteName: props.initialRouteName, + // Options for useNavigationBuilder won't update on prop change, so we need to pass a getter for the router to have the current state of isSmallScreenWidth. + getIsSmallScreenWidth: () => isSmallScreenWidthRef.current, + }); + + return ( + + + + ); +} + +ResponsiveStackNavigator.defaultProps = defaultProps; +ResponsiveStackNavigator.propTypes = propTypes; +ResponsiveStackNavigator.displayName = 'ResponsiveStackNavigator'; + +export default createNavigatorFactory(ResponsiveStackNavigator); From 492da8c25424f0567ec5e9b29b17e2c4e3896c44 Mon Sep 17 00:00:00 2001 From: Adam Grzybowski Date: Wed, 25 Oct 2023 18:09:13 +0200 Subject: [PATCH 2/2] remove freeze wrapper for central pane routes on web --- .../Navigators/CentralPaneNavigator.js | 36 ------------------- .../BaseCentralPaneNavigator.js | 33 +++++++++++++++++ .../Navigators/CentralPaneNavigator/index.js | 10 ++++++ .../CentralPaneNavigator/index.native.js | 13 +++++++ 4 files changed, 56 insertions(+), 36 deletions(-) delete mode 100644 src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator.js create mode 100644 src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.js create mode 100644 src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.js create mode 100644 src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.native.js diff --git a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator.js b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator.js deleted file mode 100644 index 64eadcbe06c3..000000000000 --- a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator.js +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; -import {createStackNavigator} from '@react-navigation/stack'; -import SCREENS from '../../../../SCREENS'; -import ReportScreenWrapper from '../ReportScreenWrapper'; -import getCurrentUrl from '../../currentUrl'; -import styles from '../../../../styles/styles'; -import FreezeWrapper from '../../FreezeWrapper'; - -const Stack = createStackNavigator(); - -const url = getCurrentUrl(); -const openOnAdminRoom = url ? new URL(url).searchParams.get('openOnAdminRoom') : undefined; - -function CentralPaneNavigator() { - return ( - - - - - - ); -} - -export default CentralPaneNavigator; diff --git a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.js b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.js new file mode 100644 index 000000000000..190fa375d611 --- /dev/null +++ b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/BaseCentralPaneNavigator.js @@ -0,0 +1,33 @@ +import React from 'react'; +import {createStackNavigator} from '@react-navigation/stack'; +import SCREENS from '../../../../../SCREENS'; +import ReportScreenWrapper from '../../ReportScreenWrapper'; +import getCurrentUrl from '../../../currentUrl'; +import styles from '../../../../../styles/styles'; + +const Stack = createStackNavigator(); + +const url = getCurrentUrl(); +const openOnAdminRoom = url ? new URL(url).searchParams.get('openOnAdminRoom') : undefined; + +function BaseCentralPaneNavigator() { + return ( + + + + ); +} + +export default BaseCentralPaneNavigator; diff --git a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.js b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.js new file mode 100644 index 000000000000..711dd468c77d --- /dev/null +++ b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.js @@ -0,0 +1,10 @@ +import React from 'react'; +import BaseCentralPaneNavigator from './BaseCentralPaneNavigator'; + +// We don't need to use freeze wraper on web because we don't render all report routes anyway. +// You can see this optimalization in the customStackNavigator. +function CentralPaneNavigator() { + return ; +} + +export default CentralPaneNavigator; diff --git a/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.native.js b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.native.js new file mode 100644 index 000000000000..2bac1d102800 --- /dev/null +++ b/src/libs/Navigation/AppNavigator/Navigators/CentralPaneNavigator/index.native.js @@ -0,0 +1,13 @@ +import React from 'react'; +import FreezeWrapper from '../../../FreezeWrapper'; +import BaseCentralPaneNavigator from './BaseCentralPaneNavigator'; + +function CentralPaneNavigator() { + return ( + + + + ); +} + +export default CentralPaneNavigator;