From b74ab713a537898f0a9e90024f39f2b65020ad62 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 13 Dec 2024 01:38:42 +0530 Subject: [PATCH] Refactor FloatingActionButton to use useBottomTabIsFocused hook and add new useBottomTabIsFocused hook for better navigation state management --- src/components/FloatingActionButton.tsx | 22 +----- src/hooks/useBottomTabIsFocused.ts | 23 ++++++ .../BottomTabBar.tsx | 74 +++++++++++++------ 3 files changed, 77 insertions(+), 42 deletions(-) create mode 100644 src/hooks/useBottomTabIsFocused.ts diff --git a/src/components/FloatingActionButton.tsx b/src/components/FloatingActionButton.tsx index 43ee40726127..22e0b347995c 100644 --- a/src/components/FloatingActionButton.tsx +++ b/src/components/FloatingActionButton.tsx @@ -1,4 +1,3 @@ -import {useIsFocused as useIsFocusedOriginal, useNavigationState} from '@react-navigation/native'; import type {ForwardedRef} from 'react'; import React, {forwardRef, useEffect, useRef} from 'react'; // eslint-disable-next-line no-restricted-imports @@ -6,16 +5,12 @@ import type {GestureResponderEvent, Role, Text, View} from 'react-native'; import {Platform} from 'react-native'; import Animated, {createAnimatedPropAdapter, Easing, interpolateColor, processColor, useAnimatedProps, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import Svg, {Path} from 'react-native-svg'; +import useBottomTabIsFocused from '@hooks/useBottomTabIsFocused'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import CENTRAL_PANE_SCREENS from '@libs/Navigation/AppNavigator/CENTRAL_PANE_SCREENS'; -import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRoute'; -import getTopmostFullScreenRoute from '@libs/Navigation/getTopmostFullScreenRoute'; -import type {CentralPaneName, FullScreenName, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types'; import variables from '@styles/variables'; import CONST from '@src/CONST'; -import SCREENS from '@src/SCREENS'; import {PressableWithoutFeedback} from './Pressable'; import {useProductTrainingContext} from './ProductTrainingContext'; import EducationalTooltip from './Tooltip/EducationalTooltip'; @@ -60,26 +55,13 @@ type FloatingActionButtonProps = { /* An accessibility role for the button */ role: Role; }; -const useIsFocused = () => { - const {shouldUseNarrowLayout} = useResponsiveLayout(); - const isFocused = useIsFocusedOriginal(); - const topmostFullScreenName = useNavigationState | undefined>(getTopmostFullScreenRoute); - const topmostCentralPane = useNavigationState | undefined>(getTopmostCentralPaneRoute); - if (topmostFullScreenName) { - return false; - } - if (shouldUseNarrowLayout) { - return isFocused || topmostCentralPane?.name === SCREENS.SEARCH.CENTRAL_PANE; - } - return isFocused || Object.keys(CENTRAL_PANE_SCREENS).includes(topmostCentralPane?.name ?? ''); -}; function FloatingActionButton({onPress, isActive, accessibilityLabel, role}: FloatingActionButtonProps, ref: ForwardedRef) { const {success, buttonDefaultBG, textLight, textDark} = useTheme(); const styles = useThemeStyles(); const borderRadius = styles.floatingActionButton.borderRadius; const {shouldUseNarrowLayout} = useResponsiveLayout(); const fabPressable = useRef(null); - const isFocused = useIsFocused(); + const isFocused = useBottomTabIsFocused(); const {renderProductTrainingTooltip, shouldShowProductTrainingTooltip, hideProductTrainingTooltip} = useProductTrainingContext( CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.GLOBAL_CREATE_TOOLTIP, isFocused, diff --git a/src/hooks/useBottomTabIsFocused.ts b/src/hooks/useBottomTabIsFocused.ts new file mode 100644 index 000000000000..33141e7ac4d8 --- /dev/null +++ b/src/hooks/useBottomTabIsFocused.ts @@ -0,0 +1,23 @@ +import {useIsFocused, useNavigationState} from '@react-navigation/native'; +import CENTRAL_PANE_SCREENS from '@libs/Navigation/AppNavigator/CENTRAL_PANE_SCREENS'; +import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRoute'; +import getTopmostFullScreenRoute from '@libs/Navigation/getTopmostFullScreenRoute'; +import type {CentralPaneName, FullScreenName, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types'; +import SCREENS from '@src/SCREENS'; +import useResponsiveLayout from './useResponsiveLayout'; + +const useBottomTabIsFocused = () => { + const {shouldUseNarrowLayout} = useResponsiveLayout(); + const isFocused = useIsFocused(); + const topmostFullScreenName = useNavigationState | undefined>(getTopmostFullScreenRoute); + const topmostCentralPane = useNavigationState | undefined>(getTopmostCentralPaneRoute); + if (topmostFullScreenName) { + return false; + } + if (shouldUseNarrowLayout) { + return isFocused || topmostCentralPane?.name === SCREENS.SEARCH.CENTRAL_PANE; + } + return isFocused || Object.keys(CENTRAL_PANE_SCREENS).includes(topmostCentralPane?.name ?? ''); +}; + +export default useBottomTabIsFocused; diff --git a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx index 88a735884493..4dbe5e738cad 100644 --- a/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomBottomTabNavigator/BottomTabBar.tsx @@ -4,11 +4,15 @@ import {useOnyx} from 'react-native-onyx'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import {PressableWithFeedback} from '@components/Pressable'; +import {useProductTrainingContext} from '@components/ProductTrainingContext'; import type {SearchQueryString} from '@components/Search/types'; import Text from '@components/Text'; +import EducationalTooltip from '@components/Tooltip/EducationalTooltip'; import useActiveWorkspace from '@hooks/useActiveWorkspace'; +import useBottomTabIsFocused from '@hooks/useBottomTabIsFocused'; import useCurrentReportID from '@hooks/useCurrentReportID'; import useLocalize from '@hooks/useLocalize'; +import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import interceptAnonymousUser from '@libs/interceptAnonymousUser'; @@ -74,9 +78,15 @@ function BottomTabBar({selectedTab}: BottomTabBarProps) { const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY); const [reportActions] = useOnyx(ONYXKEYS.COLLECTION.REPORT_ACTIONS); const [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS); + const {shouldUseNarrowLayout} = useResponsiveLayout(); const [chatTabBrickRoad, setChatTabBrickRoad] = useState(() => getChatTabBrickRoad(activeWorkspaceID, currentReportID, reports, betas, policies, priorityMode, transactionViolations), ); + const isFocused = useBottomTabIsFocused(); + const {renderProductTrainingTooltip, shouldShowProductTrainingTooltip, hideProductTrainingTooltip} = useProductTrainingContext( + CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.BOTTOM_NAV_INBOX_TOOLTIP, + isFocused, + ); useEffect(() => { setChatTabBrickRoad(getChatTabBrickRoad(activeWorkspaceID, currentReportID, reports, betas, policies, priorityMode, transactionViolations)); @@ -136,30 +146,50 @@ function BottomTabBar({selectedTab}: BottomTabBarProps) { /> )} - - - - {!!chatTabBrickRoad && ( - - )} - - - {translate('common.inbox')} - - + + + {!!chatTabBrickRoad && ( + + )} + + + {translate('common.inbox')} + + +