diff --git a/src/components/Navigation/BottomTabBar/index.tsx b/src/components/Navigation/BottomTabBar/index.tsx index 148a3b3b8338..ec8308a4218e 100644 --- a/src/components/Navigation/BottomTabBar/index.tsx +++ b/src/components/Navigation/BottomTabBar/index.tsx @@ -18,14 +18,14 @@ import useThemeStyles from '@hooks/useThemeStyles'; import clearSelectedText from '@libs/clearSelectedText/clearSelectedText'; import getPlatform from '@libs/getPlatform'; import interceptAnonymousUser from '@libs/interceptAnonymousUser'; -import {buildCannedSearchQuery} from '@libs/SearchQueryUtils'; +import {getPreservedNavigatorState} from '@libs/Navigation/AppNavigator/createSplitNavigator/usePreserveNavigatorState'; +import {buildCannedSearchQuery, buildSearchQueryJSON, buildSearchQueryString} from '@libs/SearchQueryUtils'; import type {BrickRoad} from '@libs/WorkspacesSettingsUtils'; import {getChatTabBrickRoad} from '@libs/WorkspacesSettingsUtils'; -import {getPreservedSplitNavigatorState} from '@navigation/AppNavigator/createSplitNavigator/usePreserveSplitNavigatorState'; import {isFullScreenName} from '@navigation/helpers/isNavigatorName'; import Navigation from '@navigation/Navigation'; import navigationRef from '@navigation/navigationRef'; -import type {WorkspaceSplitNavigatorParamList} from '@navigation/types'; +import type {RootNavigatorParamList, SearchFullscreenNavigatorParamList, State, WorkspaceSplitNavigatorParamList} from '@navigation/types'; import BottomTabAvatar from '@pages/home/sidebar/BottomTabAvatar'; import BottomTabBarFloatingActionButton from '@pages/home/sidebar/BottomTabBarFloatingActionButton'; import variables from '@styles/variables'; @@ -79,6 +79,27 @@ function BottomTabBar({selectedTab, isTooltipAllowed = false}: BottomTabBarProps clearSelectedText(); interceptAnonymousUser(() => { const defaultCannedQuery = buildCannedSearchQuery(); + + const rootState = navigationRef.getRootState() as State; + const lastSearchNavigator = rootState.routes.findLast((route) => route.name === NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR); + const lastSearchNavigatorState = lastSearchNavigator && lastSearchNavigator.key ? getPreservedNavigatorState(lastSearchNavigator?.key) : undefined; + const lastSearchRoute = lastSearchNavigatorState?.routes.findLast((route) => route.name === SCREENS.SEARCH.ROOT); + + if (lastSearchRoute) { + const {q, ...rest} = lastSearchRoute.params as SearchFullscreenNavigatorParamList[typeof SCREENS.SEARCH.ROOT]; + const queryJSON = buildSearchQueryJSON(q); + if (queryJSON) { + queryJSON.policyID = activeWorkspaceID; + const query = buildSearchQueryString(queryJSON); + Navigation.navigate( + ROUTES.SEARCH_ROOT.getRoute({ + query, + ...rest, + }), + ); + return; + } + } // when navigating to search we might have an activePolicyID set from workspace switcher const query = activeWorkspaceID ? `${defaultCannedQuery} ${CONST.SEARCH.SYNTAX_ROOT_KEYS.POLICY_ID}:${activeWorkspaceID}` : defaultCannedQuery; Navigation.navigate(ROUTES.SEARCH_ROOT.getRoute({query})); @@ -122,7 +143,7 @@ function BottomTabBar({selectedTab, isTooltipAllowed = false}: BottomTabBarProps return; } - const state = lastSettingsOrWorkspaceNavigatorRoute.state ?? getPreservedSplitNavigatorState(lastSettingsOrWorkspaceNavigatorRoute.key); + const state = lastSettingsOrWorkspaceNavigatorRoute.state ?? getPreservedNavigatorState(lastSettingsOrWorkspaceNavigatorRoute.key); // If there is a workspace navigator route, then we should open the workspace initial screen as it should be "remembered". if (lastSettingsOrWorkspaceNavigatorRoute.name === NAVIGATORS.WORKSPACE_SPLIT_NAVIGATOR) { diff --git a/src/libs/Navigation/AppNavigator/Navigators/SearchFullscreenNavigator.tsx b/src/libs/Navigation/AppNavigator/Navigators/SearchFullscreenNavigator.tsx index 4f8e4478e189..9f06a946c80a 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/SearchFullscreenNavigator.tsx +++ b/src/libs/Navigation/AppNavigator/Navigators/SearchFullscreenNavigator.tsx @@ -1,10 +1,11 @@ import React from 'react'; -import type {PlatformStackNavigationOptions} from '@libs/Navigation/PlatformStackNavigation/types'; -import type {SearchFullscreenNavigatorParamList} from '@libs/Navigation/types'; +import type {PlatformStackNavigationOptions, PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; +import type {AuthScreensParamList, SearchFullscreenNavigatorParamList} from '@libs/Navigation/types'; import * as SearchQueryUtils from '@libs/SearchQueryUtils'; import createSearchFullscreenNavigator from '@navigation/AppNavigator/createSearchFullscreenNavigator'; import FreezeWrapper from '@navigation/AppNavigator/FreezeWrapper'; import useRootNavigatorScreenOptions from '@navigation/AppNavigator/useRootNavigatorScreenOptions'; +import type NAVIGATORS from '@src/NAVIGATORS'; import SCREENS from '@src/SCREENS'; import type ReactComponentModule from '@src/types/utils/ReactComponentModule'; @@ -13,9 +14,8 @@ const loadSearchMoneyReportPage = () => require('@pages/Se const Stack = createSearchFullscreenNavigator(); -function SearchFullscreenNavigator() { +function SearchFullscreenNavigator({route}: PlatformStackScreenProps) { const rootNavigatorScreenOptions = useRootNavigatorScreenOptions(); - const searchRootScreenOptions: PlatformStackNavigationOptions = { ...rootNavigatorScreenOptions.fullScreen, web: { @@ -23,12 +23,12 @@ function SearchFullscreenNavigator() { cardStyleInterpolator: undefined, }, }; - return ( | PartialState>; @@ -73,7 +73,7 @@ function adaptStateIfNecessary({state, options: {sidebarScreen, defaultCentralSc const previousSameNavigator = rootState?.routes.filter((route) => route.name === parentRoute.name).at(-2); // If we have optimization for not rendering all split navigators, then last selected option may not be in the state. In this case state has to be read from the preserved state. - const previousSameNavigatorState = previousSameNavigator?.state ?? (previousSameNavigator?.key ? getPreservedSplitNavigatorState(previousSameNavigator.key) : undefined); + const previousSameNavigatorState = previousSameNavigator?.state ?? (previousSameNavigator?.key ? getPreservedNavigatorState(previousSameNavigator.key) : undefined); const previousSelectedCentralScreen = previousSameNavigatorState?.routes && previousSameNavigatorState.routes.length > 1 ? previousSameNavigatorState.routes.at(-1)?.name : undefined; @@ -113,7 +113,7 @@ function SplitRouter(options: SplitNavigatorRouterOptions) { return stackRouter.getStateForAction(state, action, configOptions); }, getInitialState({routeNames, routeParamList, routeGetIdList}: RouterConfigOptions) { - const preservedState = getPreservedSplitNavigatorState(options.parentRoute.key); + const preservedState = getPreservedNavigatorState(options.parentRoute.key); const initialState = preservedState ?? stackRouter.getInitialState({routeNames, routeParamList, routeGetIdList}); adaptStateIfNecessary({ diff --git a/src/libs/Navigation/AppNavigator/createSplitNavigator/index.tsx b/src/libs/Navigation/AppNavigator/createSplitNavigator/index.tsx index 8a943b40425a..0771da8c55f4 100644 --- a/src/libs/Navigation/AppNavigator/createSplitNavigator/index.tsx +++ b/src/libs/Navigation/AppNavigator/createSplitNavigator/index.tsx @@ -13,11 +13,11 @@ import type { } from '@libs/Navigation/PlatformStackNavigation/types'; import SidebarSpacerWrapper from './SidebarSpacerWrapper'; import SplitRouter from './SplitRouter'; -import usePreserveSplitNavigatorState from './usePreserveSplitNavigatorState'; +import usePreserveNavigatorState from './usePreserveNavigatorState'; function useCustomEffects(props: CustomEffectsHookProps) { useNavigationResetOnLayoutChange(props); - usePreserveSplitNavigatorState(props.state, props.parentRoute); + usePreserveNavigatorState(props.state, props.parentRoute); } function useCustomSplitNavigatorState({state}: CustomStateHookProps) { diff --git a/src/libs/Navigation/AppNavigator/createSplitNavigator/usePreserveNavigatorState.ts b/src/libs/Navigation/AppNavigator/createSplitNavigator/usePreserveNavigatorState.ts new file mode 100644 index 000000000000..8cbd48f5a98e --- /dev/null +++ b/src/libs/Navigation/AppNavigator/createSplitNavigator/usePreserveNavigatorState.ts @@ -0,0 +1,29 @@ +import type {NavigationState, ParamListBase, RouteProp, StackNavigationState} from '@react-navigation/native'; +import {useEffect} from 'react'; + +const preservedNavigatorStates: Record> = {}; + +const cleanPreservedNavigatorStates = (state: NavigationState) => { + const currentSplitNavigatorKeys = state.routes.map((route) => route.key); + + for (const key of Object.keys(preservedNavigatorStates)) { + if (!currentSplitNavigatorKeys.includes(key)) { + delete preservedNavigatorStates[key]; + } + } +}; + +const getPreservedNavigatorState = (key: string) => preservedNavigatorStates[key]; + +function usePreserveNavigatorState(state: StackNavigationState, route: RouteProp | undefined) { + useEffect(() => { + if (!route) { + return; + } + preservedNavigatorStates[route.key] = state; + }, [route, state]); +} + +export default usePreserveNavigatorState; + +export {getPreservedNavigatorState, cleanPreservedNavigatorStates}; diff --git a/src/libs/Navigation/AppNavigator/createSplitNavigator/usePreserveSplitNavigatorState.ts b/src/libs/Navigation/AppNavigator/createSplitNavigator/usePreserveSplitNavigatorState.ts deleted file mode 100644 index 789fc27d81fe..000000000000 --- a/src/libs/Navigation/AppNavigator/createSplitNavigator/usePreserveSplitNavigatorState.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type {NavigationState, ParamListBase, RouteProp, StackNavigationState} from '@react-navigation/native'; -import {useEffect} from 'react'; - -const preservedSplitNavigatorStates: Record> = {}; - -const cleanPreservedSplitNavigatorStates = (state: NavigationState) => { - const currentSplitNavigatorKeys = state.routes.map((route) => route.key); - - for (const key of Object.keys(preservedSplitNavigatorStates)) { - if (!currentSplitNavigatorKeys.includes(key)) { - delete preservedSplitNavigatorStates[key]; - } - } -}; - -const getPreservedSplitNavigatorState = (key: string) => preservedSplitNavigatorStates[key]; - -function usePreserveSplitNavigatorState(state: StackNavigationState, route: RouteProp | undefined) { - useEffect(() => { - if (!route) { - return; - } - preservedSplitNavigatorStates[route.key] = state; - }, [route, state]); -} - -export default usePreserveSplitNavigatorState; - -export {getPreservedSplitNavigatorState, cleanPreservedSplitNavigatorStates}; diff --git a/src/libs/Navigation/NavigationRoot.tsx b/src/libs/Navigation/NavigationRoot.tsx index 71cddba6b221..e5a878031c8a 100644 --- a/src/libs/Navigation/NavigationRoot.tsx +++ b/src/libs/Navigation/NavigationRoot.tsx @@ -25,7 +25,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; import AppNavigator from './AppNavigator'; -import {cleanPreservedSplitNavigatorStates} from './AppNavigator/createSplitNavigator/usePreserveSplitNavigatorState'; +import {cleanPreservedNavigatorStates} from './AppNavigator/createSplitNavigator/usePreserveNavigatorState'; import customGetPathFromState from './helpers/customGetPathFromState'; import getAdaptedStateFromPath from './helpers/getAdaptedStateFromPath'; import {linkingConfig} from './linkingConfig'; @@ -209,7 +209,7 @@ function NavigationRoot({authenticated, lastVisitedPath, initialUrl, onReady, sh // We want to clean saved scroll offsets for screens that aren't anymore in the state. cleanStaleScrollOffsets(state); - cleanPreservedSplitNavigatorStates(state); + cleanPreservedNavigatorStates(state); }; return ( diff --git a/src/pages/home/sidebar/BaseSidebarScreen.tsx b/src/pages/home/sidebar/BaseSidebarScreen.tsx index 6ee621d321ee..b5c1fbe9ce5b 100644 --- a/src/pages/home/sidebar/BaseSidebarScreen.tsx +++ b/src/pages/home/sidebar/BaseSidebarScreen.tsx @@ -13,7 +13,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import {updateLastAccessedWorkspace} from '@libs/actions/Policy/Policy'; import {isMobile} from '@libs/Browser'; import getInitialSplitNavigatorState from '@libs/Navigation/AppNavigator/createSplitNavigator/getInitialSplitNavigatorState'; -import {getPreservedSplitNavigatorState} from '@libs/Navigation/AppNavigator/createSplitNavigator/usePreserveSplitNavigatorState'; +import {getPreservedNavigatorState} from '@libs/Navigation/AppNavigator/createSplitNavigator/usePreserveNavigatorState'; import getTopmostReportsSplitNavigator from '@libs/Navigation/helpers/getTopmostReportsSplitNavigator'; import Navigation from '@libs/Navigation/Navigation'; import Performance from '@libs/Performance'; @@ -48,7 +48,7 @@ function BaseSidebarScreen() { } // Switching workspace to global should only be performed from the currently opened sidebar screen - const topmostReportSplitState = topmostReportSplit?.state ?? getPreservedSplitNavigatorState(topmostReportSplit?.key); + const topmostReportSplitState = topmostReportSplit?.state ?? getPreservedNavigatorState(topmostReportSplit?.key); const isCurrentSidebar = topmostReportSplitState?.routes.some((route) => currentRoute.key === route.key); if (!isCurrentSidebar) {