Skip to content

Commit c6a9e43

Browse files
committed
improve ReportActionItem performance
1 parent 15aa1ad commit c6a9e43

13 files changed

Lines changed: 275 additions & 40 deletions

Mobile-Expensify

src/components/MoneyRequestReportView/MoneyRequestReportActionsList.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import ConfirmModal from '@components/ConfirmModal';
1212
import DecisionModal from '@components/DecisionModal';
1313
import FlatList from '@components/FlatList';
1414
import {AUTOSCROLL_TO_TOP_THRESHOLD} from '@components/InvertedFlatList/BaseInvertedFlatList';
15+
import {usePersonalDetails} from '@components/OnyxListItemProvider';
1516
import {PressableWithFeedback} from '@components/Pressable';
1617
import {useSearchContext} from '@components/Search/SearchContext';
1718
import Text from '@components/Text';
@@ -141,6 +142,11 @@ function MoneyRequestReportActionsList({
141142
selector: (parentReportActions) => getParentReportAction(parentReportActions, report?.parentReportActionID),
142143
});
143144

145+
const [userWallet] = useOnyx(ONYXKEYS.USER_WALLET, {canBeMissing: false});
146+
const [isUserValidated] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => account?.validated, canBeMissing: true});
147+
const [userBillingFundID] = useOnyx(ONYXKEYS.NVP_BILLING_FUND_ID, {canBeMissing: true});
148+
const personalDetails = usePersonalDetails();
149+
144150
const transactionsWithoutPendingDelete = useMemo(() => transactions.filter((t) => !isTransactionPendingDelete(t)), [transactions]);
145151
const mostRecentIOUReportActionID = useMemo(() => getMostRecentIOURequestActionID(reportActions), [reportActions]);
146152
const transactionThreadReportID = getOneTransactionThreadReportID(report, chatReport, reportActions ?? [], false, reportTransactionIDs);
@@ -489,6 +495,10 @@ function MoneyRequestReportActionsList({
489495
isFirstVisibleReportAction={firstVisibleReportActionID === reportAction.reportActionID}
490496
shouldHideThreadDividerLine
491497
linkedReportActionID={linkedReportActionID}
498+
userWallet={userWallet}
499+
isUserValidated={isUserValidated}
500+
personalDetails={personalDetails}
501+
userBillingFundID={userBillingFundID}
492502
/>
493503
);
494504
},
@@ -504,6 +514,10 @@ function MoneyRequestReportActionsList({
504514
linkedReportActionID,
505515
allReports,
506516
policies,
517+
userWallet,
518+
isUserValidated,
519+
personalDetails,
520+
userBillingFundID,
507521
],
508522
);
509523

src/components/Search/SearchList.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Checkbox from '@components/Checkbox';
1010
import * as Expensicons from '@components/Icon/Expensicons';
1111
import MenuItem from '@components/MenuItem';
1212
import Modal from '@components/Modal';
13+
import {usePersonalDetails} from '@components/OnyxListItemProvider';
1314
import {PressableWithFeedback} from '@components/Pressable';
1415
import type ChatListItem from '@components/SelectionList/ChatListItem';
1516
import type TaskListItem from '@components/SelectionList/Search/TaskListItem';
@@ -174,6 +175,12 @@ function SearchList(
174175

175176
const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT, {canBeMissing: false});
176177

178+
const personalDetails = usePersonalDetails();
179+
180+
const [userWallet] = useOnyx(ONYXKEYS.USER_WALLET, {canBeMissing: false});
181+
const [isUserValidated] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => account?.validated, canBeMissing: true});
182+
const [userBillingFundID] = useOnyx(ONYXKEYS.NVP_BILLING_FUND_ID, {canBeMissing: true});
183+
177184
const handleLongPressRow = useCallback(
178185
(item: SearchListItem) => {
179186
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
@@ -342,15 +349,19 @@ function SearchList(
342349
isDisabled={isDisabled}
343350
allReports={allReports}
344351
groupBy={groupBy}
352+
userWallet={userWallet}
353+
isUserValidated={isUserValidated}
354+
personalDetails={personalDetails}
355+
userBillingFundID={userBillingFundID}
345356
/>
346357
);
347358
},
348359
[
349360
ListItem,
350361
canSelectMultiple,
351362
focusedIndex,
352-
handleLongPressRow,
353363
itemsToHighlight,
364+
handleLongPressRow,
354365
onCheckboxPress,
355366
onSelectRow,
356367
policies,
@@ -359,6 +370,10 @@ function SearchList(
359370
setFocusedIndex,
360371
shouldPreventDefaultFocusOnSelectRow,
361372
allReports,
373+
userWallet,
374+
isUserValidated,
375+
personalDetails,
376+
userBillingFundID,
362377
],
363378
);
364379

src/components/SelectionList/BaseSelectionListItemRenderer.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import React from 'react';
22
import type {NativeSyntheticEvent, StyleProp, TextStyle, ViewStyle} from 'react-native';
3+
import type {OnyxEntry} from 'react-native-onyx';
34
import type useArrowKeyFocusManager from '@hooks/useArrowKeyFocusManager';
45
import type useSingleExecution from '@hooks/useSingleExecution';
56
import {isMobileChrome} from '@libs/Browser';
67
import {isTransactionGroupListItemType} from '@libs/SearchUIUtils';
8+
import type {PersonalDetailsList, UserWallet} from '@src/types/onyx';
79
import type {BaseListItemProps, ExtendedTargetedEvent, ListItem, SelectionListProps} from './types';
810

911
type BaseSelectionListItemRendererProps<TItem extends ListItem> = Omit<BaseListItemProps<TItem>, 'onSelectRow'> &
@@ -15,6 +17,10 @@ type BaseSelectionListItemRendererProps<TItem extends ListItem> = Omit<BaseListI
1517
singleExecution: ReturnType<typeof useSingleExecution>['singleExecution'];
1618
titleStyles?: StyleProp<TextStyle>;
1719
titleContainerStyles?: StyleProp<ViewStyle>;
20+
userWallet?: OnyxEntry<UserWallet>;
21+
isUserValidated?: boolean | undefined;
22+
personalDetails?: OnyxEntry<PersonalDetailsList>;
23+
userBillingFundID?: number | undefined;
1824
};
1925

2026
function BaseSelectionListItemRenderer<TItem extends ListItem>({
@@ -45,6 +51,10 @@ function BaseSelectionListItemRenderer<TItem extends ListItem>({
4551
titleContainerStyles,
4652
shouldUseDefaultRightHandSideCheckmark,
4753
canShowProductTrainingTooltip = true,
54+
userWallet,
55+
isUserValidated,
56+
personalDetails,
57+
userBillingFundID,
4858
}: BaseSelectionListItemRendererProps<TItem>) {
4959
const handleOnCheckboxPress = () => {
5060
if (isTransactionGroupListItemType(item)) {
@@ -96,6 +106,10 @@ function BaseSelectionListItemRenderer<TItem extends ListItem>({
96106
titleContainerStyles={titleContainerStyles}
97107
shouldUseDefaultRightHandSideCheckmark={shouldUseDefaultRightHandSideCheckmark}
98108
canShowProductTrainingTooltip={canShowProductTrainingTooltip}
109+
userWallet={userWallet}
110+
isUserValidated={isUserValidated}
111+
personalDetails={personalDetails}
112+
userBillingFundID={userBillingFundID}
99113
/>
100114
{item.footerContent && item.footerContent}
101115
</>

src/components/SelectionList/ChatListItem.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ function ChatListItem<TItem extends ListItem>({
2323
shouldSyncFocus,
2424
policies,
2525
allReports,
26+
userWallet,
27+
isUserValidated,
28+
personalDetails,
29+
userBillingFundID,
2630
}: ChatListItemProps<TItem>) {
2731
const reportActionItem = item as unknown as ReportActionListItemType;
2832
const reportID = Number(reportActionItem?.reportID ?? CONST.DEFAULT_NUMBER_ID);
@@ -93,6 +97,10 @@ function ChatListItem<TItem extends ListItem>({
9397
}
9498
policies={policies}
9599
shouldShowBorder
100+
userWallet={userWallet}
101+
isUserValidated={isUserValidated}
102+
personalDetails={personalDetails}
103+
userBillingFundID={userBillingFundID}
96104
/>
97105
</BaseListItem>
98106
);

src/components/SelectionList/types.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type {
1212
TextStyle,
1313
ViewStyle,
1414
} from 'react-native';
15-
import type {OnyxCollection} from 'react-native-onyx';
15+
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
1616
import type {AnimatedStyle} from 'react-native-reanimated';
1717
import type {SearchRouterItem} from '@components/Search/SearchAutocompleteList';
1818
import type {SearchColumnType, SearchGroupBy} from '@components/Search/types';
@@ -22,7 +22,7 @@ import type SpendCategorySelectorListItem from '@pages/workspace/categories/Spen
2222
// eslint-disable-next-line no-restricted-imports
2323
import type CursorStyles from '@styles/utils/cursor/types';
2424
import type CONST from '@src/CONST';
25-
import type {Policy, Report, TransactionViolation} from '@src/types/onyx';
25+
import type {PersonalDetailsList, Policy, Report, TransactionViolation, UserWallet} from '@src/types/onyx';
2626
import type {Attendee, SplitExpense} from '@src/types/onyx/IOU';
2727
import type {Errors, Icon, PendingAction} from '@src/types/onyx/OnyxCommon';
2828
import type {SearchCard, SearchPersonalDetails, SearchReport, SearchReportAction, SearchTask, SearchTransaction} from '@src/types/onyx/SearchResults';
@@ -477,6 +477,18 @@ type ChatListItemProps<TItem extends ListItem> = ListItemProps<TItem> & {
477477

478478
/** The report data */
479479
report?: Report;
480+
481+
/** The user wallet */
482+
userWallet: OnyxEntry<UserWallet>;
483+
484+
/** Whether the user is validated */
485+
isUserValidated: boolean | undefined;
486+
487+
/** Personal details list */
488+
personalDetails: OnyxEntry<PersonalDetailsList>;
489+
490+
/** User billing fund ID */
491+
userBillingFundID: number | undefined;
480492
};
481493

482494
type ValidListItem =

src/pages/Debug/ReportAction/DebugReportActionCreatePage.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ function DebugReportActionCreatePage({
5050
const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: false});
5151
const [session] = useOnyx(ONYXKEYS.SESSION, {canBeMissing: false});
5252
const [personalDetailsList] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {canBeMissing: false});
53+
const [userWallet] = useOnyx(ONYXKEYS.USER_WALLET, {canBeMissing: true});
54+
const [isUserValidated] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => account?.validated, canBeMissing: true});
5355
const [draftReportAction, setDraftReportAction] = useState<string>(() => getInitialReportAction(reportID, session, personalDetailsList));
56+
const [userBillingFundID] = useOnyx(ONYXKEYS.NVP_BILLING_FUND_ID, {canBeMissing: true});
57+
5458
const [error, setError] = useState<string>();
5559

5660
const createReportAction = useCallback(() => {
@@ -120,6 +124,13 @@ function DebugReportActionCreatePage({
120124
index={0}
121125
isFirstVisibleReportAction={false}
122126
shouldDisplayContextMenu={false}
127+
userWallet={userWallet}
128+
isUserValidated={isUserValidated}
129+
personalDetails={personalDetailsList}
130+
userBillingFundID={userBillingFundID}
131+
draftMessage={undefined}
132+
emojiReactions={undefined}
133+
linkedTransactionRouteError={undefined}
123134
/>
124135
) : (
125136
<Text>{translate('debug.nothingToPreview')}</Text>

src/pages/Debug/ReportAction/DebugReportActionPreview.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ type DebugReportActionPreviewProps = {
1717
function DebugReportActionPreview({reportAction, reportID}: DebugReportActionPreviewProps) {
1818
const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT, {canBeMissing: false});
1919
const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: false});
20+
const [userWallet] = useOnyx(ONYXKEYS.USER_WALLET, {canBeMissing: true});
21+
const [isUserValidated] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => account?.validated, canBeMissing: true});
22+
const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {canBeMissing: true});
23+
const [userBillingFundID] = useOnyx(ONYXKEYS.NVP_BILLING_FUND_ID, {canBeMissing: true});
2024
const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];
2125

2226
return (
@@ -34,6 +38,10 @@ function DebugReportActionPreview({reportAction, reportID}: DebugReportActionPre
3438
index={0}
3539
isFirstVisibleReportAction={false}
3640
shouldDisplayContextMenu={false}
41+
userWallet={userWallet}
42+
isUserValidated={isUserValidated}
43+
personalDetails={personalDetails}
44+
userBillingFundID={userBillingFundID}
3745
/>
3846
</ScrollView>
3947
);

src/pages/TransactionDuplicate/DuplicateTransactionItem.tsx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import {getOriginalMessage, getReportAction, isMoneyRequestAction} from '@libs/R
77
import ReportActionItem from '@pages/home/report/ReportActionItem';
88
import CONST from '@src/CONST';
99
import ONYXKEYS from '@src/ONYXKEYS';
10-
import type {Policy, Report, Transaction} from '@src/types/onyx';
10+
import type {Policy, Report, Transaction, ReportActionsDrafts} from '@src/types/onyx';
11+
import { getOriginalReportID } from '@libs/ReportUtils';
12+
13+
1114

1215
type DuplicateTransactionItemProps = {
1316
transaction: OnyxEntry<Transaction>;
@@ -19,6 +22,10 @@ type DuplicateTransactionItemProps = {
1922

2023
function DuplicateTransactionItem({transaction, index, allReports, policies}: DuplicateTransactionItemProps) {
2124
const styles = useThemeStyles();
25+
const [userWallet] = useOnyx(ONYXKEYS.USER_WALLET, {canBeMissing: true});
26+
const [isUserValidated] = useOnyx(ONYXKEYS.ACCOUNT, {selector: (account) => account?.validated, canBeMissing: true});
27+
const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {canBeMissing: true});
28+
const [userBillingFundID] = useOnyx(ONYXKEYS.NVP_BILLING_FUND_ID, {canBeMissing: true});
2229
const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`];
2330
const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.reportID}`, {canBeMissing: false});
2431

@@ -28,6 +35,20 @@ function DuplicateTransactionItem({transaction, index, allReports, policies}: Du
2835
return IOUTransactionID === transaction?.transactionID;
2936
});
3037

38+
const originalReportID = getOriginalReportID(report?.reportID, action);
39+
40+
const [draftMessage] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${originalReportID}`, {
41+
canBeMissing: true});
42+
43+
const [emojiReactions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}${action?.reportActionID}`, {
44+
canBeMissing: true,
45+
});
46+
47+
const [linkedTransactionRouteError] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${isMoneyRequestAction(action) && getOriginalMessage(action)?.IOUTransactionID}`, {
48+
canBeMissing: true,
49+
selector: (transactionItem) => transactionItem?.errorFields?.route ?? null,
50+
});
51+
3152
if (!action || !report) {
3253
return null;
3354
}
@@ -47,6 +68,13 @@ function DuplicateTransactionItem({transaction, index, allReports, policies}: Du
4768
isMostRecentIOUReportAction={false}
4869
isFirstVisibleReportAction={false}
4970
shouldDisplayContextMenu={false}
71+
userWallet={userWallet}
72+
isUserValidated={isUserValidated}
73+
personalDetails={personalDetails}
74+
draftMessage={draftMessage as OnyxEntry<string & ReportActionsDrafts>}
75+
emojiReactions={emojiReactions}
76+
linkedTransactionRouteError={linkedTransactionRouteError}
77+
userBillingFundID={userBillingFundID ?? 0}
5078
/>
5179
</View>
5280
);

0 commit comments

Comments
 (0)