|
| 1 | +import type {ListRenderItemInfo} from '@react-native/virtualized-lists/Lists/VirtualizedList'; |
| 2 | +import React, {useCallback, useMemo} from 'react'; |
| 3 | +import {View} from 'react-native'; |
| 4 | +import type {OnyxEntry} from 'react-native-onyx'; |
| 5 | +import {useOnyx} from 'react-native-onyx'; |
| 6 | +import FlatList from '@components/FlatList'; |
| 7 | +import ReportActionsSkeletonView from '@components/ReportActionsSkeletonView'; |
| 8 | +import usePaginatedReportActions from '@hooks/usePaginatedReportActions'; |
| 9 | +import useThemeStyles from '@hooks/useThemeStyles'; |
| 10 | +import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; |
| 11 | +import { |
| 12 | + getMostRecentIOURequestActionID, |
| 13 | + getOneTransactionThreadReportID, |
| 14 | + getSortedReportActionsForDisplay, |
| 15 | + isConsecutiveActionMadeByPreviousActor, |
| 16 | + isConsecutiveChronosAutomaticTimerAction, |
| 17 | + isDeletedParentAction, |
| 18 | + shouldReportActionBeVisible, |
| 19 | +} from '@libs/ReportActionsUtils'; |
| 20 | +import {canUserPerformWriteAction, chatIncludesChronosWithID} from '@libs/ReportUtils'; |
| 21 | +import ReportActionsListItemRenderer from '@pages/home/report/ReportActionsListItemRenderer'; |
| 22 | +import CONST from '@src/CONST'; |
| 23 | +import ONYXKEYS from '@src/ONYXKEYS'; |
| 24 | +import type * as OnyxTypes from '@src/types/onyx'; |
| 25 | +import type Transaction from '@src/types/onyx/Transaction'; |
| 26 | +import {isEmptyObject} from '@src/types/utils/EmptyObject'; |
| 27 | +import MoneyRequestReportTransactionList from './MoneyRequestReportTransactionList'; |
| 28 | + |
| 29 | +type TemporaryMoneyRequestReportViewProps = { |
| 30 | + /** The report */ |
| 31 | + report: OnyxEntry<OnyxTypes.Report>; |
| 32 | +}; |
| 33 | + |
| 34 | +function getParentReportAction(parentReportActions: OnyxEntry<OnyxTypes.ReportActions>, parentReportActionID: string | undefined): OnyxEntry<OnyxTypes.ReportAction> { |
| 35 | + if (!parentReportActions || !parentReportActionID) { |
| 36 | + return; |
| 37 | + } |
| 38 | + return parentReportActions[parentReportActionID]; |
| 39 | +} |
| 40 | + |
| 41 | +/** |
| 42 | + * TODO |
| 43 | + * This component is under construction and not yet displayed to any users. |
| 44 | + */ |
| 45 | +function MoneyRequestReportView({report}: TemporaryMoneyRequestReportViewProps) { |
| 46 | + const styles = useThemeStyles(); |
| 47 | + |
| 48 | + const reportID = report?.reportID; |
| 49 | + |
| 50 | + // const [accountManagerReportID] = useOnyx(ONYXKEYS.ACCOUNT_MANAGER_REPORT_ID); |
| 51 | + // const [accountManagerReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${getNonEmptyStringOnyxID(accountManagerReportID)}`); |
| 52 | + // const [userLeavingStatus = false] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_USER_IS_LEAVING_ROOM}${reportID}`); |
| 53 | + const [reportOnyx] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {allowStaleData: true}); |
| 54 | + // const [reportNameValuePairsOnyx] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${reportID}`, {allowStaleData: true}); |
| 55 | + const [parentReportAction] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${getNonEmptyStringOnyxID(reportOnyx?.parentReportID)}`, { |
| 56 | + canEvict: false, |
| 57 | + selector: (parentReportActions) => getParentReportAction(parentReportActions, reportOnyx?.parentReportActionID), |
| 58 | + }); |
| 59 | + |
| 60 | + const {reportActions, linkedAction, sortedAllReportActions, hasNewerActions, hasOlderActions} = usePaginatedReportActions(reportID); |
| 61 | + |
| 62 | + const mostRecentIOUReportActionID = useMemo(() => getMostRecentIOURequestActionID(reportActions), [reportActions]); |
| 63 | + |
| 64 | + const transactionThreadReportID = getOneTransactionThreadReportID(reportID, reportActions ?? [], false); |
| 65 | + const [transactionThreadReportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReportID ?? CONST.DEFAULT_NUMBER_ID}`, { |
| 66 | + selector: (actions: OnyxEntry<OnyxTypes.ReportActions>) => getSortedReportActionsForDisplay(actions, canUserPerformWriteAction(report), true), |
| 67 | + }); |
| 68 | + |
| 69 | + const [transactions = {}] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION); |
| 70 | + |
| 71 | + const isOffline = false; |
| 72 | + |
| 73 | + const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID ?? CONST.DEFAULT_NUMBER_ID}`); |
| 74 | + |
| 75 | + const actionsChatItem = reportActions.filter((ra) => { |
| 76 | + return ra.actionName !== 'IOU' && ra.actionName !== CONST.REPORT.ACTIONS.TYPE.CREATED; |
| 77 | + }); |
| 78 | + |
| 79 | + // // Get a sorted array of reportActions for both the current report and the transaction thread report associated with this report (if there is one) |
| 80 | + // // so that we display transaction-level and report-level report actions in order in the one-transaction view |
| 81 | + // const reportActions2 = useMemo( |
| 82 | + // () => (reportActionsToDisplay ? getCombinedReportActions(reportActionsToDisplay, transactionThreadReportID ?? null, transactionThreadReportActions ?? []) : []), |
| 83 | + // [reportActionsToDisplay, transactionThreadReportActions, transactionThreadReportID], |
| 84 | + // ); |
| 85 | + |
| 86 | + /* Thread's divider line should hide when the first chat in the thread is marked as unread. |
| 87 | + * This is so that it will not be conflicting with header's separator line. |
| 88 | + */ |
| 89 | + // const shouldHideThreadDividerLine = useMemo( |
| 90 | + // (): boolean => getFirstVisibleReportActionID(reportActions, isOffline) === unreadMarkerReportActionID, |
| 91 | + // [reportActions, isOffline, unreadMarkerReportActionID], |
| 92 | + // ); |
| 93 | + |
| 94 | + const parentReportActionForTransactionThread = useMemo( |
| 95 | + () => |
| 96 | + isEmptyObject(transactionThreadReportActions) |
| 97 | + ? undefined |
| 98 | + : (reportActions?.find((action) => action.reportActionID === transactionThreadReport?.parentReportActionID) as OnyxEntry<OnyxTypes.ReportAction>), |
| 99 | + [reportActions, transactionThreadReportActions, transactionThreadReport?.parentReportActionID], |
| 100 | + ); |
| 101 | + |
| 102 | + const canPerformWriteAction = canUserPerformWriteAction(report); |
| 103 | + const visibleReportActions = useMemo(() => { |
| 104 | + const filteredActions = actionsChatItem.filter( |
| 105 | + (reportAction) => |
| 106 | + (isOffline || isDeletedParentAction(reportAction) || reportAction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || reportAction.errors) && |
| 107 | + shouldReportActionBeVisible(reportAction, reportAction.reportActionID, canPerformWriteAction), |
| 108 | + ); |
| 109 | + |
| 110 | + return [...filteredActions].toReversed(); |
| 111 | + }, [actionsChatItem, isOffline, canPerformWriteAction]); |
| 112 | + |
| 113 | + const transactionList = Object.values(transactions).filter((transaction): transaction is Transaction => { |
| 114 | + return transaction?.reportID === reportID; |
| 115 | + }); |
| 116 | + |
| 117 | + const renderItem = useCallback( |
| 118 | + ({item: reportAction, index}: ListRenderItemInfo<OnyxTypes.ReportAction>) => ( |
| 119 | + <ReportActionsListItemRenderer |
| 120 | + reportAction={reportAction} |
| 121 | + parentReportAction={parentReportAction} |
| 122 | + parentReportActionForTransactionThread={parentReportActionForTransactionThread} |
| 123 | + index={index} |
| 124 | + report={report} |
| 125 | + transactionThreadReport={transactionThreadReport} |
| 126 | + displayAsGroup={ |
| 127 | + !isConsecutiveChronosAutomaticTimerAction(visibleReportActions, index, chatIncludesChronosWithID(reportAction?.reportID)) && |
| 128 | + isConsecutiveActionMadeByPreviousActor(visibleReportActions, index) |
| 129 | + } |
| 130 | + mostRecentIOUReportActionID={mostRecentIOUReportActionID} |
| 131 | + shouldHideThreadDividerLine |
| 132 | + shouldDisplayNewMarker={false} |
| 133 | + // shouldHideThreadDividerLine={shouldHideThreadDividerLine} |
| 134 | + // shouldDisplayNewMarker={reportAction.reportActionID === unreadMarkerReportActionID} |
| 135 | + // shouldUseThreadDividerLine={shouldUseThreadDividerLine} |
| 136 | + shouldDisplayReplyDivider={visibleReportActions.length > 1} |
| 137 | + isFirstVisibleReportAction={false} |
| 138 | + /> |
| 139 | + ), |
| 140 | + [ |
| 141 | + report, |
| 142 | + visibleReportActions, |
| 143 | + mostRecentIOUReportActionID, |
| 144 | + parentReportAction, |
| 145 | + transactionThreadReport, |
| 146 | + parentReportActionForTransactionThread, |
| 147 | + // unreadMarkerReportActionID, |
| 148 | + // shouldHideThreadDividerLine, |
| 149 | + // shouldUseThreadDividerLine, |
| 150 | + // firstVisibleReportActionID, |
| 151 | + ], |
| 152 | + ); |
| 153 | + |
| 154 | + const listHeaderComponent = ( |
| 155 | + <MoneyRequestReportTransactionList |
| 156 | + transactions={transactionList} |
| 157 | + report={report} |
| 158 | + /> |
| 159 | + ); |
| 160 | + |
| 161 | + return ( |
| 162 | + <View style={styles.flex1}> |
| 163 | + {report ? ( |
| 164 | + <FlatList |
| 165 | + accessibilityLabel="Test" |
| 166 | + testID="report-actions-list" |
| 167 | + style={styles.overscrollBehaviorContain} |
| 168 | + data={visibleReportActions} |
| 169 | + renderItem={renderItem} |
| 170 | + keyExtractor={(item) => item.reportActionID} |
| 171 | + initialNumToRender={10} |
| 172 | + // onEndReached={onEndReached} |
| 173 | + onEndReachedThreshold={0.75} |
| 174 | + // onStartReached={onStartReached} |
| 175 | + onStartReachedThreshold={0.75} |
| 176 | + ListHeaderComponent={listHeaderComponent} |
| 177 | + keyboardShouldPersistTaps="handled" |
| 178 | + // onLayout={onLayoutInner} |
| 179 | + // onContentSizeChange={onContentSizeChangeInner} |
| 180 | + // onScroll={trackVerticalScrolling} |
| 181 | + // onScrollToIndexFailed={onScrollToIndexFailed} |
| 182 | + // extraData={extraData} |
| 183 | + // key={listID} |
| 184 | + // shouldEnableAutoScrollToTopThreshold={shouldEnableAutoScrollToTopThreshold} |
| 185 | + // initialScrollKey={reportActionID} |
| 186 | + /> |
| 187 | + ) : ( |
| 188 | + <ReportActionsSkeletonView /> |
| 189 | + )} |
| 190 | + </View> |
| 191 | + ); |
| 192 | +} |
| 193 | + |
| 194 | +MoneyRequestReportView.displayName = 'MoneyRequestReportView'; |
| 195 | + |
| 196 | +export default MoneyRequestReportView; |
0 commit comments