From 990516c865730a320d4ce35c9980a9dd5fcccb89 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Wed, 17 Jul 2024 17:38:06 +0200 Subject: [PATCH 1/5] Add createScreenNameChecker --- src/components/Search/index.tsx | 4 +- .../Navigators/BottomTabNavigator.tsx | 4 +- .../BottomTabBar/index.website.tsx | 12 ++-- src/libs/NavigationUtils.ts | 69 ++++++------------- src/libs/SearchUtils.ts | 6 +- 5 files changed, 36 insertions(+), 59 deletions(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index 78992496f031..a9142127f248 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -116,9 +116,9 @@ function Search({query, policyIDs, sortBy, sortOrder, isMobileSelectionModeActiv ); } - const shouldShowEmptyState = searchResults && SearchUtils.isSearchResultsEmpty(searchResults); + const shouldShowEmptyState = SearchUtils.isSearchResultsEmpty(searchResults); - if (shouldShowEmptyState ?? !searchResults) { + if (shouldShowEmptyState) { return ( <> | undefined; for (const selector of [getTopmostBottomTabRoute, getTopmostCentralPaneRoute]) { const selectedRoute = selector(state); - if (isBottomTabName(selectedRoute?.name)) { + if (isTabScreenName(selectedRoute?.name)) { route = selectedRoute as NavigationPartialRoute; } } diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar/index.website.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar/index.website.tsx index 556365b473c3..0f98f37e8699 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar/index.website.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar/index.website.tsx @@ -3,7 +3,6 @@ import React, {useCallback, useEffect} from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; -import type {TupleToUnion} from 'type-fest'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import {PressableWithFeedback} from '@components/Pressable'; @@ -19,7 +18,7 @@ import getTopmostBottomTabRoute from '@libs/Navigation/getTopmostBottomTabRoute' import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRoute'; import Navigation from '@libs/Navigation/Navigation'; import type {RootStackParamList, State} from '@libs/Navigation/types'; -import {isCentralPaneName, isHomeTabName, isSearchTabName, isSettingTabName} from '@libs/NavigationUtils'; +import {isCentralPaneName, isHomeTab, isSearchTab, isSettingsTab} from '@libs/NavigationUtils'; import {getChatTabBrickRoad} from '@libs/WorkspacesSettingsUtils'; import BottomTabAvatar from '@pages/home/sidebar/BottomTabAvatar'; import BottomTabBarFloatingActionButton from '@pages/home/sidebar/BottomTabBarFloatingActionButton'; @@ -42,7 +41,6 @@ function BottomTabBar({isLoadingApp = false}: PurposeForUsingExpensifyModalProps const styles = useThemeStyles(); const {translate} = useLocalize(); const navigation = useNavigation(); - const HOME_SCREENS = [SCREENS.HOME, SCREENS.REPORT]; const {activeWorkspaceID: contextActiveWorkspaceID} = useActiveWorkspace(); const activeWorkspaceID = sessionStorage.getItem(CONST.SESSION_STORAGE_KEYS.ACTIVE_WORKSPACE_ID) ?? contextActiveWorkspaceID; @@ -96,7 +94,7 @@ function BottomTabBar({isLoadingApp = false}: PurposeForUsingExpensifyModalProps ) ? theme.iconMenu : theme.icon} + fill={isHomeTab(activeBottomTabRoute?.name) ? theme.iconMenu : theme.icon} width={variables.iconBottomBar} height={variables.iconBottomBar} /> @@ -109,7 +107,7 @@ function BottomTabBar({isLoadingApp = false}: PurposeForUsingExpensifyModalProps { - if (isSearchTabName(activeBottomTabRoute?.name)) { + if (isSearchTab(activeBottomTabRoute?.name)) { return; } interceptAnonymousUser(() => Navigation.navigate(ROUTES.SEARCH.getRoute(CONST.SEARCH.TAB.ALL))); @@ -122,14 +120,14 @@ function BottomTabBar({isLoadingApp = false}: PurposeForUsingExpensifyModalProps - + diff --git a/src/libs/NavigationUtils.ts b/src/libs/NavigationUtils.ts index 34e9df954688..93d11d00345b 100644 --- a/src/libs/NavigationUtils.ts +++ b/src/libs/NavigationUtils.ts @@ -1,6 +1,4 @@ import cloneDeep from 'lodash/cloneDeep'; -import type {TupleToUnion} from 'type-fest'; -import {flattenObject} from '@src/languages/translations'; import SCREENS from '@src/SCREENS'; import getTopmostBottomTabRoute from './Navigation/getTopmostBottomTabRoute'; import type {CentralPaneName, RootStackParamList, State} from './Navigation/types'; @@ -19,14 +17,6 @@ const CENTRAL_PANE_SCREEN_NAMES = new Set([ SCREENS.REPORT, ]); -function isCentralPaneName(screen: string | undefined): screen is CentralPaneName { - if (!screen) { - return false; - } - - return CENTRAL_PANE_SCREEN_NAMES.has(screen as CentralPaneName); -} - const removePolicyIDParamFromState = (state: State) => { const stateCopy = cloneDeep(state); const bottomTabRoute = getTopmostBottomTabRoute(stateCopy); @@ -36,43 +26,28 @@ const removePolicyIDParamFromState = (state: State) => { return stateCopy; }; -const SETTINGS_SCREENS = Object.values(flattenObject(SCREENS.SETTINGS)); -const SEARCH_SCREENS = Object.values(flattenObject(SCREENS.SEARCH)); -const HOME_SCREENS = [SCREENS.HOME, SCREENS.REPORT]; -const BOTTOM_TAB_SCREEN_NAMES = new Set([...SETTINGS_SCREENS, ...SEARCH_SCREENS, ...HOME_SCREENS]); - -const SETTINGS_TAB_SCREEN_NAMES = new Set(SETTINGS_SCREENS); - -const SEARCH_TAB_SCREEN_NAMES = new Set(SEARCH_SCREENS); - -const HOME_SCREEN_NAMES = new Set(HOME_SCREENS); - -function isBottomTabName(screen: TupleToUnion | undefined) { - if (!screen) { - return false; - } - return BOTTOM_TAB_SCREEN_NAMES.has(screen); +const TAB_SETTINGS_SCREENS = [SCREENS.SETTINGS.ROOT]; +const TAB_SEARCH_SCREENS = [SCREENS.SEARCH.BOTTOM_TAB, SCREENS.SEARCH.CENTRAL_PANE]; +const TAB_CHAT_SCREENS = [SCREENS.HOME]; + +const TAB_SCREEN_NAMES = new Set([...TAB_SETTINGS_SCREENS, ...TAB_SEARCH_SCREENS, ...TAB_CHAT_SCREENS]); +const TAB_SETTINGS_SCREEN_NAMES = new Set(TAB_SETTINGS_SCREENS); +const TAB_SEARCH_SCREEN_NAMES = new Set(TAB_SEARCH_SCREENS); +const TAB_CHAT_SCREEN_NAMES = new Set(TAB_CHAT_SCREENS); + +function createScreenNameChecker(screenNames: Set) { + return function (screen: string | undefined): screen is ScreenName { + if (!screen) { + return false; + } + return screenNames.has(screen); + }; } -function isSettingTabName(screen: TupleToUnion | undefined) { - if (!screen) { - return false; - } - return SETTINGS_TAB_SCREEN_NAMES.has(screen); -} - -function isSearchTabName(screen: TupleToUnion | undefined) { - if (!screen) { - return false; - } - return SEARCH_TAB_SCREEN_NAMES.has(screen); -} - -function isHomeTabName(screen: TupleToUnion | undefined) { - if (!screen) { - return false; - } - return HOME_SCREEN_NAMES.has(screen); -} +const isTabScreenName = createScreenNameChecker(TAB_SCREEN_NAMES); +const isSettingsTab = createScreenNameChecker(TAB_SETTINGS_SCREEN_NAMES); +const isSearchTab = createScreenNameChecker(TAB_SEARCH_SCREEN_NAMES); +const isHomeTab = createScreenNameChecker(TAB_CHAT_SCREEN_NAMES); +const isCentralPaneName = createScreenNameChecker(CENTRAL_PANE_SCREEN_NAMES); -export {isCentralPaneName, isBottomTabName, isSearchTabName, isSettingTabName, isHomeTabName, removePolicyIDParamFromState}; +export {isTabScreenName, isCentralPaneName, isSearchTab, isHomeTab, isSettingsTab, removePolicyIDParamFromState}; diff --git a/src/libs/SearchUtils.ts b/src/libs/SearchUtils.ts index 4ec3fa9fb314..1b0f09137180 100644 --- a/src/libs/SearchUtils.ts +++ b/src/libs/SearchUtils.ts @@ -304,7 +304,11 @@ function getSearchParams() { return topmostCentralPaneRoute?.params as AuthScreensParamList['Search_Central_Pane']; } -function isSearchResultsEmpty(searchResults: SearchResults) { +function isSearchResultsEmpty(searchResults: SearchResults | undefined): searchResults is undefined { + if (!searchResults) { + return true; + } + return !Object.keys(searchResults?.data).some((key) => key.startsWith(ONYXKEYS.COLLECTION.TRANSACTION)); } From 01da307a2bca1bb22f62a0ffdf56ae7367a7076a Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Thu, 18 Jul 2024 11:08:27 +0200 Subject: [PATCH 2/5] Replace useActiveBottomTabRoute with useActiveCentralPaneRoute --- src/hooks/useActiveBottomTabRoute.ts | 8 - src/hooks/useActiveCentralPaneRoute.ts | 9 ++ .../ActiveCentralPaneRouteContext.ts | 6 + .../Navigators/BottomTabNavigator.tsx | 25 +-- .../BottomTabBar/index.tsx | 48 ++---- .../BottomTabBar/index.website.tsx | 144 ------------------ .../createCustomBottomTabNavigator/index.tsx | 3 +- src/libs/NavigationUtils.ts | 29 +--- src/pages/Search/SearchPageBottomTab.tsx | 10 +- src/pages/settings/InitialSettingsPage.tsx | 10 +- 10 files changed, 52 insertions(+), 240 deletions(-) delete mode 100644 src/hooks/useActiveBottomTabRoute.ts create mode 100644 src/hooks/useActiveCentralPaneRoute.ts create mode 100644 src/libs/Navigation/AppNavigator/Navigators/ActiveCentralPaneRouteContext.ts delete mode 100644 src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar/index.website.tsx diff --git a/src/hooks/useActiveBottomTabRoute.ts b/src/hooks/useActiveBottomTabRoute.ts deleted file mode 100644 index 434cca0cd815..000000000000 --- a/src/hooks/useActiveBottomTabRoute.ts +++ /dev/null @@ -1,8 +0,0 @@ -import {useContext} from 'react'; -import ActiveBottomTabRouteContext from '@libs/Navigation/AppNavigator/Navigators/ActiveBottomTabRouteContext'; - -function useActiveBottomTabRoute() { - return useContext(ActiveBottomTabRouteContext); -} - -export default useActiveBottomTabRoute; diff --git a/src/hooks/useActiveCentralPaneRoute.ts b/src/hooks/useActiveCentralPaneRoute.ts new file mode 100644 index 000000000000..05354e810c3d --- /dev/null +++ b/src/hooks/useActiveCentralPaneRoute.ts @@ -0,0 +1,9 @@ +import {useContext} from 'react'; +import ActiveCentralPaneRouteContext from '@libs/Navigation/AppNavigator/Navigators/ActiveCentralPaneRouteContext'; +import type {AuthScreensParamList, NavigationPartialRoute} from '@libs/Navigation/types'; + +function useActiveCentralPaneRoute(): NavigationPartialRoute | undefined { + return useContext(ActiveCentralPaneRouteContext); +} + +export default useActiveCentralPaneRoute; diff --git a/src/libs/Navigation/AppNavigator/Navigators/ActiveCentralPaneRouteContext.ts b/src/libs/Navigation/AppNavigator/Navigators/ActiveCentralPaneRouteContext.ts new file mode 100644 index 000000000000..6f37126584a2 --- /dev/null +++ b/src/libs/Navigation/AppNavigator/Navigators/ActiveCentralPaneRouteContext.ts @@ -0,0 +1,6 @@ +import React from 'react'; +import type {AuthScreensParamList, NavigationPartialRoute} from '@libs/Navigation/types'; + +const ActiveCentralPaneRouteContext = React.createContext | undefined>(undefined); + +export default ActiveCentralPaneRouteContext; diff --git a/src/libs/Navigation/AppNavigator/Navigators/BottomTabNavigator.tsx b/src/libs/Navigation/AppNavigator/Navigators/BottomTabNavigator.tsx index 559c4f820017..30e8d4c668c6 100644 --- a/src/libs/Navigation/AppNavigator/Navigators/BottomTabNavigator.tsx +++ b/src/libs/Navigation/AppNavigator/Navigators/BottomTabNavigator.tsx @@ -2,15 +2,13 @@ import {useNavigationState} from '@react-navigation/native'; import type {StackNavigationOptions} from '@react-navigation/stack'; import React from 'react'; import createCustomBottomTabNavigator from '@libs/Navigation/AppNavigator/createCustomBottomTabNavigator'; -import getTopmostBottomTabRoute from '@libs/Navigation/getTopmostBottomTabRoute'; import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRoute'; -import type {BottomTabNavigatorParamList, BottomTabScreensParamList, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types'; -import {isTabScreenName} from '@libs/NavigationUtils'; +import type {BottomTabNavigatorParamList, CentralPaneName, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types'; import SidebarScreen from '@pages/home/sidebar/SidebarScreen'; import SearchPageBottomTab from '@pages/Search/SearchPageBottomTab'; import SCREENS from '@src/SCREENS'; import type ReactComponentModule from '@src/types/utils/ReactComponentModule'; -import ActiveBottomTabRouteContext from './ActiveBottomTabRouteContext'; +import ActiveCentralPaneRouteContext from './ActiveCentralPaneRouteContext'; const loadInitialSettingsPage = () => require('../../../../pages/settings/InitialSettingsPage').default; const Tab = createCustomBottomTabNavigator(); @@ -21,22 +19,9 @@ const screenOptions: StackNavigationOptions = { }; function BottomTabNavigator() { - const activeRoute = useNavigationState | undefined>((state) => { - if (!state) { - return undefined; - } - let route: NavigationPartialRoute | undefined; - for (const selector of [getTopmostBottomTabRoute, getTopmostCentralPaneRoute]) { - const selectedRoute = selector(state); - if (isTabScreenName(selectedRoute?.name)) { - route = selectedRoute as NavigationPartialRoute; - } - } - - return route; - }); + const activeRoute = useNavigationState | undefined>(getTopmostCentralPaneRoute); return ( - + - + ); } diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar/index.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar/index.tsx index f244342c28ae..1ee25b45d331 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar/index.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar/index.tsx @@ -1,8 +1,7 @@ -import {useNavigation, useNavigationState} from '@react-navigation/native'; +import {useNavigation} from '@react-navigation/native'; import React, {memo, useCallback, useEffect} from 'react'; import {NativeModules, View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; -import {withOnyx} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import {PressableWithFeedback} from '@components/Pressable'; @@ -13,8 +12,6 @@ import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import * as Session from '@libs/actions/Session'; import interceptAnonymousUser from '@libs/interceptAnonymousUser'; -import getTopmostBottomTabRoute from '@libs/Navigation/getTopmostBottomTabRoute'; -import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRoute'; import Navigation from '@libs/Navigation/Navigation'; import type {RootStackParamList, State} from '@libs/Navigation/types'; import {isCentralPaneName} from '@libs/NavigationUtils'; @@ -30,17 +27,17 @@ import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; -type PurposeForUsingExpensifyModalOnyxProps = { - isLoadingApp: OnyxEntry; +type BottomTabBarProps = { + selectedTab: string | undefined; }; -type PurposeForUsingExpensifyModalProps = PurposeForUsingExpensifyModalOnyxProps; -function BottomTabBar({isLoadingApp = false}: PurposeForUsingExpensifyModalProps) { +function BottomTabBar({selectedTab}: BottomTabBarProps) { const theme = useTheme(); const styles = useThemeStyles(); const {translate} = useLocalize(); const navigation = useNavigation(); const {activeWorkspaceID} = useActiveWorkspace(); + const [isLoadingApp] = useOnyx(ONYXKEYS.IS_LOADING_APP); useEffect(() => { const navigationState = navigation.getState() as State | undefined; @@ -61,27 +58,14 @@ function BottomTabBar({isLoadingApp = false}: PurposeForUsingExpensifyModalProps // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps }, [isLoadingApp]); - // Parent navigator of the bottom tab bar is the root navigator. - const currentTabName = useNavigationState((state) => { - const topmostCentralPaneRoute = getTopmostCentralPaneRoute(state); - - if (topmostCentralPaneRoute && topmostCentralPaneRoute.name === SCREENS.SEARCH.CENTRAL_PANE) { - return SCREENS.SEARCH.CENTRAL_PANE; - } - - const topmostBottomTabRoute = getTopmostBottomTabRoute(state); - return topmostBottomTabRoute?.name ?? SCREENS.HOME; - }); - const chatTabBrickRoad = getChatTabBrickRoad(activeWorkspaceID); - const navigateToChats = useCallback(() => { - if (currentTabName === SCREENS.HOME) { + if (selectedTab === SCREENS.HOME) { return; } - const route = activeWorkspaceID ? (`/w/${activeWorkspaceID}/home` as Route) : ROUTES.HOME; + const route = activeWorkspaceID ? (`/w/${activeWorkspaceID}/${ROUTES.HOME}` as Route) : ROUTES.HOME; Navigation.navigate(route); - }, [activeWorkspaceID, currentTabName]); + }, [activeWorkspaceID, selectedTab]); return ( @@ -96,7 +80,7 @@ function BottomTabBar({isLoadingApp = false}: PurposeForUsingExpensifyModalProps @@ -109,7 +93,7 @@ function BottomTabBar({isLoadingApp = false}: PurposeForUsingExpensifyModalProps { - if (currentTabName === SCREENS.SEARCH.BOTTOM_TAB || currentTabName === SCREENS.SEARCH.CENTRAL_PANE) { + if (selectedTab === SCREENS.SEARCH.BOTTOM_TAB) { return; } interceptAnonymousUser(() => Navigation.navigate(ROUTES.SEARCH.getRoute(CONST.SEARCH.TAB.ALL))); @@ -122,14 +106,14 @@ function BottomTabBar({isLoadingApp = false}: PurposeForUsingExpensifyModalProps - + @@ -139,8 +123,4 @@ function BottomTabBar({isLoadingApp = false}: PurposeForUsingExpensifyModalProps BottomTabBar.displayName = 'BottomTabBar'; -export default withOnyx({ - isLoadingApp: { - key: ONYXKEYS.IS_LOADING_APP, - }, -})(memo(BottomTabBar)); +export default memo(BottomTabBar); diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar/index.website.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar/index.website.tsx deleted file mode 100644 index 0f98f37e8699..000000000000 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar/index.website.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import {useNavigation, useNavigationState} from '@react-navigation/native'; -import React, {useCallback, useEffect} from 'react'; -import {View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; -import {withOnyx} from 'react-native-onyx'; -import Icon from '@components/Icon'; -import * as Expensicons from '@components/Icon/Expensicons'; -import {PressableWithFeedback} from '@components/Pressable'; -import Tooltip from '@components/Tooltip'; -import useActiveBottomTabRoute from '@hooks/useActiveBottomTabRoute'; -import useActiveWorkspace from '@hooks/useActiveWorkspace'; -import useLocalize from '@hooks/useLocalize'; -import useTheme from '@hooks/useTheme'; -import useThemeStyles from '@hooks/useThemeStyles'; -import * as Session from '@libs/actions/Session'; -import interceptAnonymousUser from '@libs/interceptAnonymousUser'; -import getTopmostBottomTabRoute from '@libs/Navigation/getTopmostBottomTabRoute'; -import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRoute'; -import Navigation from '@libs/Navigation/Navigation'; -import type {RootStackParamList, State} from '@libs/Navigation/types'; -import {isCentralPaneName, isHomeTab, isSearchTab, isSettingsTab} from '@libs/NavigationUtils'; -import {getChatTabBrickRoad} from '@libs/WorkspacesSettingsUtils'; -import BottomTabAvatar from '@pages/home/sidebar/BottomTabAvatar'; -import BottomTabBarFloatingActionButton from '@pages/home/sidebar/BottomTabBarFloatingActionButton'; -import variables from '@styles/variables'; -import * as Welcome from '@userActions/Welcome'; -import CONST from '@src/CONST'; -import NAVIGATORS from '@src/NAVIGATORS'; -import ONYXKEYS from '@src/ONYXKEYS'; -import type {Route} from '@src/ROUTES'; -import ROUTES from '@src/ROUTES'; -import SCREENS from '@src/SCREENS'; - -type PurposeForUsingExpensifyModalOnyxProps = { - isLoadingApp: OnyxEntry; -}; -type PurposeForUsingExpensifyModalProps = PurposeForUsingExpensifyModalOnyxProps; - -function BottomTabBar({isLoadingApp = false}: PurposeForUsingExpensifyModalProps) { - const theme = useTheme(); - const styles = useThemeStyles(); - const {translate} = useLocalize(); - const navigation = useNavigation(); - const {activeWorkspaceID: contextActiveWorkspaceID} = useActiveWorkspace(); - const activeWorkspaceID = sessionStorage.getItem(CONST.SESSION_STORAGE_KEYS.ACTIVE_WORKSPACE_ID) ?? contextActiveWorkspaceID; - - useEffect(() => { - const navigationState = navigation.getState() as State | undefined; - const routes = navigationState?.routes; - const currentRoute = routes?.[navigationState?.index ?? 0]; - // When we are redirected to the Settings tab from the OldDot, we don't want to call the Welcome.show() method. - // To prevent this, the value of the bottomTabRoute?.name is checked here - if (!!(currentRoute && currentRoute.name !== NAVIGATORS.BOTTOM_TAB_NAVIGATOR && !isCentralPaneName(currentRoute.name)) || Session.isAnonymousUser()) { - return; - } - - Welcome.isOnboardingFlowCompleted({onNotCompleted: () => Navigation.navigate(ROUTES.ONBOARDING_ROOT)}); - // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps - }, [isLoadingApp]); - - // Parent navigator of the bottom tab bar is the root navigator. - const currentTabName = useNavigationState((state) => { - const topmostCentralPaneRoute = getTopmostCentralPaneRoute(state); - - if (topmostCentralPaneRoute && topmostCentralPaneRoute.name === SCREENS.SEARCH.CENTRAL_PANE) { - return SCREENS.SEARCH.CENTRAL_PANE; - } - - const topmostBottomTabRoute = getTopmostBottomTabRoute(state); - return topmostBottomTabRoute?.name ?? SCREENS.HOME; - }); - - const activeBottomTabRoute = useActiveBottomTabRoute(); - const chatTabBrickRoad = getChatTabBrickRoad(activeWorkspaceID); - - const navigateToChats = useCallback(() => { - if (currentTabName === SCREENS.HOME) { - return; - } - const route = activeWorkspaceID ? (`/w/${activeWorkspaceID}/home` as Route) : ROUTES.HOME; - Navigation.navigate(route); - }, [activeWorkspaceID, currentTabName]); - - return ( - - - - - - {chatTabBrickRoad && ( - - )} - - - - - { - if (isSearchTab(activeBottomTabRoute?.name)) { - return; - } - interceptAnonymousUser(() => Navigation.navigate(ROUTES.SEARCH.getRoute(CONST.SEARCH.TAB.ALL))); - }} - role={CONST.ROLE.BUTTON} - accessibilityLabel={translate('common.search')} - wrapperStyle={styles.flex1} - style={styles.bottomTabBarItem} - > - - - - - - - - - - - ); -} - -BottomTabBar.displayName = 'BottomTabBar'; - -export default withOnyx({ - isLoadingApp: { - key: ONYXKEYS.IS_LOADING_APP, - }, -})(BottomTabBar); diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/index.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/index.tsx index 6a6f44df20bd..89b83dae816c 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/index.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/index.tsx @@ -44,6 +44,7 @@ function CustomBottomTabNavigator({initialRouteName, children, screenOptions, .. const styles = useThemeStyles(); const stateToRender = getStateToRender(state); + const selectedTab = stateToRender.routes.at(-1)?.name; return ( - + ); diff --git a/src/libs/NavigationUtils.ts b/src/libs/NavigationUtils.ts index 93d11d00345b..572310e8218b 100644 --- a/src/libs/NavigationUtils.ts +++ b/src/libs/NavigationUtils.ts @@ -26,28 +26,11 @@ const removePolicyIDParamFromState = (state: State) => { return stateCopy; }; -const TAB_SETTINGS_SCREENS = [SCREENS.SETTINGS.ROOT]; -const TAB_SEARCH_SCREENS = [SCREENS.SEARCH.BOTTOM_TAB, SCREENS.SEARCH.CENTRAL_PANE]; -const TAB_CHAT_SCREENS = [SCREENS.HOME]; - -const TAB_SCREEN_NAMES = new Set([...TAB_SETTINGS_SCREENS, ...TAB_SEARCH_SCREENS, ...TAB_CHAT_SCREENS]); -const TAB_SETTINGS_SCREEN_NAMES = new Set(TAB_SETTINGS_SCREENS); -const TAB_SEARCH_SCREEN_NAMES = new Set(TAB_SEARCH_SCREENS); -const TAB_CHAT_SCREEN_NAMES = new Set(TAB_CHAT_SCREENS); - -function createScreenNameChecker(screenNames: Set) { - return function (screen: string | undefined): screen is ScreenName { - if (!screen) { - return false; - } - return screenNames.has(screen); - }; +function isCentralPaneName(screen: string | undefined): screen is CentralPaneName { + if (!screen) { + return false; + } + return CENTRAL_PANE_SCREEN_NAMES.has(screen as CentralPaneName); } -const isTabScreenName = createScreenNameChecker(TAB_SCREEN_NAMES); -const isSettingsTab = createScreenNameChecker(TAB_SETTINGS_SCREEN_NAMES); -const isSearchTab = createScreenNameChecker(TAB_SEARCH_SCREEN_NAMES); -const isHomeTab = createScreenNameChecker(TAB_CHAT_SCREEN_NAMES); -const isCentralPaneName = createScreenNameChecker(CENTRAL_PANE_SCREEN_NAMES); - -export {isTabScreenName, isCentralPaneName, isSearchTab, isHomeTab, isSettingsTab, removePolicyIDParamFromState}; +export {isCentralPaneName, removePolicyIDParamFromState}; diff --git a/src/pages/Search/SearchPageBottomTab.tsx b/src/pages/Search/SearchPageBottomTab.tsx index 9ae6423a6cc1..965917bc5ebe 100644 --- a/src/pages/Search/SearchPageBottomTab.tsx +++ b/src/pages/Search/SearchPageBottomTab.tsx @@ -4,7 +4,7 @@ import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import Search from '@components/Search'; -import useActiveBottomTabRoute from '@hooks/useActiveBottomTabRoute'; +import useActiveCentralPaneRoute from '@hooks/useActiveCentralPaneRoute'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; @@ -28,7 +28,7 @@ const defaultSearchProps = { function SearchPageBottomTab() { const {translate} = useLocalize(); const {isSmallScreenWidth} = useWindowDimensions(); - const activeBottomTabRoute = useActiveBottomTabRoute(); + const activeCentralPaneRoute = useActiveCentralPaneRoute(); const styles = useThemeStyles(); const [isMobileSelectionModeActive, setIsMobileSelectionModeActive] = useState(false); @@ -38,11 +38,11 @@ function SearchPageBottomTab() { sortBy, sortOrder, } = useMemo(() => { - if (activeBottomTabRoute?.name !== SCREENS.SEARCH.CENTRAL_PANE || !activeBottomTabRoute.params) { + if (activeCentralPaneRoute?.name !== SCREENS.SEARCH.CENTRAL_PANE || !activeCentralPaneRoute.params) { return defaultSearchProps; } - return {...defaultSearchProps, ...activeBottomTabRoute.params} as SearchPageProps['route']['params']; - }, [activeBottomTabRoute]); + return {...defaultSearchProps, ...activeCentralPaneRoute.params} as SearchPageProps['route']['params']; + }, [activeCentralPaneRoute]); const query = rawQuery as SearchQuery; diff --git a/src/pages/settings/InitialSettingsPage.tsx b/src/pages/settings/InitialSettingsPage.tsx index d8051a5f7ed5..e11da8bf49fc 100755 --- a/src/pages/settings/InitialSettingsPage.tsx +++ b/src/pages/settings/InitialSettingsPage.tsx @@ -20,7 +20,7 @@ import Text from '@components/Text'; import Tooltip from '@components/Tooltip'; import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; -import useActiveBottomTabRoute from '@hooks/useActiveBottomTabRoute'; +import useActiveCentralPaneRoute from '@hooks/useActiveCentralPaneRoute'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useSingleExecution from '@hooks/useSingleExecution'; @@ -104,7 +104,7 @@ function InitialSettingsPage({session, userWallet, bankAccountList, fundList, wa const waitForNavigate = useWaitForNavigation(); const popoverAnchor = useRef(null); const {translate, formatPhoneNumber} = useLocalize(); - const activeBottomTabRoute = useActiveBottomTabRoute(); + const activeCentralPaneRoute = useActiveCentralPaneRoute(); const emojiCode = currentUserPersonalDetails?.status?.emojiCode ?? ''; const [privateSubscription] = useOnyx(ONYXKEYS.NVP_PRIVATE_SUBSCRIPTION); @@ -330,9 +330,9 @@ function InitialSettingsPage({session, userWallet, bankAccountList, fundList, wa shouldBlockSelection={!!item.link} onSecondaryInteraction={item.link ? (event) => openPopover(item.link, event) : undefined} focused={ - !!activeBottomTabRoute && + !!activeCentralPaneRoute && !!item.routeName && - !!(activeBottomTabRoute.name.toLowerCase().replaceAll('_', '') === item.routeName.toLowerCase().replaceAll('/', '')) + !!(activeCentralPaneRoute.name.toLowerCase().replaceAll('_', '') === item.routeName.toLowerCase().replaceAll('/', '')) } isPaneMenu iconRight={item.iconRight} @@ -353,7 +353,7 @@ function InitialSettingsPage({session, userWallet, bankAccountList, fundList, wa userWallet?.currentBalance, isExecuting, singleExecution, - activeBottomTabRoute, + activeCentralPaneRoute, waitForNavigate, ], ); From 6fbbaeddeb9b459bb8e8a47988ba4b39932c8215 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Thu, 18 Jul 2024 12:05:53 +0200 Subject: [PATCH 3/5] Remove unused nav types --- .../AppNavigator/Navigators/ActiveBottomTabRouteContext.ts | 6 ------ src/libs/Navigation/types.ts | 7 ------- 2 files changed, 13 deletions(-) delete mode 100644 src/libs/Navigation/AppNavigator/Navigators/ActiveBottomTabRouteContext.ts diff --git a/src/libs/Navigation/AppNavigator/Navigators/ActiveBottomTabRouteContext.ts b/src/libs/Navigation/AppNavigator/Navigators/ActiveBottomTabRouteContext.ts deleted file mode 100644 index ce55da8e4bde..000000000000 --- a/src/libs/Navigation/AppNavigator/Navigators/ActiveBottomTabRouteContext.ts +++ /dev/null @@ -1,6 +0,0 @@ -import React from 'react'; -import type {BottomTabScreensParamList, NavigationPartialRoute} from '@libs/Navigation/types'; - -const ActiveBottomTabRouteContext = React.createContext | undefined>(undefined); - -export default ActiveBottomTabRouteContext; diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index c273b2db6a10..8c4e7a17ca08 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -1063,7 +1063,6 @@ type RightModalNavigatorParamList = { type TravelNavigatorParamList = { [SCREENS.TRAVEL.MY_TRIPS]: undefined; - [SCREENS.RIGHT_MODAL.SEARCH_REPORT]: NavigatorScreenParams; }; type FullScreenNavigatorParamList = { @@ -1160,8 +1159,6 @@ type ExplanationModalNavigatorParamList = { [SCREENS.EXPLANATION_MODAL.ROOT]: undefined; }; -type BottomTabScreensParamList = {[SCREENS.HOME]: undefined; [SCREENS.REPORT]: undefined} & SearchNavigatorParamList & SettingsNavigatorParamList; - type BottomTabNavigatorParamList = { [SCREENS.HOME]: {policyID?: string}; [SCREENS.SEARCH.BOTTOM_TAB]: { @@ -1260,8 +1257,6 @@ type RootStackParamList = PublicScreensParamList & AuthScreensParamList & LeftMo type BottomTabName = keyof BottomTabNavigatorParamList; -type BottomTabScreenName = keyof BottomTabScreensParamList; - type FullScreenName = keyof FullScreenNavigatorParamList; type CentralPaneName = keyof CentralPaneScreensParamList; @@ -1280,8 +1275,6 @@ export type { BackToParams, BackToAndForwardToParms, BottomTabName, - BottomTabScreenName, - BottomTabScreensParamList, BottomTabNavigatorParamList, DetailsNavigatorParamList, EditRequestNavigatorParamList, From ba63e416dc3bebf4261a5dae37d0df751316b158 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Thu, 18 Jul 2024 14:02:32 +0200 Subject: [PATCH 4/5] Refactor loading variables names in Search --- src/components/Search/index.tsx | 13 +++++++------ src/libs/SearchUtils.ts | 6 +----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx index a9142127f248..6b47364345c7 100644 --- a/src/components/Search/index.tsx +++ b/src/components/Search/index.tsx @@ -101,10 +101,11 @@ function Search({query, policyIDs, sortBy, sortOrder, isMobileSelectionModeActiv // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps }, [hash, isOffline]); - const isLoadingItems = !isOffline && searchResults?.data === undefined; - const isLoadingMoreItems = !isLoadingItems && searchResults?.search?.isLoading && searchResults?.search?.offset > 0; + const isDataLoaded = searchResults?.data !== undefined; + const shouldShowLoadingState = !isOffline && !isDataLoaded; + const shouldShowLoadingMoreItems = !shouldShowLoadingState && searchResults?.search?.isLoading && searchResults?.search?.offset > 0; - if (isLoadingItems) { + if (shouldShowLoadingState) { return ( <> { - if (!searchResults?.search?.hasMoreResults || isLoadingItems || isLoadingMoreItems) { + if (!searchResults?.search?.hasMoreResults || shouldShowLoadingState || shouldShowLoadingMoreItems) { return; } const currentOffset = searchResults?.search?.offset ?? 0; @@ -224,7 +225,7 @@ function Search({query, policyIDs, sortBy, sortOrder, isMobileSelectionModeActiv setIsMobileSelectionModeActive={setIsMobileSelectionModeActive} isMobileSelectionModeActive={isMobileSelectionModeActive} listFooterContent={ - isLoadingMoreItems ? ( + shouldShowLoadingMoreItems ? ( key.startsWith(ONYXKEYS.COLLECTION.TRANSACTION)); } From 36fea789aa33c9249d8de86fba07d99787bd7b21 Mon Sep 17 00:00:00 2001 From: Wojciech Boman Date: Thu, 18 Jul 2024 16:58:10 +0200 Subject: [PATCH 5/5] Replace BottomTabBar/index.tsx with BottomTabBar.tsx --- .../{BottomTabBar/index.tsx => BottomTabBar.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/{BottomTabBar/index.tsx => BottomTabBar.tsx} (100%) diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar/index.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx similarity index 100% rename from src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar/index.tsx rename to src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx