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

[CP Staging] Search bottom-up if a component is in a narrow modal navigator #43074

Merged
merged 6 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
18 changes: 13 additions & 5 deletions src/hooks/useResponsiveLayout.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {NavigationContainerRefContext, NavigationContext} from '@react-navigation/native';
import {useContext} from 'react';
import ModalContext from '@components/Modal/ModalContext';
import Navigation from '@libs/Navigation/Navigation';
import CONST from '@src/CONST';
import useRootNavigationState from './useRootNavigationState';
import NAVIGATORS from '@src/NAVIGATORS';
import useWindowDimensions from './useWindowDimensions';

type ResponsiveLayoutResult = {
Expand Down Expand Up @@ -38,16 +38,24 @@ export default function useResponsiveLayout(): ResponsiveLayoutResult {
// This means it will only be defined if the component calling this hook is a child of a modal component. See BaseModal for the provider.
const {activeModalType} = useContext(ModalContext);

// This refers to the state of the root navigator, and is true if and only if the topmost navigator is the "left modal navigator" or the "right modal navigator"
const isDisplayedInModalNavigator = !!useRootNavigationState(Navigation.isModalNavigatorActive);
// We are using these contexts directly instead of useNavigation/useNavigationState, because those will throw an error if used outside a navigator.
// This hook can be used within or outside a navigator, so using useNavigationState does not work.
// Furthermore, wrapping useNavigationState in a try/catch does not work either, because that breaks the rules of hooks.
// Note that these three lines are copied closely from the internal implementation of useNavigation: https://github.com/react-navigation/react-navigation/blob/52a3234b7aaf4d4fcc9c0155f44f3ea2233f0f40/packages/core/src/useNavigation.tsx#L18-L28
const navigationContainerRef = useContext(NavigationContainerRefContext);
const navigator = useContext(NavigationContext);
const currentNavigator = navigator ?? navigationContainerRef;

const isDisplayedInNarrowModalNavigator =
!!currentNavigator?.getParent?.(NAVIGATORS.RIGHT_MODAL_NAVIGATOR as unknown as undefined) || !!currentNavigator?.getParent?.(NAVIGATORS.LEFT_MODAL_NAVIGATOR as unknown as undefined);
roryabraham marked this conversation as resolved.
Show resolved Hide resolved

// The component calling this hook is in a "narrow pane modal" if:
const isInNarrowPaneModal =
// it's a child of the right-docked modal
activeModalType === CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED ||
// or there's a "right modal navigator" or "left modal navigator" on the top of the root navigation stack
// and the component calling this hook is not the child of another modal type, such as a confirm modal
(isDisplayedInModalNavigator && !activeModalType);
(isDisplayedInNarrowModalNavigator && !activeModalType);

const shouldUseNarrowLayout = isSmallScreenWidth || isInNarrowPaneModal;

Expand Down
30 changes: 0 additions & 30 deletions src/hooks/useRootNavigationState.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import ModalNavigatorScreenOptions from '@libs/Navigation/AppNavigator/ModalNavigatorScreenOptions';
import type {AuthScreensParamList, LeftModalNavigatorParamList} from '@libs/Navigation/types';
import type NAVIGATORS from '@src/NAVIGATORS';
import NAVIGATORS from '@src/NAVIGATORS';
import SCREENS from '@src/SCREENS';
import Overlay from './Overlay';

Expand All @@ -32,7 +32,10 @@ function LeftModalNavigator({navigation}: LeftModalNavigatorProps) {
/>
)}
<View style={styles.LHPNavigatorContainer(isSmallScreenWidth)}>
<Stack.Navigator screenOptions={screenOptions}>
<Stack.Navigator
screenOptions={screenOptions}
id={NAVIGATORS.LEFT_MODAL_NAVIGATOR}
>
<Stack.Screen
name={SCREENS.LEFT_MODAL.CHAT_FINDER}
getComponent={loadChatFinder}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import useWindowDimensions from '@hooks/useWindowDimensions';
import ModalNavigatorScreenOptions from '@libs/Navigation/AppNavigator/ModalNavigatorScreenOptions';
import * as ModalStackNavigators from '@libs/Navigation/AppNavigator/ModalStackNavigators';
import type {AuthScreensParamList, RightModalNavigatorParamList} from '@navigation/types';
import type NAVIGATORS from '@src/NAVIGATORS';
import NAVIGATORS from '@src/NAVIGATORS';
import SCREENS from '@src/SCREENS';
import Overlay from './Overlay';

Expand Down Expand Up @@ -36,7 +36,10 @@ function RightModalNavigator({navigation}: RightModalNavigatorProps) {
/>
)}
<View style={styles.RHPNavigatorContainer(isSmallScreenWidth)}>
<Stack.Navigator screenOptions={screenOptions}>
<Stack.Navigator
screenOptions={screenOptions}
id={NAVIGATORS.RIGHT_MODAL_NAVIGATOR}
>
<Stack.Screen
name={SCREENS.RIGHT_MODAL.SETTINGS}
component={ModalStackNavigators.SettingsModalStackNavigator}
Expand Down
14 changes: 1 addition & 13 deletions src/libs/Navigation/Navigation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {findFocusedRoute} from '@react-navigation/core';
import type {EventArg, NavigationContainerEventMap, NavigationState} from '@react-navigation/native';
import type {EventArg, NavigationContainerEventMap} from '@react-navigation/native';
import {CommonActions, getPathFromState, StackActions} from '@react-navigation/native';
import Log from '@libs/Log';
import * as ReportUtils from '@libs/ReportUtils';
Expand Down Expand Up @@ -356,17 +356,6 @@ function navigateWithSwitchPolicyID(params: SwitchPolicyIDParams) {
return switchPolicyID(navigationRef.current, params);
}

/**
* Check if the modal is being displayed.
*
* @param state - MUST be the state of the root navigator for this to work. Do not use a child navigator state.
*/
function isModalNavigatorActive(state: NavigationState) {
const lastRoute = state?.routes?.at(-1);
const lastRouteName = lastRoute?.name;
return lastRouteName === NAVIGATORS.LEFT_MODAL_NAVIGATOR || lastRouteName === NAVIGATORS.RIGHT_MODAL_NAVIGATOR;
}

export default {
setShouldPopAllStateOnUP,
navigate,
Expand All @@ -386,7 +375,6 @@ export default {
parseHybridAppUrl,
navigateWithSwitchPolicyID,
resetToHome,
isModalNavigatorActive,
closeRHPFlow,
setNavigationActionToMicrotaskQueue,
};
Expand Down
Loading