From 0599043e31be92c87b452b2a3fed7a5a2f651e47 Mon Sep 17 00:00:00 2001 From: Vit Horacek <36083550+mountiny@users.noreply.github.com> Date: Thu, 29 May 2025 01:02:35 +0200 Subject: [PATCH] Revert "Create custom history param" --- src/CONST.ts | 2 - .../addCustomHistoryRouterExtension.ts | 152 ------------------ .../AppNavigator/customHistory/index.ts | 2 - .../AppNavigator/customHistory/types.ts | 18 --- .../customHistory/useCustomHistoryParam.ts | 42 ----- .../index.native.tsx | 3 +- .../index.tsx | 3 +- .../Navigation/linkingConfig/HISTORY_PARAM.ts | 5 - .../RELATIONS/SCREEN_TO_HISTORY_PARAM.ts | 22 --- src/libs/Navigation/linkingConfig/config.ts | 3 - .../helpers/getHistoryParamParse.ts | 5 - src/libs/Navigation/types.ts | 1 - .../AddDelegate/ConfirmDelegatePage.tsx | 14 +- 13 files changed, 11 insertions(+), 261 deletions(-) delete mode 100644 src/libs/Navigation/AppNavigator/customHistory/addCustomHistoryRouterExtension.ts delete mode 100644 src/libs/Navigation/AppNavigator/customHistory/index.ts delete mode 100644 src/libs/Navigation/AppNavigator/customHistory/types.ts delete mode 100644 src/libs/Navigation/AppNavigator/customHistory/useCustomHistoryParam.ts delete mode 100644 src/libs/Navigation/linkingConfig/HISTORY_PARAM.ts delete mode 100644 src/libs/Navigation/linkingConfig/RELATIONS/SCREEN_TO_HISTORY_PARAM.ts delete mode 100644 src/libs/Navigation/linkingConfig/helpers/getHistoryParamParse.ts diff --git a/src/CONST.ts b/src/CONST.ts index 13e1a22725efc..f160b9fe75c77 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -5178,12 +5178,10 @@ const CONST = { REPLACE: 'REPLACE', PUSH: 'PUSH', NAVIGATE: 'NAVIGATE', - SET_PARAMS: 'SET_PARAMS', /** These action types are custom for RootNavigator */ DISMISS_MODAL: 'DISMISS_MODAL', OPEN_WORKSPACE_SPLIT: 'OPEN_WORKSPACE_SPLIT', - SET_HISTORY_PARAM: 'SET_HISTORY_PARAM', }, }, TIME_PERIOD: { diff --git a/src/libs/Navigation/AppNavigator/customHistory/addCustomHistoryRouterExtension.ts b/src/libs/Navigation/AppNavigator/customHistory/addCustomHistoryRouterExtension.ts deleted file mode 100644 index ca2deafc7493c..0000000000000 --- a/src/libs/Navigation/AppNavigator/customHistory/addCustomHistoryRouterExtension.ts +++ /dev/null @@ -1,152 +0,0 @@ -import {CommonActions, findFocusedRoute} from '@react-navigation/native'; -import type {ParamListBase, PartialState, Router, RouterConfigOptions, StackActionType} from '@react-navigation/native'; -import type {PlatformStackNavigationState, PlatformStackRouterFactory, PlatformStackRouterOptions} from '@libs/Navigation/PlatformStackNavigation/types'; -import type {SetParamsAction} from '@libs/Navigation/types'; -import CONST from '@src/CONST'; -import SCREEN_TO_HISTORY_PARAM from '@src/libs/Navigation/linkingConfig/RELATIONS/SCREEN_TO_HISTORY_PARAM'; -import type {Screen} from '@src/SCREENS'; -import type {HistoryStackNavigatorAction, SetHistoryParamActionType} from './types'; - -const CUSTOM_HISTORY_PREFIX = 'CUSTOM_HISTORY'; - -function isSetParamsAction(action: HistoryStackNavigatorAction): action is SetParamsAction { - return action.type === CONST.NAVIGATION.ACTION_TYPE.SET_PARAMS; -} - -function isSetHistoryParamAction(action: HistoryStackNavigatorAction): action is SetHistoryParamActionType { - return action.type === CONST.NAVIGATION.ACTION_TYPE.SET_HISTORY_PARAM; -} - -// The history can be anything. For now, string is enough but we can extend it to include more data if necessary. -function getCustomHistoryEntry(routeName: string) { - return `${CUSTOM_HISTORY_PREFIX}-${routeName}`; -} - -/** - * Higher-order function that extends the React Navigation stack router with custom history functionality. - * It allows tracking and managing navigation history entries that are not determined by the routes of navigator. - * The extension adds support for custom history entries through route params and maintains a history stack - * that can be manipulated independently of the navigation state. - * - * @param originalStackRouter - The original stack router function to be extended - * @returns Enhanced router with custom history functionality - */ - -function addCustomHistoryRouterExtension( - originalRouter: PlatformStackRouterFactory, -) { - return (options: RouterOptions): Router, HistoryStackNavigatorAction> => { - const router = originalRouter(options); - - const enhanceStateWithHistory = (state: PlatformStackNavigationState) => { - return { - ...state, - history: state.routes.map((route) => route.key), - }; - }; - - // Override methods to enhance state with history - const getInitialState = (configOptions: RouterConfigOptions) => { - const state = router.getInitialState(configOptions); - return enhanceStateWithHistory(state); - }; - - const getRehydratedState = (partialState: PartialState>, configOptions: RouterConfigOptions) => { - const state = router.getRehydratedState(partialState, configOptions); - const stateWithInitialHistory = enhanceStateWithHistory(state); - - const focusedRoute = findFocusedRoute(stateWithInitialHistory); - - // There always be a focused route in the state. It's for type safety. - if (!focusedRoute) { - return stateWithInitialHistory; - } - - // @ts-expect-error focusedRoute.key is always defined because it is a route from a rehydrated state. Find focused route isn't correctly typed in this case. - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - const customHistoryEntry = getCustomHistoryEntry(focusedRoute.key); - - const customHistoryParamName = SCREEN_TO_HISTORY_PARAM[focusedRoute.name as Screen]; - - if ( - // The custom history param name should be defined - typeof customHistoryParamName === 'string' && - // Params for the focused route should be defined - focusedRoute.params && - // The custom history param with given name should be defined in the params - customHistoryParamName in focusedRoute.params && - // The custom history param should be set to true - (focusedRoute.params as Record)[customHistoryParamName] && - // The last history entry should not be the custom history entry for the focused route to avoid duplication - stateWithInitialHistory.history.at(-1) !== customHistoryEntry - ) { - // Add the custom history entry to the initial history - stateWithInitialHistory.history = [...stateWithInitialHistory.history, customHistoryEntry]; - } - - return stateWithInitialHistory; - }; - - const getStateForAction = ( - state: PlatformStackNavigationState, - action: CommonActions.Action | StackActionType | HistoryStackNavigatorAction, - configOptions: RouterConfigOptions, - ) => { - // We want to set the right param and then update the history - if (isSetHistoryParamAction(action)) { - const customHistoryEntry = getCustomHistoryEntry(action.payload.key); - - // Start with updating the param. - const setParamsAction = CommonActions.setParams({[action.payload.key]: action.payload.value}); - const stateWithUpdatedParams = router.getStateForAction(state, setParamsAction, configOptions); - - // This shouldn't ever happen as the history should be always defined. It's for type safety. - if (!stateWithUpdatedParams?.history) { - return stateWithUpdatedParams; - } - - // If it's set to true, we need to add the history entry if it's not already there. - if (action.payload.value && stateWithUpdatedParams.history.at(-1) !== customHistoryEntry) { - return {...stateWithUpdatedParams, history: [...stateWithUpdatedParams.history, customHistoryEntry]}; - } - - // If it's set to false, we need to remove the history entry if it's there. - if (!action.payload.value) { - return {...stateWithUpdatedParams, history: stateWithUpdatedParams.history.filter((entry) => entry !== customHistoryEntry)}; - } - - // Else, do not change history. - return stateWithUpdatedParams; - } - - const newState = router.getStateForAction(state, action, configOptions); - - // If the action was not handled, return null. - if (!newState) { - return null; - } - - // If the action was a setParams action, we need to preserve the history. - if (isSetParamsAction(action) && state.history) { - return { - ...newState, - history: [...state.history], - }; - } - - // Handle every other action. - // @ts-expect-error newState can be partial or not. But getRehydratedState will handle it correctly even if the stale === false. - // And we need to update the history if routes have changed. - return getRehydratedState(newState, configOptions); - }; - - return { - ...router, - getInitialState, - getRehydratedState, - getStateForAction, - }; - }; -} - -export default addCustomHistoryRouterExtension; diff --git a/src/libs/Navigation/AppNavigator/customHistory/index.ts b/src/libs/Navigation/AppNavigator/customHistory/index.ts deleted file mode 100644 index cfea975fcb72a..0000000000000 --- a/src/libs/Navigation/AppNavigator/customHistory/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export {default as addCustomHistoryRouterExtension} from './addCustomHistoryRouterExtension'; -export {default as useCustomHistoryParam} from './useCustomHistoryParam'; diff --git a/src/libs/Navigation/AppNavigator/customHistory/types.ts b/src/libs/Navigation/AppNavigator/customHistory/types.ts deleted file mode 100644 index cd84971f4edf3..0000000000000 --- a/src/libs/Navigation/AppNavigator/customHistory/types.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type {CommonActions, StackActionType} from '@react-navigation/native'; -import type CONST from '@src/CONST'; - -type HistoryStackNavigatorAction = CommonActions.Action | StackActionType | HistoryStackNavigatorActionType; - -type HistoryStackNavigatorActionType = { - type: typeof CONST.NAVIGATION.ACTION_TYPE.SET_HISTORY_PARAM; - payload: { - key: string; - value: boolean; - }; -}; - -type SetHistoryParamActionType = HistoryStackNavigatorAction & { - type: typeof CONST.NAVIGATION.ACTION_TYPE.SET_HISTORY_PARAM; -}; - -export type {HistoryStackNavigatorAction, HistoryStackNavigatorActionType, SetHistoryParamActionType}; diff --git a/src/libs/Navigation/AppNavigator/customHistory/useCustomHistoryParam.ts b/src/libs/Navigation/AppNavigator/customHistory/useCustomHistoryParam.ts deleted file mode 100644 index e7f657982e721..0000000000000 --- a/src/libs/Navigation/AppNavigator/customHistory/useCustomHistoryParam.ts +++ /dev/null @@ -1,42 +0,0 @@ -import {useNavigation, useRoute} from '@react-navigation/native'; -import SCREEN_TO_HISTORY_PARAM from '@libs/Navigation/linkingConfig/RELATIONS/SCREEN_TO_HISTORY_PARAM'; -import CONST from '@src/CONST'; -import type {Screen} from '@src/SCREENS'; - -/** - * Custom hook for managing navigation history entries - * It works as useState but it pushes the history entry when the value is true. - * The value will change to false if the user navigates back with the browser back button. - * It uses screen param to store the information and make it visible in the url so the state persist after refreshing the page. - * - * @returns A tuple containing [historyParam, setHistoryParam] where: - * - historyParam: boolean | undefined - The current state of the history parameter - * - setHistoryParam: (value: boolean) => void - Function to update the history parameter - */ -function useCustomHistoryParam() { - const navigation = useNavigation(); - const route = useRoute(); - const historyParamName = SCREEN_TO_HISTORY_PARAM[route.name as Screen]; - - if (!historyParamName || typeof historyParamName !== 'string') { - throw new Error(`Screen ${route.name} does not have a history param. You can use this hook only on the screens that have one defined in SCREEN_TO_HISTORY_PARAM.`); - } - - const historyParam = route.params && (route.params as Record)[historyParamName] ? ((route.params as Record)[historyParamName] as boolean) : false; - - if (typeof historyParam !== 'boolean') { - throw new Error(`The history param ${historyParamName} is not a boolean. Make sure that you used getHistoryParamParse for this screen in linkingConfig/config.ts`); - } - - return [ - historyParam, - (value: boolean) => { - navigation.dispatch({ - type: CONST.NAVIGATION.ACTION_TYPE.SET_HISTORY_PARAM, - payload: {key: historyParamName, value}, - }); - }, - ] as const; -} - -export default useCustomHistoryParam; diff --git a/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.native.tsx b/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.native.tsx index f2b6fcf7eb320..1f3b4a4c04cea 100644 --- a/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.native.tsx +++ b/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.native.tsx @@ -3,7 +3,6 @@ import {StackRouter, useNavigationBuilder} from '@react-navigation/native'; import {NativeStackView} from '@react-navigation/native-stack'; import type {NativeStackNavigationEventMap, NativeStackNavigationOptions} from '@react-navigation/native-stack'; import React, {useMemo} from 'react'; -import {addCustomHistoryRouterExtension} from '@libs/Navigation/AppNavigator/customHistory'; import convertToNativeNavigationOptions from '@libs/Navigation/PlatformStackNavigation/navigationOptions/convertToNativeNavigationOptions'; import type { CreatePlatformStackNavigatorComponentOptions, @@ -19,7 +18,7 @@ function createPlatformStackNavigatorComponent, ) { - const createRouter = addCustomHistoryRouterExtension(options?.createRouter ?? StackRouter); + const createRouter = options?.createRouter ?? StackRouter; const defaultScreenOptions = options?.defaultScreenOptions; const useCustomState = options?.useCustomState ?? (() => undefined); const useCustomEffects = options?.useCustomEffects ?? (() => undefined); diff --git a/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.tsx b/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.tsx index e98de444ad714..fa45e5834aaa6 100644 --- a/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.tsx +++ b/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.tsx @@ -3,7 +3,6 @@ import {StackRouter, useNavigationBuilder} from '@react-navigation/native'; import type {StackNavigationEventMap, StackNavigationOptions} from '@react-navigation/stack'; import {StackView} from '@react-navigation/stack'; import React, {useMemo} from 'react'; -import {addCustomHistoryRouterExtension} from '@libs/Navigation/AppNavigator/customHistory'; import convertToWebNavigationOptions from '@libs/Navigation/PlatformStackNavigation/navigationOptions/convertToWebNavigationOptions'; import type { CreatePlatformStackNavigatorComponentOptions, @@ -19,7 +18,7 @@ function createPlatformStackNavigatorComponent, ) { - const createRouter = addCustomHistoryRouterExtension(options?.createRouter ?? StackRouter); + const createRouter = options?.createRouter ?? StackRouter; const useCustomState = options?.useCustomState ?? (() => undefined); const defaultScreenOptions = options?.defaultScreenOptions; const ExtraContent = options?.ExtraContent; diff --git a/src/libs/Navigation/linkingConfig/HISTORY_PARAM.ts b/src/libs/Navigation/linkingConfig/HISTORY_PARAM.ts deleted file mode 100644 index 9ea2bc1aa1855..0000000000000 --- a/src/libs/Navigation/linkingConfig/HISTORY_PARAM.ts +++ /dev/null @@ -1,5 +0,0 @@ -const HISTORY_PARAM = { - SHOW_VALIDATE_CODE_ACTION_MODAL: 'showValidateActionModal', -} as const; - -export default HISTORY_PARAM; diff --git a/src/libs/Navigation/linkingConfig/RELATIONS/SCREEN_TO_HISTORY_PARAM.ts b/src/libs/Navigation/linkingConfig/RELATIONS/SCREEN_TO_HISTORY_PARAM.ts deleted file mode 100644 index 356dc2e49ccd0..0000000000000 --- a/src/libs/Navigation/linkingConfig/RELATIONS/SCREEN_TO_HISTORY_PARAM.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type {NavigatorScreenParams} from '@react-navigation/native'; -import HISTORY_PARAM from '@libs/Navigation/linkingConfig/HISTORY_PARAM'; -import type {RootNavigatorParamList} from '@libs/Navigation/types'; -import type {Screen} from '@src/SCREENS'; -import SCREENS from '@src/SCREENS'; - -type DeepPairsOf = DeepPairsForScreen; - -type DeepPairsForScreen = Key extends keyof ParamList ? (ParamList[Key] extends NavigatorScreenParams ? DeepPairsOf : [Key, keyof ParamList[Key]]) : never; - -type DeepPairsOfRoot = DeepPairsOf; - -type ScreenToHistoryParamMap = Partial<{ - [TScreen in Screen]: Extract[1]; -}>; - -// This file maps screens to their history parameters -const SCREEN_TO_HISTORY_PARAM: ScreenToHistoryParamMap = { - [SCREENS.SETTINGS.DELEGATE.DELEGATE_CONFIRM]: HISTORY_PARAM.SHOW_VALIDATE_CODE_ACTION_MODAL, -}; - -export default SCREEN_TO_HISTORY_PARAM; diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 10d26086e9429..b018ac8b514ff 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -6,8 +6,6 @@ import NAVIGATORS from '@src/NAVIGATORS'; import ROUTES from '@src/ROUTES'; import type {Screen} from '@src/SCREENS'; import SCREENS from '@src/SCREENS'; -import getHistoryParamParse from './helpers/getHistoryParamParse'; -import HISTORY_PARAM from './HISTORY_PARAM'; // Moved to a separate file to avoid cyclic dependencies. const config: LinkingOptions['config'] = { @@ -323,7 +321,6 @@ const config: LinkingOptions['config'] = { path: ROUTES.SETTINGS_DELEGATE_CONFIRM.route, parse: { login: (login: string) => decodeURIComponent(login), - ...getHistoryParamParse(HISTORY_PARAM.SHOW_VALIDATE_CODE_ACTION_MODAL), }, }, [SCREENS.SETTINGS.PROFILE.STATUS]: { diff --git a/src/libs/Navigation/linkingConfig/helpers/getHistoryParamParse.ts b/src/libs/Navigation/linkingConfig/helpers/getHistoryParamParse.ts deleted file mode 100644 index 7bae4da41012d..0000000000000 --- a/src/libs/Navigation/linkingConfig/helpers/getHistoryParamParse.ts +++ /dev/null @@ -1,5 +0,0 @@ -const getHistoryParamParse = (historyParamName: string) => ({ - [historyParamName]: (value: string) => value === 'true', -}); - -export default getHistoryParamParse; diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 023c5c999cea1..595349b683ed1 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -2143,6 +2143,5 @@ export type { TestDriveModalNavigatorParamList, WorkspaceScreenName, TestDriveDemoNavigatorParamList, - SetParamsAction, WorkspacesTabNavigatorName, }; diff --git a/src/pages/settings/Security/AddDelegate/ConfirmDelegatePage.tsx b/src/pages/settings/Security/AddDelegate/ConfirmDelegatePage.tsx index ec4c275a7f0ac..da6b3dd558ea9 100644 --- a/src/pages/settings/Security/AddDelegate/ConfirmDelegatePage.tsx +++ b/src/pages/settings/Security/AddDelegate/ConfirmDelegatePage.tsx @@ -1,4 +1,4 @@ -import React, {useState} from 'react'; +import React, {useEffect, useState} from 'react'; import type {ValueOf} from 'type-fest'; import Button from '@components/Button'; import DelegateNoAccessWrapper from '@components/DelegateNoAccessWrapper'; @@ -13,7 +13,6 @@ import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import {formatPhoneNumber} from '@libs/LocalePhoneNumber'; -import {useCustomHistoryParam} from '@libs/Navigation/AppNavigator/customHistory'; import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; @@ -25,17 +24,21 @@ import DelegateMagicCodeModal from './DelegateMagicCodeModal'; type ConfirmDelegatePageProps = PlatformStackScreenProps; -function ConfirmDelegatePage({route}: ConfirmDelegatePageProps) { +function ConfirmDelegatePage({route, navigation}: ConfirmDelegatePageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const login = route.params.login; const role = route.params.role as ValueOf; + const showValidateActionModal = route.params.showValidateActionModal === 'true'; const {isOffline} = useNetwork(); const [shouldDisableModalAnimation, setShouldDisableModalAnimation] = useState(true); + const [shouldShowLoading, setShouldShowLoading] = useState(showValidateActionModal ?? false); - const [isValidateCodeActionModalVisible, setIsValidateCodeActionModalVisible] = useCustomHistoryParam(); - const [shouldShowLoading, setShouldShowLoading] = useState(isValidateCodeActionModalVisible ?? false); + const [isValidateCodeActionModalVisible, setIsValidateCodeActionModalVisible] = useState(showValidateActionModal ?? false); + useEffect(() => { + navigation.setParams({showValidateActionModal: String(isValidateCodeActionModalVisible)}); + }, [isValidateCodeActionModalVisible, navigation]); const personalDetails = getPersonalDetailByEmail(login); const avatarIcon = personalDetails?.avatar ?? FallbackAvatar; @@ -90,6 +93,7 @@ function ConfirmDelegatePage({route}: ConfirmDelegatePageProps) { // We should disable the animation initially and only enable it when the user manually opens the modal // to ensure it appears immediately when refreshing the page. disableAnimation={shouldDisableModalAnimation} + shouldHandleNavigationBack login={login} role={role} onClose={() => {