From e43d6162cfb5a29581461bbced5d418914a63e41 Mon Sep 17 00:00:00 2001 From: Ming Date: Tue, 17 Mar 2026 22:37:22 +0700 Subject: [PATCH 1/3] Optimize fetching openPolicy --- src/pages/workspace/WorkspaceInitialPage.tsx | 80 +++++++------------- 1 file changed, 29 insertions(+), 51 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 3357fc38ba2d5..e06d142de9ab3 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -1,29 +1,12 @@ -import {findFocusedRoute, useFocusEffect, useNavigationState} from '@react-navigation/native'; -import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; -import {View} from 'react-native'; -import {useOnyx} from 'react-native-onyx'; -import type {ValueOf} from 'type-fest'; +import { findFocusedRoute, useFocusEffect, useIsFocused, useNavigationState } from '@react-navigation/native'; +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { View } from 'react-native'; +import { useOnyx } from 'react-native-onyx'; +import type { ValueOf } from 'type-fest'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import HighlightableMenuItem from '@components/HighlightableMenuItem'; -import { - Building, - CalendarSolid, - Car, - Coins, - CreditCard, - ExpensifyAppIcon, - ExpensifyCard, - Feed, - Folder, - Gear, - InvoiceGeneric, - Pencil, - Sync, - Tag, - Users, - Workflows, -} from '@components/Icon/Expensicons'; +import { Building, CalendarSolid, Car, Coins, CreditCard, ExpensifyAppIcon, ExpensifyCard, Feed, Folder, Gear, InvoiceGeneric, Pencil, Sync, Tag, Users, Workflows } from '@components/Icon/Expensicons'; import MenuItem from '@components/MenuItem'; import BottomTabBar from '@components/Navigation/BottomTabBar'; import BOTTOM_TABS from '@components/Navigation/BottomTabBar/BOTTOM_TABS'; @@ -38,41 +21,30 @@ import usePrevious from '@hooks/usePrevious'; import useSingleExecution from '@hooks/useSingleExecution'; import useThemeStyles from '@hooks/useThemeStyles'; import useWaitForNavigation from '@hooks/useWaitForNavigation'; -import {confirmReadyToOpenApp} from '@libs/actions/App'; -import {isConnectionInProgress} from '@libs/actions/connections'; -import {clearErrors, openPolicyInitialPage, removeWorkspace} from '@libs/actions/Policy/Policy'; -import {checkIfFeedConnectionIsBroken, flatAllCardsList} from '@libs/CardUtils'; -import {convertToDisplayString} from '@libs/CurrencyUtils'; +import { confirmReadyToOpenApp } from '@libs/actions/App'; +import { isConnectionInProgress } from '@libs/actions/connections'; +import { clearErrors, openPolicyInitialPage, removeWorkspace } from '@libs/actions/Policy/Policy'; +import { checkIfFeedConnectionIsBroken, flatAllCardsList } from '@libs/CardUtils'; +import { convertToDisplayString } from '@libs/CurrencyUtils'; import Navigation from '@libs/Navigation/Navigation'; -import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; -import { - shouldShowPolicy as checkIfShouldShowPolicy, - getWorkspaceAccountID, - goBackFromInvalidPolicy, - hasPolicyCategoriesError, - isPaidGroupPolicy, - isPendingDeletePolicy, - isPolicyAdmin, - isPolicyFeatureEnabled, - shouldShowEmployeeListError, - shouldShowSyncError, - shouldShowTaxRateError, -} from '@libs/PolicyUtils'; -import {getDefaultWorkspaceAvatar, getIcons, getPolicyExpenseChat, getReportName, getReportOfflinePendingActionAndErrors} from '@libs/ReportUtils'; +import type { PlatformStackScreenProps } from '@libs/Navigation/PlatformStackNavigation/types'; +import { shouldShowPolicy as checkIfShouldShowPolicy, getWorkspaceAccountID, goBackFromInvalidPolicy, hasPolicyCategoriesError, isPaidGroupPolicy, isPendingDeletePolicy, isPolicyAdmin, isPolicyFeatureEnabled, shouldShowEmployeeListError, shouldShowSyncError, shouldShowTaxRateError } from '@libs/PolicyUtils'; +import { getDefaultWorkspaceAvatar, getIcons, getPolicyExpenseChat, getReportName, getReportOfflinePendingActionAndErrors } from '@libs/ReportUtils'; import type WORKSPACE_TO_RHP from '@navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP'; -import type {WorkspaceSplitNavigatorParamList} from '@navigation/types'; +import type { WorkspaceSplitNavigatorParamList } from '@navigation/types'; import CONST from '@src/CONST'; -import type {TranslationPaths} from '@src/languages/types'; +import type { TranslationPaths } from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; -import type {PendingAction} from '@src/types/onyx/OnyxCommon'; -import type {PolicyFeatureName} from '@src/types/onyx/Policy'; -import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import type { PendingAction } from '@src/types/onyx/OnyxCommon'; +import type { PolicyFeatureName } from '@src/types/onyx/Policy'; +import { isEmptyObject } from '@src/types/utils/EmptyObject'; import type IconAsset from '@src/types/utils/IconAsset'; -import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading'; +import type { WithPolicyAndFullscreenLoadingProps } from './withPolicyAndFullscreenLoading'; import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading'; + type WorkspaceTopLevelScreens = keyof typeof WORKSPACE_TO_RHP; type WorkspaceMenuItem = { @@ -111,6 +83,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${route.params?.policyID}`); const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); const {login, accountID} = useCurrentUserPersonalDetails(); + const isFocused = useIsFocused(); const hasSyncError = shouldShowSyncError(policy, isConnectionInProgress(connectionSyncProgress, policy)); const waitForNavigate = useWaitForNavigation(); const {singleExecution, isExecuting} = useSingleExecution(); @@ -148,7 +121,12 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac openPolicyInitialPage(route.params.policyID); }, [policyDraft?.id, route.params.policyID]); - useNetwork({onReconnect: fetchPolicyData}); + useNetwork({onReconnect: () => { + if (!isFocused) { + return; + } + fetchPolicyData(); + }}); useFocusEffect( useCallback(() => { @@ -503,4 +481,4 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac WorkspaceInitialPage.displayName = 'WorkspaceInitialPage'; -export default withPolicyAndFullscreenLoading(WorkspaceInitialPage); +export default withPolicyAndFullscreenLoading(WorkspaceInitialPage); \ No newline at end of file From af8093a96d73cb487c5f317e1dcb4dd2de238452 Mon Sep 17 00:00:00 2001 From: Ming Date: Tue, 17 Mar 2026 22:50:58 +0700 Subject: [PATCH 2/3] merge main --- src/pages/workspace/WorkspaceInitialPage.tsx | 87 +++++++++++++------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index e06d142de9ab3..35044b4727c5f 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -1,12 +1,29 @@ -import { findFocusedRoute, useFocusEffect, useIsFocused, useNavigationState } from '@react-navigation/native'; -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { View } from 'react-native'; -import { useOnyx } from 'react-native-onyx'; -import type { ValueOf } from 'type-fest'; +import {findFocusedRoute, useFocusEffect, useIsFocused, useNavigationState} from '@react-navigation/native'; +import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; +import {View} from 'react-native'; +import {useOnyx} from 'react-native-onyx'; +import type {ValueOf} from 'type-fest'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import HighlightableMenuItem from '@components/HighlightableMenuItem'; -import { Building, CalendarSolid, Car, Coins, CreditCard, ExpensifyAppIcon, ExpensifyCard, Feed, Folder, Gear, InvoiceGeneric, Pencil, Sync, Tag, Users, Workflows } from '@components/Icon/Expensicons'; +import { + Building, + CalendarSolid, + Car, + Coins, + CreditCard, + ExpensifyAppIcon, + ExpensifyCard, + Feed, + Folder, + Gear, + InvoiceGeneric, + Pencil, + Sync, + Tag, + Users, + Workflows, +} from '@components/Icon/Expensicons'; import MenuItem from '@components/MenuItem'; import BottomTabBar from '@components/Navigation/BottomTabBar'; import BOTTOM_TABS from '@components/Navigation/BottomTabBar/BOTTOM_TABS'; @@ -21,30 +38,41 @@ import usePrevious from '@hooks/usePrevious'; import useSingleExecution from '@hooks/useSingleExecution'; import useThemeStyles from '@hooks/useThemeStyles'; import useWaitForNavigation from '@hooks/useWaitForNavigation'; -import { confirmReadyToOpenApp } from '@libs/actions/App'; -import { isConnectionInProgress } from '@libs/actions/connections'; -import { clearErrors, openPolicyInitialPage, removeWorkspace } from '@libs/actions/Policy/Policy'; -import { checkIfFeedConnectionIsBroken, flatAllCardsList } from '@libs/CardUtils'; -import { convertToDisplayString } from '@libs/CurrencyUtils'; +import {confirmReadyToOpenApp} from '@libs/actions/App'; +import {isConnectionInProgress} from '@libs/actions/connections'; +import {clearErrors, openPolicyInitialPage, removeWorkspace} from '@libs/actions/Policy/Policy'; +import {checkIfFeedConnectionIsBroken, flatAllCardsList} from '@libs/CardUtils'; +import {convertToDisplayString} from '@libs/CurrencyUtils'; import Navigation from '@libs/Navigation/Navigation'; -import type { PlatformStackScreenProps } from '@libs/Navigation/PlatformStackNavigation/types'; -import { shouldShowPolicy as checkIfShouldShowPolicy, getWorkspaceAccountID, goBackFromInvalidPolicy, hasPolicyCategoriesError, isPaidGroupPolicy, isPendingDeletePolicy, isPolicyAdmin, isPolicyFeatureEnabled, shouldShowEmployeeListError, shouldShowSyncError, shouldShowTaxRateError } from '@libs/PolicyUtils'; -import { getDefaultWorkspaceAvatar, getIcons, getPolicyExpenseChat, getReportName, getReportOfflinePendingActionAndErrors } from '@libs/ReportUtils'; +import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; +import { + shouldShowPolicy as checkIfShouldShowPolicy, + getWorkspaceAccountID, + goBackFromInvalidPolicy, + hasPolicyCategoriesError, + isPaidGroupPolicy, + isPendingDeletePolicy, + isPolicyAdmin, + isPolicyFeatureEnabled, + shouldShowEmployeeListError, + shouldShowSyncError, + shouldShowTaxRateError, +} from '@libs/PolicyUtils'; +import {getDefaultWorkspaceAvatar, getIcons, getPolicyExpenseChat, getReportName, getReportOfflinePendingActionAndErrors} from '@libs/ReportUtils'; import type WORKSPACE_TO_RHP from '@navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP'; -import type { WorkspaceSplitNavigatorParamList } from '@navigation/types'; +import type {WorkspaceSplitNavigatorParamList} from '@navigation/types'; import CONST from '@src/CONST'; -import type { TranslationPaths } from '@src/languages/types'; +import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; -import type { PendingAction } from '@src/types/onyx/OnyxCommon'; -import type { PolicyFeatureName } from '@src/types/onyx/Policy'; -import { isEmptyObject } from '@src/types/utils/EmptyObject'; +import type {PendingAction} from '@src/types/onyx/OnyxCommon'; +import type {PolicyFeatureName} from '@src/types/onyx/Policy'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type IconAsset from '@src/types/utils/IconAsset'; -import type { WithPolicyAndFullscreenLoadingProps } from './withPolicyAndFullscreenLoading'; +import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading'; import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading'; - type WorkspaceTopLevelScreens = keyof typeof WORKSPACE_TO_RHP; type WorkspaceMenuItem = { @@ -83,7 +111,6 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac const [policyCategories] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${route.params?.policyID}`); const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); const {login, accountID} = useCurrentUserPersonalDetails(); - const isFocused = useIsFocused(); const hasSyncError = shouldShowSyncError(policy, isConnectionInProgress(connectionSyncProgress, policy)); const waitForNavigate = useWaitForNavigation(); const {singleExecution, isExecuting} = useSingleExecution(); @@ -121,12 +148,14 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac openPolicyInitialPage(route.params.policyID); }, [policyDraft?.id, route.params.policyID]); - useNetwork({onReconnect: () => { - if (!isFocused) { - return; - } - fetchPolicyData(); - }}); + useNetwork({ + onReconnect: () => { + if (!isFocused) { + return; + } + fetchPolicyData(); + }, + }); useFocusEffect( useCallback(() => { @@ -481,4 +510,4 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, route}: Workspac WorkspaceInitialPage.displayName = 'WorkspaceInitialPage'; -export default withPolicyAndFullscreenLoading(WorkspaceInitialPage); \ No newline at end of file +export default withPolicyAndFullscreenLoading(WorkspaceInitialPage); From 22dae1f8e6b1890bff12567fbf34330d25feb087 Mon Sep 17 00:00:00 2001 From: Ming Date: Wed, 18 Mar 2026 21:27:42 +0700 Subject: [PATCH 3/3] also optimize open overview page --- src/pages/workspace/WorkspaceOverviewPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceOverviewPage.tsx b/src/pages/workspace/WorkspaceOverviewPage.tsx index 5b3037a5d3b0d..edf8557910755 100644 --- a/src/pages/workspace/WorkspaceOverviewPage.tsx +++ b/src/pages/workspace/WorkspaceOverviewPage.tsx @@ -197,7 +197,7 @@ function WorkspaceOverviewPage({policyDraft, policy: policyProp, route}: Workspa const mentionReportContextValue = {policyID: policy?.id, currentReportID: undefined, exactlyMatch: true}; const fetchPolicyData = () => { - if (policyDraft?.id) { + if (policyDraft?.id || !isFocused) { return; } openPolicyProfilePage(route.params.policyID);