Skip to content
Merged
48 changes: 16 additions & 32 deletions src/libs/Navigation/AppNavigator/AuthScreens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import getCurrentUrl from '@libs/Navigation/currentUrl';
import Navigation from '@libs/Navigation/Navigation';
import Animations from '@libs/Navigation/PlatformStackNavigation/navigationOptions/animation';
import Presentation from '@libs/Navigation/PlatformStackNavigation/navigationOptions/presentation';
import type {PlatformStackNavigationOptions} from '@libs/Navigation/PlatformStackNavigation/types';
import type {AuthScreensParamList} from '@libs/Navigation/types';
import NetworkConnection from '@libs/NetworkConnection';
import onyxSubscribe from '@libs/onyxSubscribe';
Expand Down Expand Up @@ -62,12 +61,7 @@ import type {SelectedTimezone, Timezone} from '@src/types/onyx/PersonalDetails';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import type ReactComponentModule from '@src/types/utils/ReactComponentModule';
import createRootStackNavigator from './createRootStackNavigator';
import {
reportsSplitsWithEnteringAnimation,
searchFullscreenWithEnteringAnimation,
settingsSplitWithEnteringAnimation,
workspaceSplitsWithoutEnteringAnimation,
} from './createRootStackNavigator/GetStateForActionHandlers';
import {screensWithEnteringAnimation, workspaceSplitsWithoutEnteringAnimation} from './createRootStackNavigator/GetStateForActionHandlers';
import defaultScreenOptions from './defaultScreenOptions';
import {ShareModalStackNavigator} from './ModalStackNavigators';
import ExplanationModalNavigator from './Navigators/ExplanationModalNavigator';
Expand Down Expand Up @@ -466,30 +460,20 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
};
};

const getFullScreenNavigatorOptions =
(routesWithEnteringAnimation: Set<string>, defaultOptions: PlatformStackNavigationOptions) =>
({route}: {route: RouteProp<AuthScreensParamList>}) => {
// We don't need to do anything special for the wide screen.
if (!shouldUseNarrowLayout) {
return defaultOptions;
}
// On the narrow screen, we want to animate this navigator if pushed SplitNavigator includes desired screen
const animationEnabled = routesWithEnteringAnimation.has(route.key);
// Animation is enabled when navigating to any screen different than split sidebar screen
const getFullscreenNavigatorOptions = ({route}: {route: RouteProp<AuthScreensParamList>}) => {
// We don't need to do anything special for the wide screen.
if (!shouldUseNarrowLayout) {
return rootNavigatorScreenOptions.splitNavigator;
}

return {
...defaultOptions,
animation: animationEnabled ? Animations.SLIDE_FROM_RIGHT : Animations.NONE,
};
// On the narrow screen, we want to animate this navigator if pushed SplitNavigator includes desired screen
const animationEnabled = screensWithEnteringAnimation.has(route.key);
return {
...rootNavigatorScreenOptions.splitNavigator,
animation: animationEnabled ? Animations.SLIDE_FROM_RIGHT : Animations.NONE,
};

// Animation is enabled when navigating to the report screen
const getReportsSplitNavigatorOptions = getFullScreenNavigatorOptions(reportsSplitsWithEnteringAnimation, rootNavigatorScreenOptions.splitNavigator);

// Animation is enabled when navigating to any screen different than SCREENS.SETTINGS.ROOT
const getSettingsSplitNavigatorOptions = getFullScreenNavigatorOptions(settingsSplitWithEnteringAnimation, rootNavigatorScreenOptions.splitNavigator);

// Animation is enabled when navigating to SCREENS.SEARCH.MONEY_REQUEST_REPORT
const getSearchFullscreenNavigatorOptions = getFullScreenNavigatorOptions(searchFullscreenWithEnteringAnimation, rootNavigatorScreenOptions.fullScreen);
};

const clearStatus = () => {
User.clearCustomStatus();
Expand Down Expand Up @@ -558,17 +542,17 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
{/* This has to be the first navigator in auth screens. */}
<RootStack.Screen
name={NAVIGATORS.REPORTS_SPLIT_NAVIGATOR}
options={getReportsSplitNavigatorOptions}
options={getFullscreenNavigatorOptions}
getComponent={loadReportSplitNavigator}
/>
<RootStack.Screen
name={NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR}
options={getSettingsSplitNavigatorOptions}
options={getFullscreenNavigatorOptions}
getComponent={loadSettingsSplitNavigator}
/>
<RootStack.Screen
name={NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR}
options={getSearchFullscreenNavigatorOptions}
options={getFullscreenNavigatorOptions}
getComponent={loadSearchNavigator}
/>
<RootStack.Screen
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {CommonActions, RouterConfigOptions, StackActionType, StackNavigationState} from '@react-navigation/native';
import {StackActions} from '@react-navigation/native';
import type {ParamListBase, Router} from '@react-navigation/routers';
import SCREENS_WITH_NAVIGATION_TAB_BAR from '@components/Navigation/TopLevelNavigationTabBar/SCREENS_WITH_NAVIGATION_TAB_BAR';
import Log from '@libs/Log';
import NAVIGATORS from '@src/NAVIGATORS';
import SCREENS from '@src/SCREENS';
Expand All @@ -23,9 +24,8 @@ const MODAL_ROUTES_TO_DISMISS: string[] = [
];

const workspaceSplitsWithoutEnteringAnimation = new Set<string>();
const reportsSplitsWithEnteringAnimation = new Set<string>();
const settingsSplitWithEnteringAnimation = new Set<string>();
const searchFullscreenWithEnteringAnimation = new Set<string>();

const screensWithEnteringAnimation = new Set<string>();
/**
* Handles the OPEN_WORKSPACE_SPLIT action.
* If the user is on other tab than workspaces and the workspace split is "remembered", this action will be called after pressing the settings tab.
Expand Down Expand Up @@ -73,84 +73,29 @@ function handleOpenWorkspaceSplitAction(
return stateWithWorkspaceSplitNavigator;
}

/**
* If a new ReportSplitNavigator is opened, it is necessary to check whether workspace is currently selected in the application.
* If so, the id of the current policy has to be passed to the new ReportSplitNavigator.
*/
function handlePushReportSplitAction(
state: StackNavigationState<ParamListBase>,
action: PushActionType,
configOptions: RouterConfigOptions,
stackRouter: Router<StackNavigationState<ParamListBase>, CommonActions.Action | StackActionType>,
) {
const stateWithReportsSplitNavigator = stackRouter.getStateForAction(state, action, configOptions);

if (!stateWithReportsSplitNavigator) {
Log.hmmm('[handlePushReportAction] ReportsSplitNavigator has not been found in the navigation state.');
return null;
}

const lastFullScreenRoute = stateWithReportsSplitNavigator.routes.at(-1);
const actionPayloadScreen = action.payload?.params && 'screen' in action.payload.params ? action.payload?.params?.screen : undefined;

// ReportScreen should always be opened with an animation
if (actionPayloadScreen === SCREENS.REPORT && lastFullScreenRoute?.key) {
reportsSplitsWithEnteringAnimation.add(lastFullScreenRoute.key);
}

return stateWithReportsSplitNavigator;
}

function handlePushSettingsSplitAction(
state: StackNavigationState<ParamListBase>,
action: PushActionType,
configOptions: RouterConfigOptions,
stackRouter: Router<StackNavigationState<ParamListBase>, CommonActions.Action | StackActionType>,
) {
const stateWithSettingsSplitNavigator = stackRouter.getStateForAction(state, action, configOptions);

if (!stateWithSettingsSplitNavigator) {
Log.hmmm('[handlePushSettingsAction] SettingsSplitNavigator has not been found in the navigation state.');
return null;
}

const lastFullScreenRoute = stateWithSettingsSplitNavigator.routes.at(-1);
const actionPayloadScreen = action.payload?.params && 'screen' in action.payload.params ? action.payload?.params?.screen : undefined;

// Transitioning to all central screens in settings should be animated
if (actionPayloadScreen !== SCREENS.SETTINGS.ROOT && lastFullScreenRoute?.key) {
settingsSplitWithEnteringAnimation.add(lastFullScreenRoute.key);
}

return stateWithSettingsSplitNavigator;
}

/**
* If a new Search page is opened, it is necessary to check whether workspace is currently selected in the application.
* If so, the id of the current policy has to be passed to the new Search page
*/
function handlePushSearchPageAction(
function handlePushFullscreenAction(
state: StackNavigationState<ParamListBase>,
action: PushActionType,
configOptions: RouterConfigOptions,
stackRouter: Router<StackNavigationState<ParamListBase>, CommonActions.Action | StackActionType>,
) {
const stateWithSearchFullscreenNavigator = stackRouter.getStateForAction(state, action, configOptions);
const stateWithNavigator = stackRouter.getStateForAction(state, action, configOptions);
const navigatorName = action.payload.name;

if (!stateWithSearchFullscreenNavigator) {
Log.hmmm('[handlePushSettingsAction] SearchFullscreenNavigator has not been found in the navigation state.');
if (!stateWithNavigator) {
Log.hmmm(`[handlePushAction] ${navigatorName} has not been found in the navigation state.`);
return null;
}

const lastFullScreenRoute = stateWithSearchFullscreenNavigator.routes.at(-1);
const actionPayloadScreen = action.payload?.params && 'screen' in action.payload.params ? action.payload?.params?.screen : undefined;
const lastFullScreenRoute = stateWithNavigator.routes.at(-1);
const actionPayloadScreen = action.payload?.params && 'screen' in action.payload.params ? (action.payload?.params?.screen as string) : undefined;

// Transitioning to SCREENS.SEARCH.MONEY_REQUEST_REPORT should be animated
if (actionPayloadScreen === SCREENS.SEARCH.MONEY_REQUEST_REPORT && lastFullScreenRoute?.key) {
searchFullscreenWithEnteringAnimation.add(lastFullScreenRoute.key);
// Transitioning to all central screens in each split should be animated
if (lastFullScreenRoute?.key && actionPayloadScreen && !SCREENS_WITH_NAVIGATION_TAB_BAR.includes(actionPayloadScreen)) {
screensWithEnteringAnimation.add(lastFullScreenRoute.key);
}

return stateWithSearchFullscreenNavigator;
return stateWithNavigator;
}

function handleReplaceReportsSplitNavigatorAction(
Expand All @@ -170,7 +115,7 @@ function handleReplaceReportsSplitNavigatorAction(

// ReportScreen should always be opened with an animation when replacing the navigator
if (lastReportsSplitNavigator?.key) {
reportsSplitsWithEnteringAnimation.add(lastReportsSplitNavigator.key);
screensWithEnteringAnimation.add(lastReportsSplitNavigator.key);
}

return stateWithReportsSplitNavigator;
Expand Down Expand Up @@ -213,12 +158,8 @@ export {
handleDismissModalAction,
handleNavigatingToModalFromModal,
handleOpenWorkspaceSplitAction,
handlePushReportSplitAction,
handlePushSearchPageAction,
handlePushSettingsSplitAction,
handlePushFullscreenAction,
handleReplaceReportsSplitNavigatorAction,
reportsSplitsWithEnteringAnimation,
searchFullscreenWithEnteringAnimation,
settingsSplitWithEnteringAnimation,
screensWithEnteringAnimation,
workspaceSplitsWithoutEnteringAnimation,
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type {CommonActions, RouterConfigOptions, StackActionType, StackNavigatio
import {findFocusedRoute, StackRouter} from '@react-navigation/native';
import type {ParamListBase} from '@react-navigation/routers';
import * as Localize from '@libs/Localize';
import {isOnboardingFlowName} from '@libs/Navigation/helpers/isNavigatorName';
import {isFullScreenName, isOnboardingFlowName} from '@libs/Navigation/helpers/isNavigatorName';
import isSideModalNavigator from '@libs/Navigation/helpers/isSideModalNavigator';
import * as Welcome from '@userActions/Welcome';
import CONST from '@src/CONST';
Expand All @@ -11,9 +11,7 @@ import {
handleDismissModalAction,
handleNavigatingToModalFromModal,
handleOpenWorkspaceSplitAction,
handlePushReportSplitAction,
handlePushSearchPageAction,
handlePushSettingsSplitAction,
handlePushFullscreenAction,
handleReplaceReportsSplitNavigatorAction,
} from './GetStateForActionHandlers';
import syncBrowserHistory from './syncBrowserHistory';
Expand Down Expand Up @@ -81,18 +79,11 @@ function RootStackRouter(options: RootStackNavigatorRouterOptions) {
return handleReplaceReportsSplitNavigatorAction(state, action, configOptions, stackRouter);
}

if (isPushAction(action)) {
if (action.payload.name === NAVIGATORS.REPORTS_SPLIT_NAVIGATOR) {
return handlePushReportSplitAction(state, action, configOptions, stackRouter);
}

if (action.payload.name === NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR) {
return handlePushSearchPageAction(state, action, configOptions, stackRouter);
}

if (action.payload.name === NAVIGATORS.SETTINGS_SPLIT_NAVIGATOR) {
return handlePushSettingsSplitAction(state, action, configOptions, stackRouter);
}
// When navigating to a specific workspace from WorkspaceListPage there should be entering animation for its sidebar (only case where we want animation for sidebar)
// That's why we have a separate handler for opening it called handleOpenWorkspaceSplitAction
// options for WorkspaceSplitNavigator can be found in AuthScreens.tsx > getWorkspaceSplitNavigatorOptions
if (isPushAction(action) && isFullScreenName(action.payload.name) && action.payload.name !== NAVIGATORS.WORKSPACE_SPLIT_NAVIGATOR) {
return handlePushFullscreenAction(state, action, configOptions, stackRouter);
}

// Don't let the user navigate back to a non-onboarding screen if they are currently on an onboarding screen and it's not finished.
Expand Down
Loading