|
| 1 | +import {useMemo, useState} from 'react'; |
| 2 | +import type {OnyxEntry} from 'react-native-onyx'; |
| 3 | +import {getReportPreviewAction} from '@libs/actions/IOU/MoneyRequestBuilder'; |
| 4 | +import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; |
| 5 | +import {getCombinedReportActions, getFilteredReportActionsForReportView, isCreatedAction} from '@libs/ReportActionsUtils'; |
| 6 | +import {isConciergeChatReport, isInvoiceReport, isMoneyRequestReport, isReportTransactionThread as isReportTransactionThreadUtil} from '@libs/ReportUtils'; |
| 7 | +import getReportActionsToDisplay from '@pages/inbox/report/getReportActionsToDisplay'; |
| 8 | +import ONYXKEYS from '@src/ONYXKEYS'; |
| 9 | +import type {Pages, Report, ReportAction} from '@src/types/onyx'; |
| 10 | +import useIsInSidePanel from './useIsInSidePanel'; |
| 11 | +import useNetwork from './useNetwork'; |
| 12 | +import useOnyx from './useOnyx'; |
| 13 | +import usePaginatedReportActions from './usePaginatedReportActions'; |
| 14 | +import useTransactionThread from './useTransactionThread'; |
| 15 | + |
| 16 | +type UseReportActionsPaginationResult = { |
| 17 | + reportActions: ReportAction[]; |
| 18 | + allReportActions: ReportAction[]; |
| 19 | + allReportActionIDs: string[]; |
| 20 | + hasOlderActions: boolean; |
| 21 | + hasNewerActions: boolean; |
| 22 | + sortedAllReportActions: ReportAction[] | undefined; |
| 23 | + oldestUnreadReportAction: ReportAction | undefined; |
| 24 | + reportActionPages: OnyxEntry<Pages>; |
| 25 | + transactionThreadReportID: string | undefined; |
| 26 | + transactionThreadReport: OnyxEntry<Report>; |
| 27 | + parentReportActionForTransactionThread: ReportAction | undefined; |
| 28 | + shouldAddCreatedAction: boolean; |
| 29 | + treatAsNoPaginationAnchor: boolean; |
| 30 | + setTreatAsNoPaginationAnchor: (value: boolean) => void; |
| 31 | +}; |
| 32 | + |
| 33 | +function useReportActionsPagination(reportID: string | undefined, reportActionIDFromRoute: string | undefined): UseReportActionsPaginationResult { |
| 34 | + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); |
| 35 | + const {isOffline} = useNetwork(); |
| 36 | + |
| 37 | + const [treatAsNoPaginationAnchor, setTreatAsNoPaginationAnchor] = useState(false); |
| 38 | + const nonEmptyReportIDForPages = getNonEmptyStringOnyxID(reportID); |
| 39 | + const [reportActionPages] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_PAGES}${nonEmptyReportIDForPages}`); |
| 40 | + |
| 41 | + const { |
| 42 | + reportActions: unfilteredReportActions, |
| 43 | + hasOlderActions, |
| 44 | + hasNewerActions, |
| 45 | + sortedAllReportActions, |
| 46 | + oldestUnreadReportAction, |
| 47 | + } = usePaginatedReportActions(reportID, reportActionIDFromRoute, { |
| 48 | + shouldLinkToOldestUnreadReportAction: true, |
| 49 | + treatAsNoPaginationAnchor, |
| 50 | + }); |
| 51 | + const allReportActions = useMemo(() => getFilteredReportActionsForReportView(unfilteredReportActions), [unfilteredReportActions]); |
| 52 | + |
| 53 | + const thread = useTransactionThread({reportID, report, allReportActions, isOffline}); |
| 54 | + |
| 55 | + const isInSidePanel = useIsInSidePanel(); |
| 56 | + const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); |
| 57 | + const isConciergeSidePanel = isInSidePanel && isConciergeChatReport(report, conciergeReportID); |
| 58 | + |
| 59 | + const [reportLoadingState] = useOnyx(`${ONYXKEYS.COLLECTION.RAM_ONLY_REPORT_LOADING_STATE}${reportID}`); |
| 60 | + const isLoadingInitialReportActions = reportLoadingState?.isLoadingInitialReportActions; |
| 61 | + |
| 62 | + const isReportTransactionThread = isReportTransactionThreadUtil(report); |
| 63 | + const isInitiallyLoadingTransactionThread = isReportTransactionThread && (!!isLoadingInitialReportActions || (allReportActions ?? [])?.length <= 1); |
| 64 | + |
| 65 | + const lastAction = allReportActions?.at(-1); |
| 66 | + const shouldAddCreatedAction = !isCreatedAction(lastAction) && (isMoneyRequestReport(report) || isInvoiceReport(report) || isInitiallyLoadingTransactionThread || isConciergeSidePanel); |
| 67 | + |
| 68 | + const reportPreviewAction = useMemo(() => getReportPreviewAction(report?.chatReportID, report?.reportID), [report?.chatReportID, report?.reportID]); |
| 69 | + |
| 70 | + // When we are offline before opening an IOU/Expense report, |
| 71 | + // the total of the report and sometimes the expense aren't displayed because these actions aren't returned until `OpenReport` API is complete. |
| 72 | + // We generate a fake created action here if it doesn't exist to display the total whenever possible because the total just depends on report data |
| 73 | + // and we also generate an expense action if the number of expenses in allReportActions is less than the total number of expenses |
| 74 | + // to display at least one expense action to match the total data. |
| 75 | + const reportActionsToDisplay = useMemo( |
| 76 | + () => getReportActionsToDisplay(allReportActions, lastAction, report, reportPreviewAction, thread.transactionThreadReport, shouldAddCreatedAction), |
| 77 | + [allReportActions, lastAction, report, reportPreviewAction, shouldAddCreatedAction, thread.transactionThreadReport], |
| 78 | + ); |
| 79 | + |
| 80 | + const reportActions = useMemo( |
| 81 | + () => (reportActionsToDisplay ? getCombinedReportActions(reportActionsToDisplay, thread.transactionThreadReportID ?? null, thread.transactionThreadReportActions ?? []) : []), |
| 82 | + [reportActionsToDisplay, thread.transactionThreadReportActions, thread.transactionThreadReportID], |
| 83 | + ); |
| 84 | + |
| 85 | + const allReportActionIDs = useMemo(() => allReportActions.map((action) => action.reportActionID), [allReportActions]); |
| 86 | + |
| 87 | + return { |
| 88 | + reportActions, |
| 89 | + allReportActions, |
| 90 | + allReportActionIDs, |
| 91 | + hasOlderActions, |
| 92 | + hasNewerActions, |
| 93 | + sortedAllReportActions, |
| 94 | + oldestUnreadReportAction, |
| 95 | + reportActionPages, |
| 96 | + transactionThreadReportID: thread.transactionThreadReportID, |
| 97 | + transactionThreadReport: thread.transactionThreadReport, |
| 98 | + parentReportActionForTransactionThread: thread.parentReportActionForTransactionThread, |
| 99 | + shouldAddCreatedAction, |
| 100 | + treatAsNoPaginationAnchor, |
| 101 | + setTreatAsNoPaginationAnchor, |
| 102 | + }; |
| 103 | +} |
| 104 | + |
| 105 | +export default useReportActionsPagination; |
0 commit comments