diff --git a/src/components/Navigation/NavigationTabBar/NavigationTabBarDummy.tsx b/src/components/Navigation/NavigationTabBar/NavigationTabBarDummy.tsx new file mode 100644 index 000000000000..2eeebcaebcc7 --- /dev/null +++ b/src/components/Navigation/NavigationTabBar/NavigationTabBarDummy.tsx @@ -0,0 +1,299 @@ +import React, {memo, useEffect, useState} from 'react'; +import {View} from 'react-native'; +import type {ValueOf} from 'type-fest'; +import FloatingActionButton from '@components/FloatingActionButton'; +import HeaderGap from '@components/HeaderGap'; +import Icon from '@components/Icon'; +import * as Expensicons from '@components/Icon/Expensicons'; +import ImageSVG from '@components/ImageSVG'; +import {PressableWithFeedback} from '@components/Pressable'; +import Text from '@components/Text'; +import useLocalize from '@hooks/useLocalize'; +import useOnyx from '@hooks/useOnyx'; +import useResponsiveLayout from '@hooks/useResponsiveLayout'; +import {useSidebarOrderedReports} from '@hooks/useSidebarOrderedReports'; +import useStyleUtils from '@hooks/useStyleUtils'; +import useTheme from '@hooks/useTheme'; +import useThemeStyles from '@hooks/useThemeStyles'; +import useWorkspacesTabIndicatorStatus from '@hooks/useWorkspacesTabIndicatorStatus'; +import type {BrickRoad} from '@libs/WorkspacesSettingsUtils'; +import {getChatTabBrickRoad} from '@libs/WorkspacesSettingsUtils'; +import NavigationTabBarAvatar from '@pages/home/sidebar/NavigationTabBarAvatar'; +import variables from '@styles/variables'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import NAVIGATION_TABS from './NAVIGATION_TABS'; + +const noop = () => undefined; + +function NavigationTabBarWideDummy({selectedTab}: {selectedTab: ValueOf}) { + const theme = useTheme(); + const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); + const {translate} = useLocalize(); + const {indicatorColor: workspacesTabIndicatorColor, status: workspacesTabIndicatorStatus} = useWorkspacesTabIndicatorStatus(); + const [chatTabBrickRoad, setChatTabBrickRoad] = useState(undefined); + const {orderedReports} = useSidebarOrderedReports(); + const [reportAttributes] = useOnyx(ONYXKEYS.DERIVED.REPORT_ATTRIBUTES, {selector: (value) => value?.reports, canBeMissing: true}); + + useEffect(() => { + setChatTabBrickRoad(getChatTabBrickRoad(orderedReports)); + // We need to get a new brick road state when report attributes are updated, otherwise we'll be showing an outdated brick road. + // That's why reportAttributes is added as a dependency here + }, [orderedReports, reportAttributes]); + + return ( + + + + + + + + + + {!!chatTabBrickRoad && ( + + )} + + + {translate('common.inbox')} + + + + + + + + {translate('common.reports')} + + + + + + {!!workspacesTabIndicatorStatus && } + + + {translate('common.workspacesTabTitle')} + + + + + + + + + ); +} + +function NavigationTabBarNarrowDummy({selectedTab}: {selectedTab: ValueOf}) { + const theme = useTheme(); + const styles = useThemeStyles(); + const {translate} = useLocalize(); + const {indicatorColor: workspacesTabIndicatorColor, status: workspacesTabIndicatorStatus} = useWorkspacesTabIndicatorStatus(); + const [chatTabBrickRoad, setChatTabBrickRoad] = useState(undefined); + const {orderedReports} = useSidebarOrderedReports(); + const [reportAttributes] = useOnyx(ONYXKEYS.DERIVED.REPORT_ATTRIBUTES, {selector: (value) => value?.reports, canBeMissing: true}); + + useEffect(() => { + setChatTabBrickRoad(getChatTabBrickRoad(orderedReports)); + // We need to get a new brick road state when report attributes are updated, otherwise we'll be showing an outdated brick road. + // That's why reportAttributes is added as a dependency here + }, [orderedReports, reportAttributes]); + + return ( + + + + + {!!chatTabBrickRoad && ( + + )} + + + {translate('common.inbox')} + + + + + + + + {translate('common.reports')} + + + + + + + + + {!!workspacesTabIndicatorStatus && } + + + {translate('common.workspacesTabTitle')} + + + + + ); +} + +/** + * This is a dummy component for the NavigationTabBar created for performance reasons. + * It is used to render the dummy NavigationTabBar in a wide or narrow layout. + * @param selectedTab - The selected tab. + * @returns The NavigationTabBarDummy component. + */ +function NavigationTabBarDummy({selectedTab}: {selectedTab: ValueOf}) { + const {shouldUseNarrowLayout} = useResponsiveLayout(); + + if (shouldUseNarrowLayout) { + return ; + } + + return ; +} + +export default memo(NavigationTabBarDummy); diff --git a/src/components/Navigation/SearchSidebar.tsx b/src/components/Navigation/SearchSidebar.tsx index 6da1ec0b91e0..ae6e42796201 100644 --- a/src/components/Navigation/SearchSidebar.tsx +++ b/src/components/Navigation/SearchSidebar.tsx @@ -17,8 +17,8 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import SCREENS from '@src/SCREENS'; import type {SearchResults} from '@src/types/onyx'; -import NavigationTabBar from './NavigationTabBar'; import NAVIGATION_TABS from './NavigationTabBar/NAVIGATION_TABS'; +import NavigationTabBarDummy from './NavigationTabBar/NavigationTabBarDummy'; import TopBar from './TopBar'; type SearchSidebarProps = { @@ -76,7 +76,7 @@ function SearchSidebar({state}: SearchSidebarProps) { /> - + ); } diff --git a/src/pages/Search/SearchPageNarrow.tsx b/src/pages/Search/SearchPageNarrow.tsx index 63ca9abb5ba2..23b6b55b25ea 100644 --- a/src/pages/Search/SearchPageNarrow.tsx +++ b/src/pages/Search/SearchPageNarrow.tsx @@ -5,8 +5,8 @@ import Animated, {clamp, runOnJS, useAnimatedScrollHandler, useAnimatedStyle, us import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import type {DropdownOption} from '@components/ButtonWithDropdownMenu/types'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import NavigationTabBar from '@components/Navigation/NavigationTabBar'; import NAVIGATION_TABS from '@components/Navigation/NavigationTabBar/NAVIGATION_TABS'; +import NavigationTabBarDummy from '@components/Navigation/NavigationTabBar/NavigationTabBarDummy'; import TopBar from '@components/Navigation/TopBar'; import ScreenWrapper from '@components/ScreenWrapper'; import Search from '@components/Search'; @@ -141,7 +141,7 @@ function SearchPageNarrow({queryJSON, headerButtonsOptions, currentSearchResults testID={SearchPageNarrow.displayName} shouldEnableMaxHeight offlineIndicatorStyle={styles.mtAuto} - bottomContent={} + bottomContent={} headerGapStyles={styles.searchHeaderGap} shouldShowOfflineIndicator={!!searchResults} > diff --git a/src/pages/home/sidebar/BaseSidebarScreen.tsx b/src/pages/home/sidebar/BaseSidebarScreen.tsx index b713f09429d7..c71fd8cc7c3b 100644 --- a/src/pages/home/sidebar/BaseSidebarScreen.tsx +++ b/src/pages/home/sidebar/BaseSidebarScreen.tsx @@ -1,7 +1,7 @@ import React, {useEffect} from 'react'; import {View} from 'react-native'; -import NavigationTabBar from '@components/Navigation/NavigationTabBar'; import NAVIGATION_TABS from '@components/Navigation/NavigationTabBar/NAVIGATION_TABS'; +import NavigationTabBarDummy from '@components/Navigation/NavigationTabBar/NavigationTabBarDummy'; import TopBar from '@components/Navigation/TopBar'; import ScreenWrapper from '@components/ScreenWrapper'; import useLocalize from '@hooks/useLocalize'; @@ -27,7 +27,7 @@ function BaseSidebarScreen() { shouldEnableKeyboardAvoidingView={false} style={[styles.sidebar, isMobile() ? styles.userSelectNone : {}]} testID={BaseSidebarScreen.displayName} - bottomContent={!shouldDisplayLHB && } + bottomContent={!shouldDisplayLHB && } > {({insets}) => ( <> @@ -39,7 +39,7 @@ function BaseSidebarScreen() { - {shouldDisplayLHB && } + {shouldDisplayLHB && } )} diff --git a/src/pages/settings/InitialSettingsPage.tsx b/src/pages/settings/InitialSettingsPage.tsx index 56c4f2d3a18e..ceb13a8044fb 100755 --- a/src/pages/settings/InitialSettingsPage.tsx +++ b/src/pages/settings/InitialSettingsPage.tsx @@ -13,8 +13,8 @@ import CustomStatusBarAndBackgroundContext from '@components/CustomStatusBarAndB import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import MenuItem from '@components/MenuItem'; -import NavigationTabBar from '@components/Navigation/NavigationTabBar'; import NAVIGATION_TABS from '@components/Navigation/NavigationTabBar/NAVIGATION_TABS'; +import NavigationTabBarDummy from '@components/Navigation/NavigationTabBar/NavigationTabBarDummy'; import {PressableWithFeedback} from '@components/Pressable'; import ScreenWrapper from '@components/ScreenWrapper'; import {ScrollOffsetContext} from '@components/ScrollOffsetContextProvider'; @@ -419,7 +419,7 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr } + bottomContent={!shouldDisplayLHB && } shouldEnableKeyboardAvoidingView={false} > {headerContent} @@ -443,7 +443,7 @@ function InitialSettingsPage({currentUserPersonalDetails}: InitialSettingsPagePr onCancel={() => toggleSignoutConfirmModal(false)} /> - {shouldDisplayLHB && } + {shouldDisplayLHB && } ); } diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 91deef0f5b42..b5015126d92e 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -25,8 +25,8 @@ import { Workflows, } from '@components/Icon/Expensicons'; import MenuItem from '@components/MenuItem'; -import NavigationTabBar from '@components/Navigation/NavigationTabBar'; import NAVIGATION_TABS from '@components/Navigation/NavigationTabBar/NAVIGATION_TABS'; +import NavigationTabBarDummy from '@components/Navigation/NavigationTabBar/NavigationTabBarDummy'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; @@ -437,7 +437,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac } + bottomContent={shouldShowNavigationTabBar && !shouldDisplayLHB && } > )} - {shouldShowNavigationTabBar && shouldDisplayLHB && } + {shouldShowNavigationTabBar && shouldDisplayLHB && } ); diff --git a/src/pages/workspace/WorkspacesListPage.tsx b/src/pages/workspace/WorkspacesListPage.tsx index e09a780f7ec0..d0df3fb83c3d 100755 --- a/src/pages/workspace/WorkspacesListPage.tsx +++ b/src/pages/workspace/WorkspacesListPage.tsx @@ -12,8 +12,8 @@ import * as Expensicons from '@components/Icon/Expensicons'; import * as Illustrations from '@components/Icon/Illustrations'; import LottieAnimations from '@components/LottieAnimations'; import type {MenuItemProps} from '@components/MenuItem'; -import NavigationTabBar from '@components/Navigation/NavigationTabBar'; import NAVIGATION_TABS from '@components/Navigation/NavigationTabBar/NAVIGATION_TABS'; +import NavigationTabBarDummy from '@components/Navigation/NavigationTabBar/NavigationTabBarDummy'; import TopBar from '@components/Navigation/TopBar'; import type {OfflineWithFeedbackProps} from '@components/OfflineWithFeedback'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; @@ -482,7 +482,7 @@ function WorkspacesListPage() { shouldEnableMaxHeight testID={WorkspacesListPage.displayName} shouldShowOfflineIndicatorInWideScreen - bottomContent={shouldUseNarrowLayout && } + bottomContent={shouldUseNarrowLayout && } enableEdgeToEdgeBottomSafeAreaPadding={false} > @@ -509,7 +509,7 @@ function WorkspacesListPage() { )} - {shouldDisplayLHB && } + {shouldDisplayLHB && } ); } @@ -520,7 +520,7 @@ function WorkspacesListPage() { shouldShowOfflineIndicatorInWideScreen testID={WorkspacesListPage.displayName} enableEdgeToEdgeBottomSafeAreaPadding={false} - bottomContent={shouldUseNarrowLayout && } + bottomContent={shouldUseNarrowLayout && } > {!shouldUseNarrowLayout && {getHeaderButton()}} @@ -546,7 +546,7 @@ function WorkspacesListPage() { isModalOpen={isSupportalActionRestrictedModalOpen} hideSupportalModal={hideSupportalModal} /> - {shouldDisplayLHB && } + {shouldDisplayLHB && } ); }