diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index b0918391f432..9dcb31dd8c86 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -810,13 +810,6 @@ function openReport( parameters.shouldRetry = false; } - const report = ReportUtils.getReport(reportID); - // If we open an exist report, but it is not present in Onyx yet, we should change the method to set for this report - // and we need data to be available when we navigate to the chat page - if (isEmptyObject(report)) { - optimisticData[0].onyxMethod = Onyx.METHOD.SET; - } - // If we are creating a new report, we need to add the optimistic report data and a report action const isCreatingNewReport = !isEmptyObject(newReportObject); if (isCreatingNewReport) { diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 8620d8d4866e..83cf4bbed197 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -5,7 +5,7 @@ import React, {memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, u import type {FlatList, ViewStyle} from 'react-native'; import {InteractionManager, View} from 'react-native'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; -import {withOnyx} from 'react-native-onyx'; +import {useOnyx, withOnyx} from 'react-native-onyx'; import type {LayoutChangeEvent} from 'react-native/Libraries/Types/CoreEventTypes'; import Banner from '@components/Banner'; import BlockingView from '@components/BlockingViews/BlockingView'; @@ -47,16 +47,14 @@ import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type * as OnyxTypes from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue'; import HeaderView from './HeaderView'; import ReportActionsView from './report/ReportActionsView'; import ReportFooter from './report/ReportFooter'; import type {ActionListContextType, ReactionListRef, ScrollPosition} from './ReportScreenContext'; import {ActionListContext, ReactionListContext} from './ReportScreenContext'; -type ReportScreenOnyxPropsWithoutParentReportAction = { - /** Get modal status */ - modal: OnyxEntry; - +type ReportScreenOnyxProps = { /** Tells us if the sidebar has rendered */ isSidebarLoaded: OnyxEntry; @@ -66,21 +64,9 @@ type ReportScreenOnyxPropsWithoutParentReportAction = { /** The policies which the user has access to */ policies: OnyxCollection; - /** The account manager report ID */ - accountManagerReportID: OnyxEntry; - - /** Whether user is leaving the current report */ - userLeavingStatus: OnyxEntry; - - /** Whether the composer is full size */ - isComposerFullSize: OnyxEntry; - /** An array containing all report actions related to this report, sorted based on a date criterion */ sortedAllReportActions: OnyxTypes.ReportAction[]; - /** The report currently being looked at */ - report: OnyxEntry; - reportNameValuePairs: OnyxEntry; /** The report metadata loading states */ @@ -94,14 +80,7 @@ type OnyxHOCProps = { type ReportScreenNavigationProps = StackScreenProps; -type ReportScreenPropsWithoutParentReportAction = OnyxHOCProps & CurrentReportIDContextValue & ReportScreenOnyxPropsWithoutParentReportAction & ReportScreenNavigationProps; - -type ReportScreenParentReportActionOnyxProps = { - /** The report's parentReportActions */ - parentReportActions: OnyxEntry; -}; - -type ReportScreenProps = ReportScreenPropsWithoutParentReportAction & ReportScreenParentReportActionOnyxProps; +type ReportScreenProps = OnyxHOCProps & CurrentReportIDContextValue & ReportScreenOnyxProps & ReportScreenNavigationProps; /** Get the currently viewed report ID as number */ function getReportID(route: ReportScreenNavigationProps['route']): string { @@ -134,7 +113,6 @@ function getParentReportAction(parentReportActions: OnyxEntry getParentReportAction(parentReportActions, reportOnyx?.parentReportActionID ?? ''), + }); + + const isLoadingReportOnyx = isLoadingOnyxValue(reportResult); + /** * Create a lightweight Report so as to keep the re-rendering as light as possible by * passing in only the required props. @@ -178,91 +165,89 @@ function ReportScreen({ */ const report = useMemo( (): OnyxTypes.Report => ({ - lastReadTime: reportProp?.lastReadTime, - reportID: reportProp?.reportID ?? '', - policyID: reportProp?.policyID, - lastVisibleActionCreated: reportProp?.lastVisibleActionCreated, - statusNum: reportProp?.statusNum, - stateNum: reportProp?.stateNum, - writeCapability: reportProp?.writeCapability, - type: reportProp?.type, - errorFields: reportProp?.errorFields, - isPolicyExpenseChat: reportProp?.isPolicyExpenseChat, - parentReportID: reportProp?.parentReportID, - parentReportActionID: reportProp?.parentReportActionID, - chatType: reportProp?.chatType, - pendingFields: reportProp?.pendingFields, - isDeletedParentAction: reportProp?.isDeletedParentAction, - reportName: reportProp?.reportName, - description: reportProp?.description, - managerID: reportProp?.managerID, - total: reportProp?.total, - nonReimbursableTotal: reportProp?.nonReimbursableTotal, - fieldList: reportProp?.fieldList, - ownerAccountID: reportProp?.ownerAccountID, - currency: reportProp?.currency, - unheldTotal: reportProp?.unheldTotal, - participants: reportProp?.participants, - isWaitingOnBankAccount: reportProp?.isWaitingOnBankAccount, - iouReportID: reportProp?.iouReportID, - isOwnPolicyExpenseChat: reportProp?.isOwnPolicyExpenseChat, - notificationPreference: reportProp?.notificationPreference, - isPinned: reportProp?.isPinned, - chatReportID: reportProp?.chatReportID, - visibility: reportProp?.visibility, - oldPolicyName: reportProp?.oldPolicyName, - policyName: reportProp?.policyName, - isOptimisticReport: reportProp?.isOptimisticReport, - lastMentionedTime: reportProp?.lastMentionedTime, - avatarUrl: reportProp?.avatarUrl, - permissions: reportProp?.permissions, - invoiceReceiver: reportProp?.invoiceReceiver, + lastReadTime: reportOnyx?.lastReadTime, + reportID: reportOnyx?.reportID ?? '', + policyID: reportOnyx?.policyID, + lastVisibleActionCreated: reportOnyx?.lastVisibleActionCreated, + statusNum: reportOnyx?.statusNum, + stateNum: reportOnyx?.stateNum, + writeCapability: reportOnyx?.writeCapability, + type: reportOnyx?.type, + errorFields: reportOnyx?.errorFields, + isPolicyExpenseChat: reportOnyx?.isPolicyExpenseChat, + parentReportID: reportOnyx?.parentReportID, + parentReportActionID: reportOnyx?.parentReportActionID, + chatType: reportOnyx?.chatType, + pendingFields: reportOnyx?.pendingFields, + isDeletedParentAction: reportOnyx?.isDeletedParentAction, + reportName: reportOnyx?.reportName, + description: reportOnyx?.description, + managerID: reportOnyx?.managerID, + total: reportOnyx?.total, + nonReimbursableTotal: reportOnyx?.nonReimbursableTotal, + fieldList: reportOnyx?.fieldList, + ownerAccountID: reportOnyx?.ownerAccountID, + currency: reportOnyx?.currency, + unheldTotal: reportOnyx?.unheldTotal, + participants: reportOnyx?.participants, + isWaitingOnBankAccount: reportOnyx?.isWaitingOnBankAccount, + iouReportID: reportOnyx?.iouReportID, + isOwnPolicyExpenseChat: reportOnyx?.isOwnPolicyExpenseChat, + notificationPreference: reportOnyx?.notificationPreference, + isPinned: reportOnyx?.isPinned, + chatReportID: reportOnyx?.chatReportID, + visibility: reportOnyx?.visibility, + oldPolicyName: reportOnyx?.oldPolicyName, + policyName: reportOnyx?.policyName, + isOptimisticReport: reportOnyx?.isOptimisticReport, + lastMentionedTime: reportOnyx?.lastMentionedTime, + avatarUrl: reportOnyx?.avatarUrl, + permissions: reportOnyx?.permissions, + invoiceReceiver: reportOnyx?.invoiceReceiver, }), [ - reportProp?.lastReadTime, - reportProp?.reportID, - reportProp?.policyID, - reportProp?.lastVisibleActionCreated, - reportProp?.statusNum, - reportProp?.stateNum, - reportProp?.writeCapability, - reportProp?.type, - reportProp?.errorFields, - reportProp?.isPolicyExpenseChat, - reportProp?.parentReportID, - reportProp?.parentReportActionID, - reportProp?.chatType, - reportProp?.pendingFields, - reportProp?.isDeletedParentAction, - reportProp?.reportName, - reportProp?.description, - reportProp?.managerID, - reportProp?.total, - reportProp?.nonReimbursableTotal, - reportProp?.fieldList, - reportProp?.ownerAccountID, - reportProp?.currency, - reportProp?.unheldTotal, - reportProp?.participants, - reportProp?.isWaitingOnBankAccount, - reportProp?.iouReportID, - reportProp?.isOwnPolicyExpenseChat, - reportProp?.notificationPreference, - reportProp?.isPinned, - reportProp?.chatReportID, - reportProp?.visibility, - reportProp?.oldPolicyName, - reportProp?.policyName, - reportProp?.isOptimisticReport, - reportProp?.lastMentionedTime, - reportProp?.avatarUrl, - reportProp?.permissions, - reportProp?.invoiceReceiver, + reportOnyx?.lastReadTime, + reportOnyx?.reportID, + reportOnyx?.policyID, + reportOnyx?.lastVisibleActionCreated, + reportOnyx?.statusNum, + reportOnyx?.stateNum, + reportOnyx?.writeCapability, + reportOnyx?.type, + reportOnyx?.errorFields, + reportOnyx?.isPolicyExpenseChat, + reportOnyx?.parentReportID, + reportOnyx?.parentReportActionID, + reportOnyx?.chatType, + reportOnyx?.pendingFields, + reportOnyx?.isDeletedParentAction, + reportOnyx?.reportName, + reportOnyx?.description, + reportOnyx?.managerID, + reportOnyx?.total, + reportOnyx?.nonReimbursableTotal, + reportOnyx?.fieldList, + reportOnyx?.ownerAccountID, + reportOnyx?.currency, + reportOnyx?.unheldTotal, + reportOnyx?.participants, + reportOnyx?.isWaitingOnBankAccount, + reportOnyx?.iouReportID, + reportOnyx?.isOwnPolicyExpenseChat, + reportOnyx?.notificationPreference, + reportOnyx?.isPinned, + reportOnyx?.chatReportID, + reportOnyx?.visibility, + reportOnyx?.oldPolicyName, + reportOnyx?.policyName, + reportOnyx?.isOptimisticReport, + reportOnyx?.lastMentionedTime, + reportOnyx?.avatarUrl, + reportOnyx?.permissions, + reportOnyx?.invoiceReceiver, ], ); - const parentReportAction = useMemo(() => getParentReportAction(parentReportActions, report?.parentReportActionID), [parentReportActions, report.parentReportActionID]); - const prevReport = usePrevious(report); const prevUserLeavingStatus = usePrevious(userLeavingStatus); const [isLinkingToMessage, setIsLinkingToMessage] = useState(!!reportActionIDFromRoute); @@ -469,10 +454,6 @@ function ReportScreen({ Timing.end(CONST.TIMING.CHAT_RENDER); Performance.markEnd(CONST.TIMING.CHAT_RENDER); - // Call OpenReport only if we are not linking to a message or the report is not available yet - if (!reportActionIDFromRoute || !report.reportID) { - fetchReportIfNeeded(); - } const interactionTask = InteractionManager.runAfterInteractions(() => { ComposerActions.setShouldShowComposeInput(true); }); @@ -489,6 +470,16 @@ function ReportScreen({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + useEffect(() => { + // Call OpenReport only if we are not linking to a message or the report is not available yet + if (isLoadingReportOnyx || (reportActionIDFromRoute && report.reportID)) { + return; + } + + fetchReportIfNeeded(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isLoadingReportOnyx]); + // If a user has chosen to leave a thread, and then returns to it (e.g. with the back button), we need to call `openReport` again in order to allow the user to rejoin and to receive real-time updates useEffect(() => { if (!shouldUseNarrowLayout || !isFocused || prevIsFocused || !ReportUtils.isChatThread(report) || report.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN) { @@ -753,11 +744,8 @@ function ReportScreen({ ReportScreen.displayName = 'ReportScreen'; export default withCurrentReportID( - withOnyx( + withOnyx( { - modal: { - key: ONYXKEYS.MODAL, - }, isSidebarLoaded: { key: ONYXKEYS.IS_SIDEBAR_LOADED, }, @@ -766,10 +754,6 @@ export default withCurrentReportID( canEvict: false, selector: (allReportActions: OnyxEntry) => ReportActionsUtils.getSortedReportActionsForDisplay(allReportActions, true), }, - report: { - key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${getReportID(route)}`, - allowStaleData: true, - }, reportNameValuePairs: { key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${getReportID(route)}`, allowStaleData: true, @@ -784,10 +768,6 @@ export default withCurrentReportID( hasLoadingNewerReportActionsError: false, }, }, - isComposerFullSize: { - key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT_IS_COMPOSER_FULL_SIZE}${getReportID(route)}`, - initialValue: false, - }, betas: { key: ONYXKEYS.BETAS, }, @@ -795,42 +775,19 @@ export default withCurrentReportID( key: ONYXKEYS.COLLECTION.POLICY, allowStaleData: true, }, - accountManagerReportID: { - key: ONYXKEYS.ACCOUNT_MANAGER_REPORT_ID, - initialValue: null, - }, - userLeavingStatus: { - key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT_USER_IS_LEAVING_ROOM}${getReportID(route)}`, - initialValue: false, - }, }, true, )( - withOnyx({ - parentReportActions: { - key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report ? report.parentReportID : 0}`, - canEvict: false, - }, - })( - memo(ReportScreen, (prevProps, nextProps) => { - const prevParentReportAction = getParentReportAction(prevProps.parentReportActions, prevProps.report?.parentReportActionID); - const nextParentReportAction = getParentReportAction(nextProps.parentReportActions, nextProps.report?.parentReportActionID); - return ( - prevProps.isSidebarLoaded === nextProps.isSidebarLoaded && - lodashIsEqual(prevProps.sortedAllReportActions, nextProps.sortedAllReportActions) && - lodashIsEqual(prevProps.reportMetadata, nextProps.reportMetadata) && - prevProps.isComposerFullSize === nextProps.isComposerFullSize && - lodashIsEqual(prevProps.betas, nextProps.betas) && - lodashIsEqual(prevProps.policies, nextProps.policies) && - prevProps.accountManagerReportID === nextProps.accountManagerReportID && - prevProps.userLeavingStatus === nextProps.userLeavingStatus && - prevProps.currentReportID === nextProps.currentReportID && - lodashIsEqual(prevProps.modal, nextProps.modal) && - lodashIsEqual(prevParentReportAction, nextParentReportAction) && - lodashIsEqual(prevProps.route, nextProps.route) && - lodashIsEqual(prevProps.report, nextProps.report) - ); - }), + memo( + ReportScreen, + (prevProps, nextProps) => + prevProps.isSidebarLoaded === nextProps.isSidebarLoaded && + lodashIsEqual(prevProps.sortedAllReportActions, nextProps.sortedAllReportActions) && + lodashIsEqual(prevProps.reportMetadata, nextProps.reportMetadata) && + lodashIsEqual(prevProps.betas, nextProps.betas) && + lodashIsEqual(prevProps.policies, nextProps.policies) && + prevProps.currentReportID === nextProps.currentReportID && + lodashIsEqual(prevProps.route, nextProps.route), ), ), ); diff --git a/src/pages/home/report/ReportActionsView.tsx b/src/pages/home/report/ReportActionsView.tsx index d1e45f3998cd..982fe49a4c44 100755 --- a/src/pages/home/report/ReportActionsView.tsx +++ b/src/pages/home/report/ReportActionsView.tsx @@ -630,6 +630,7 @@ export default Performance.withRenderTrace({id: ' rendering'} }, transactionThreadReport: { key: ({transactionThreadReportID}) => `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`, + initialValue: {} as OnyxTypes.Report, }, })(MemoizedReportActionsView), );