Skip to content

Commit 7866007

Browse files
authored
Merge pull request #91416 from callstack-internal/perf/report-item-personal-details-v2
refactor: remove personalDetails from ReportActionsList dependencies
2 parents 92b1883 + 2ae2fc2 commit 7866007

25 files changed

Lines changed: 673 additions & 215 deletions

src/components/MoneyRequestReportView/MoneyRequestReportActionsList.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import type {LayoutChangeEvent, ListRenderItemInfo, NativeScrollEvent, NativeSyn
66
// eslint-disable-next-line no-restricted-imports
77
import {DeviceEventEmitter, InteractionManager, View} from 'react-native';
88
import FlatListWithScrollKey from '@components/FlatList/FlatListWithScrollKey';
9-
import {usePersonalDetails} from '@components/OnyxListItemProvider';
109
import ScrollView from '@components/ScrollView';
1110
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
1211
import useLoadReportActions from '@hooks/useLoadReportActions';
@@ -128,7 +127,6 @@ function MoneyRequestReportActionsList({onLayout}: MoneyRequestReportListProps)
128127

129128
const parentReportAction = useParentReportAction(report);
130129

131-
const personalDetails = usePersonalDetails();
132130
const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED);
133131
const [betas] = useOnyx(ONYXKEYS.BETAS);
134132

@@ -567,7 +565,6 @@ function MoneyRequestReportActionsList({onLayout}: MoneyRequestReportListProps)
567565
isFirstVisibleReportAction={firstVisibleReportActionID === reportAction.reportActionID}
568566
shouldHideThreadDividerLine
569567
linkedReportActionID={linkedReportActionID}
570-
personalDetails={personalDetails}
571568
isHarvestCreatedExpenseReport={shouldShowHarvestCreatedAction}
572569
/>
573570
</ReportActionIndexContext.Provider>
@@ -582,7 +579,6 @@ function MoneyRequestReportActionsList({onLayout}: MoneyRequestReportListProps)
582579
unreadMarkerReportActionID,
583580
firstVisibleReportActionID,
584581
linkedReportActionID,
585-
personalDetails,
586582
shouldShowHarvestCreatedAction,
587583
],
588584
);

src/components/Search/SearchList/ListItem/ChatListItem.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React from 'react';
2-
import {usePersonalDetails} from '@components/OnyxListItemProvider';
32
import BaseListItem from '@components/SelectionList/ListItem/BaseListItem';
43
import type {ListItem} from '@components/SelectionList/types';
54
import useAnimatedHighlightStyle from '@hooks/useAnimatedHighlightStyle';
@@ -31,7 +30,7 @@ function ChatListItem<TItem extends ListItem>({
3130
const reportActionItem = item as unknown as ReportActionListItemType;
3231
const [reportStable] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportActionItem?.reportID}`, {selector: getStableReportSelector});
3332
const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportActionItem?.childReportID}`);
34-
const personalDetails = usePersonalDetails();
33+
3534
const styles = useThemeStyles();
3635
const theme = useTheme();
3736
const animatedHighlightStyle = useAnimatedHighlightStyle({
@@ -88,7 +87,6 @@ function ChatListItem<TItem extends ListItem>({
8887
isFirstVisibleReportAction={false}
8988
shouldDisplayContextMenu={false}
9089
shouldShowBorder
91-
personalDetails={personalDetails}
9290
/>
9391
</BaseListItem>
9492
);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {canShowReportRecipientLocalTimeSelector} from '@selectors/Report';
2+
import type {OnyxEntry} from 'react-native-onyx';
3+
import ONYXKEYS from '@src/ONYXKEYS';
4+
import type {Report} from '@src/types/onyx';
5+
import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails';
6+
import useOnyx from './useOnyx';
7+
8+
type UseReportRecipientLocalTimeParams = {
9+
/** The report currently being looked at */
10+
report: OnyxEntry<Report>;
11+
};
12+
13+
function useReportRecipientLocalTime({report}: UseReportRecipientLocalTimeParams): boolean {
14+
const {accountID: currentUserAccountID} = useCurrentUserPersonalDetails();
15+
16+
const [canShowRecipientLocalTime = false] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: canShowReportRecipientLocalTimeSelector(report, currentUserAccountID)});
17+
18+
return canShowRecipientLocalTime;
19+
}
20+
21+
export default useReportRecipientLocalTime;

src/pages/Debug/ReportAction/DebugReportActionCreatePage.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ function DebugReportActionCreatePage({
134134
shouldDisplayNewMarker={false}
135135
isFirstVisibleReportAction={false}
136136
shouldDisplayContextMenu={false}
137-
personalDetails={personalDetailsList}
138137
/>
139138
) : (
140139
<Text>{translate('debug.nothingToPreview')}</Text>

src/pages/Debug/ReportAction/DebugReportActionPreview.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React from 'react';
22
import type {OnyxEntry} from 'react-native-onyx';
3-
import {usePersonalDetails} from '@components/OnyxListItemProvider';
43
import ScrollView from '@components/ScrollView';
54
import useOnyx from '@hooks/useOnyx';
65
import ReportActionItem from '@pages/inbox/report/ReportActionItem';
@@ -16,7 +15,6 @@ type DebugReportActionPreviewProps = {
1615
};
1716

1817
function DebugReportActionPreview({reportAction, reportID}: DebugReportActionPreviewProps) {
19-
const personalDetails = usePersonalDetails();
2018
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`);
2119
const [transactionThreadReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportAction?.childReportID}`);
2220

@@ -31,7 +29,6 @@ function DebugReportActionPreview({reportAction, reportID}: DebugReportActionPre
3129
shouldDisplayNewMarker={false}
3230
isFirstVisibleReportAction={false}
3331
shouldDisplayContextMenu={false}
34-
personalDetails={personalDetails}
3532
/>
3633
</ScrollView>
3734
);

src/pages/TransactionDuplicate/DuplicateTransactionItem.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React, {useMemo} from 'react';
22
import {View} from 'react-native';
33
import type {OnyxEntry} from 'react-native-onyx';
4-
import {usePersonalDetails} from '@components/OnyxListItemProvider';
54
import useOnyx from '@hooks/useOnyx';
65
import useThemeStyles from '@hooks/useThemeStyles';
76
import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
@@ -23,7 +22,6 @@ const linkedTransactionRouteErrorSelector = (transaction: OnyxEntry<Transaction>
2322

2423
function DuplicateTransactionItem({transaction, onPreviewPressed}: DuplicateTransactionItemProps) {
2524
const styles = useThemeStyles();
26-
const personalDetails = usePersonalDetails();
2725

2826
const [reportStable] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`, {selector: getStableReportSelector});
2927
const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportStable?.reportID}`);
@@ -68,7 +66,6 @@ function DuplicateTransactionItem({transaction, onPreviewPressed}: DuplicateTran
6866
shouldDisplayNewMarker={false}
6967
isFirstVisibleReportAction={false}
7068
shouldDisplayContextMenu={false}
71-
personalDetails={personalDetails}
7269
draftMessage={matchingDraftMessage}
7370
linkedTransactionRouteError={linkedTransactionRouteError}
7471
/>
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
import {personalDetailByAccountIDSelector} from '@selectors/PersonalDetails';
2+
import React from 'react';
3+
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
4+
import OfflineWithFeedback from '@components/OfflineWithFeedback';
5+
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
6+
import useNetwork from '@hooks/useNetwork';
7+
import useOnyx from '@hooks/useOnyx';
8+
import useResponsiveLayout from '@hooks/useResponsiveLayout';
9+
import useThemeStyles from '@hooks/useThemeStyles';
10+
import {isTripPreview} from '@libs/ReportActionsUtils';
11+
import {canCurrentUserOpenReport, canUserPerformWriteAction as canUserPerformWriteActionReportUtils, isArchivedReport, navigateToLinkedReportAction} from '@libs/ReportUtils';
12+
import {navigateToConciergeChatAndDeleteReport} from '@userActions/Report';
13+
import ONYXKEYS from '@src/ONYXKEYS';
14+
import type {Beta, IntroSelected, PersonalDetails, Report, ReportAction, ReportNameValuePairs} from '@src/types/onyx';
15+
import type {Errors} from '@src/types/onyx/OnyxCommon';
16+
import ReportActionItem from './ReportActionItem';
17+
import ThreadDivider from './ThreadDivider';
18+
19+
type AncestorReportActionItemProps = {
20+
/** Report for this action */
21+
report: Report;
22+
23+
/** All the data of the action item */
24+
reportAction: ReportAction;
25+
26+
/** Should we display the new marker on top of the comment? */
27+
shouldDisplayNewMarker: boolean;
28+
29+
/** Report name value pairs for the ancestor reports */
30+
reportNameValuePairs: OnyxCollection<ReportNameValuePairs>;
31+
32+
/** Beta features list */
33+
allBetas: OnyxEntry<Beta[]>;
34+
35+
/** Concierge personal details */
36+
conciergePersonalDetail: OnyxEntry<PersonalDetails>;
37+
38+
/** The user's Concierge reportID */
39+
conciergeReportID: string | undefined;
40+
41+
/** Account ID of the current user */
42+
currentUserAccountID: number;
43+
44+
/** Model of onboarding */
45+
introSelected: OnyxEntry<IntroSelected>;
46+
47+
/** If this is the first visible report action */
48+
isFirstVisibleReportAction: boolean;
49+
50+
/** Whether the current report is archived */
51+
isReportArchived: boolean;
52+
53+
/** Whether the user has viewed the self-guided tour */
54+
isSelfTourViewed: boolean | undefined;
55+
56+
/** Linked transaction route error */
57+
linkedTransactionRouteError: Errors | undefined;
58+
59+
/** Report action belonging to the report's parent */
60+
parentReportAction: OnyxEntry<ReportAction>;
61+
62+
/** If the thread divider line will be used */
63+
shouldUseThreadDividerLine: boolean;
64+
65+
/** The transaction thread report associated with the current report, if any */
66+
transactionThreadReport: OnyxEntry<Report>;
67+
};
68+
69+
function AncestorReportActionItem({
70+
report,
71+
reportAction,
72+
shouldDisplayNewMarker,
73+
reportNameValuePairs,
74+
allBetas,
75+
conciergePersonalDetail,
76+
conciergeReportID,
77+
currentUserAccountID,
78+
introSelected,
79+
isFirstVisibleReportAction,
80+
isReportArchived,
81+
isSelfTourViewed,
82+
linkedTransactionRouteError,
83+
parentReportAction,
84+
shouldUseThreadDividerLine,
85+
transactionThreadReport,
86+
}: AncestorReportActionItemProps) {
87+
const styles = useThemeStyles();
88+
const currentUserPersonalDetail = useCurrentUserPersonalDetails();
89+
const [reportOwnerPersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: personalDetailByAccountIDSelector(report?.ownerAccountID)});
90+
91+
const shouldDisplayThreadDivider = !isTripPreview(reportAction);
92+
const isAncestorReportArchived = isArchivedReport(reportNameValuePairs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report?.reportID}`]);
93+
const canOpenAncestorReport = canCurrentUserOpenReport(report, allBetas, isAncestorReportArchived);
94+
95+
const {isOffline} = useNetwork();
96+
const {isInNarrowPaneModal} = useResponsiveLayout();
97+
98+
const openLinkedAncestorReport = (isArchived: boolean) => {
99+
navigateToLinkedReportAction(
100+
{
101+
report,
102+
reportAction,
103+
shouldDisplayNewMarker,
104+
},
105+
isInNarrowPaneModal,
106+
canUserPerformWriteActionReportUtils(report, isArchived),
107+
isOffline,
108+
);
109+
};
110+
111+
const openAncestorReport = () => {
112+
openLinkedAncestorReport(isReportArchived);
113+
};
114+
115+
const openAncestorReportFromThreadDivider = () => {
116+
openLinkedAncestorReport(isAncestorReportArchived);
117+
};
118+
119+
const deleteAncestorReportAndNavigateToConcierge = () => {
120+
navigateToConciergeChatAndDeleteReport(
121+
report?.reportID,
122+
conciergeReportID,
123+
currentUserAccountID,
124+
introSelected,
125+
isSelfTourViewed,
126+
allBetas,
127+
reportOwnerPersonalDetail,
128+
currentUserPersonalDetail,
129+
conciergePersonalDetail,
130+
);
131+
};
132+
133+
return (
134+
<OfflineWithFeedback
135+
shouldDisableOpacity={!!reportAction?.pendingAction}
136+
pendingAction={report?.pendingFields?.addWorkspaceRoom ?? report?.pendingFields?.createChat}
137+
errors={report?.errorFields?.addWorkspaceRoom ?? report?.errorFields?.createChat}
138+
errorRowStyles={[styles.ml10, styles.mr2]}
139+
onClose={deleteAncestorReportAndNavigateToConcierge}
140+
>
141+
{shouldDisplayThreadDivider && (
142+
<ThreadDivider
143+
shouldDisplayNewMarker={shouldDisplayNewMarker}
144+
onPress={canOpenAncestorReport ? openAncestorReportFromThreadDivider : undefined}
145+
/>
146+
)}
147+
<ReportActionItem
148+
report={report}
149+
action={reportAction}
150+
onPress={canOpenAncestorReport ? openAncestorReport : undefined}
151+
parentReportAction={parentReportAction}
152+
transactionThreadReport={transactionThreadReport}
153+
displayAsGroup={false}
154+
shouldDisplayNewMarker={shouldDisplayNewMarker}
155+
isFirstVisibleReportAction={isFirstVisibleReportAction}
156+
shouldUseThreadDividerLine={shouldUseThreadDividerLine}
157+
isThreadReportParentAction
158+
linkedTransactionRouteError={linkedTransactionRouteError}
159+
/>
160+
</OfflineWithFeedback>
161+
);
162+
}
163+
164+
export default AncestorReportActionItem;

src/pages/inbox/report/PureReportActionItem.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* eslint-disable rulesdir/no-deep-equal-in-memo */
22
import {useNavigation} from '@react-navigation/native';
3+
import {personalDetailsDisplayNameSelector} from '@selectors/PersonalDetails';
34
import {deepEqual} from 'fast-equals';
45
import mapValues from 'lodash/mapValues';
56
import React, {memo, useContext, useEffect, useRef, useState} from 'react';
@@ -38,7 +39,6 @@ import {isReportMessageAttachment} from '@libs/isReportMessageAttachment';
3839
import type {PlatformStackNavigationProp} from '@libs/Navigation/PlatformStackNavigation/types';
3940
import type {ReportsSplitNavigatorParamList} from '@libs/Navigation/types';
4041
import Permissions from '@libs/Permissions';
41-
import {getDisplayNameOrDefault} from '@libs/PersonalDetailsUtils';
4242
import {
4343
extractLinksFromMessageHtml,
4444
getOriginalMessage,
@@ -135,9 +135,6 @@ type PureReportActionItemProps = {
135135
/** Linked transaction route error */
136136
linkedTransactionRouteError?: Errors;
137137

138-
/** Personal details list */
139-
personalDetails?: OnyxTypes.PersonalDetailsList;
140-
141138
/** ID of the original report from which the given reportAction is first created */
142139
originalReportID?: string;
143140

@@ -175,7 +172,6 @@ function PureReportActionItem({
175172
draftMessage,
176173
iouReport,
177174
linkedTransactionRouteError,
178-
personalDetails,
179175
originalReportID = '-1',
180176
originalReport,
181177
isClosedExpenseReportWithNoExpenses,
@@ -185,6 +181,7 @@ function PureReportActionItem({
185181
}: PureReportActionItemProps) {
186182
const isConciergeGreeting = action.reportActionID === CONST.CONCIERGE_GREETING_ACTION_ID;
187183
const shouldDisplayContextMenuValue = shouldDisplayContextMenu && !isConciergeGreeting;
184+
const [actorDisplayName] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {selector: personalDetailsDisplayNameSelector(action.actorAccountID ?? CONST.DEFAULT_NUMBER_ID)});
188185

189186
const {transitionActionSheetState} = ActionSheetAwareScrollView.useActionSheetAwareScrollViewActions();
190187
const {translate, datetimeToCalendarTime} = useLocalize();
@@ -474,11 +471,9 @@ function PureReportActionItem({
474471
const isEmpty = !shouldRenderViewBasedOnAction && !isClosedExpenseReportWithNoExpenses;
475472
const shouldDisplayThreadReplies = shouldDisplayThreadRepliesUtils(action, isThreadReportParentAction) && !isOnSearch;
476473

477-
// Calculating accessibilityLabel for chat message with sender, date and time and the message content.
478-
const displayName = getDisplayNameOrDefault(personalDetails?.[action.actorAccountID ?? CONST.DEFAULT_NUMBER_ID]);
479474
const formattedTimestamp = datetimeToCalendarTime(action.created, false);
480475
const plainMessage = getReportActionText(action);
481-
const accessibilityLabel = `${displayName}, ${formattedTimestamp}, ${plainMessage}`;
476+
const accessibilityLabel = `${actorDisplayName ?? ''}, ${formattedTimestamp}, ${plainMessage}`;
482477

483478
return (
484479
<ShowContextMenuStateContext.Provider value={contextMenuStateValue}>
@@ -601,7 +596,6 @@ function PureReportActionItem({
601596
updateHiddenState={updateHiddenState}
602597
isClosedExpenseReportWithNoExpenses={isClosedExpenseReportWithNoExpenses}
603598
isHarvestCreatedExpenseReport={isHarvestCreatedExpenseReport}
604-
personalDetails={personalDetails}
605599
shouldShowBorder={shouldShowBorder}
606600
isOnSearch={isOnSearch}
607601
setIsPaymentMethodPopoverActive={setIsPaymentMethodPopoverActive}
@@ -685,7 +679,6 @@ export default memo(PureReportActionItem, (prevProps, nextProps) => {
685679
prevProps.draftMessage === nextProps.draftMessage &&
686680
prevProps.iouReport?.reportID === nextProps.iouReport?.reportID &&
687681
deepEqual(prevProps.linkedTransactionRouteError, nextProps.linkedTransactionRouteError) &&
688-
deepEqual(prevProps.personalDetails, nextProps.personalDetails) &&
689682
prevProps.originalReportID === nextProps.originalReportID &&
690683
deepEqual(prevProps.originalReport?.participants, nextProps.originalReport?.participants) &&
691684
prevProps.isClosedExpenseReportWithNoExpenses === nextProps.isClosedExpenseReportWithNoExpenses &&

0 commit comments

Comments
 (0)