Skip to content

Commit 6127a1f

Browse files
authored
Merge pull request #43610 from s77rt/participants-migration-polish
Participants migration polish
2 parents 2ee7c52 + 7213c4b commit 6127a1f

13 files changed

+66
-139
lines changed

src/components/LHNOptionsList/OptionRowLHN.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti
125125

126126
const isGroupChat = ReportUtils.isGroupChat(optionItem) || ReportUtils.isDeprecatedGroupDM(optionItem);
127127

128-
const fullTitle = isGroupChat ? ReportUtils.getGroupChatName(undefined, false, optionItem.reportID ?? '-1') : optionItem.text;
128+
const fullTitle = isGroupChat ? ReportUtils.getGroupChatName(undefined, false, report) : optionItem.text;
129129
const subscriptAvatarBorderColor = isFocused ? focusedBackgroundColor : theme.sidebar;
130130
return (
131131
<OfflineWithFeedback

src/components/ReportWelcomeText.tsx

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, {useMemo} from 'react';
22
import {View} from 'react-native';
33
import type {OnyxEntry} from 'react-native-onyx';
4-
import {useOnyx, withOnyx} from 'react-native-onyx';
4+
import {withOnyx} from 'react-native-onyx';
55
import useLocalize from '@hooks/useLocalize';
66
import useThemeStyles from '@hooks/useThemeStyles';
77
import Navigation from '@libs/Navigation/Navigation';
@@ -33,17 +33,13 @@ type ReportWelcomeTextProps = ReportWelcomeTextOnyxProps & {
3333
function ReportWelcomeText({report, policy, personalDetails}: ReportWelcomeTextProps) {
3434
const {translate} = useLocalize();
3535
const styles = useThemeStyles();
36-
const [session] = useOnyx(ONYXKEYS.SESSION);
3736
const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(report);
3837
const isChatRoom = ReportUtils.isChatRoom(report);
3938
const isSelfDM = ReportUtils.isSelfDM(report);
4039
const isInvoiceRoom = ReportUtils.isInvoiceRoom(report);
41-
const isOneOnOneChat = ReportUtils.isOneOnOneChat(report);
4240
const isSystemChat = ReportUtils.isSystemChat(report);
4341
const isDefault = !(isChatRoom || isPolicyExpenseChat || isSelfDM || isInvoiceRoom || isSystemChat);
44-
const participantAccountIDs = Object.keys(report?.participants ?? {})
45-
.map(Number)
46-
.filter((accountID) => accountID !== session?.accountID || (!isOneOnOneChat && !isSystemChat));
42+
const participantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report);
4743
const isMultipleParticipant = participantAccountIDs.length > 1;
4844
const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, personalDetails), isMultipleParticipant);
4945
const roomWelcomeMessage = ReportUtils.getRoomWelcomeMessage(report);

src/libs/OptionsListUtils.ts

+5-29
Original file line numberDiff line numberDiff line change
@@ -774,15 +774,9 @@ function createOption(
774774
result.policyID = report.policyID;
775775
result.isSelfDM = ReportUtils.isSelfDM(report);
776776

777-
// For 1:1 chat, we don't want to include currentUser as participants in order to not mark 1:1 chats as having multiple participants
778-
const isOneOnOneChat = ReportUtils.isOneOnOneChat(report);
779-
const visibleParticipantAccountIDs = Object.entries(report.participants ?? {})
780-
.filter(([, participant]) => participant && !participant.hidden)
781-
.map(([accountID]) => Number(accountID))
782-
.filter((accountID) => accountID !== currentUserAccountID || !isOneOnOneChat);
777+
const visibleParticipantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report, true);
783778

784779
result.tooltipText = ReportUtils.getReportParticipantsTitle(visibleParticipantAccountIDs);
785-
result.isOneOnOneChat = isOneOnOneChat;
786780

787781
hasMultipleParticipants = personalDetailList.length > 1 || result.isChatRoom || result.isPolicyExpenseChat || ReportUtils.isGroupChat(report);
788782
subtitle = ReportUtils.getChatRoomSubtitle(report);
@@ -839,13 +833,7 @@ function createOption(
839833
*/
840834
function getReportOption(participant: Participant): ReportUtils.OptionData {
841835
const report = ReportUtils.getReport(participant.reportID);
842-
843-
// For 1:1 chat, we don't want to include currentUser as participants in order to not mark 1:1 chats as having multiple participants
844-
const isOneOnOneChat = ReportUtils.isOneOnOneChat(report);
845-
const visibleParticipantAccountIDs = Object.entries(report?.participants ?? {})
846-
.filter(([, reportParticipant]) => reportParticipant && !reportParticipant.hidden)
847-
.map(([accountID]) => Number(accountID))
848-
.filter((accountID) => accountID !== currentUserAccountID || !isOneOnOneChat);
836+
const visibleParticipantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report, true);
849837

850838
const option = createOption(
851839
visibleParticipantAccountIDs,
@@ -1554,11 +1542,8 @@ function createOptionList(personalDetails: OnyxEntry<PersonalDetailsList>, repor
15541542
return;
15551543
}
15561544

1557-
// For 1:1 chat, we don't want to include currentUser as participants in order to not mark 1:1 chats as having multiple participants
15581545
const isOneOnOneChat = ReportUtils.isOneOnOneChat(report);
1559-
const accountIDs = Object.keys(report.participants ?? {})
1560-
.map(Number)
1561-
.filter((accountID) => accountID !== currentUserAccountID || !isOneOnOneChat);
1546+
const accountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report);
15621547

15631548
const isChatRoom = ReportUtils.isChatRoom(report);
15641549
if ((!accountIDs || accountIDs.length === 0) && !isChatRoom) {
@@ -1591,11 +1576,7 @@ function createOptionList(personalDetails: OnyxEntry<PersonalDetailsList>, repor
15911576
}
15921577

15931578
function createOptionFromReport(report: Report, personalDetails: OnyxEntry<PersonalDetailsList>) {
1594-
// For 1:1 chat, we don't want to include currentUser as participants in order to not mark 1:1 chats as having multiple participants
1595-
const isOneOnOneChat = ReportUtils.isOneOnOneChat(report);
1596-
const accountIDs = Object.keys(report.participants ?? {})
1597-
.map(Number)
1598-
.filter((accountID) => accountID !== currentUserAccountID || !isOneOnOneChat);
1579+
const accountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report);
15991580

16001581
return {
16011582
item: report,
@@ -1864,13 +1845,8 @@ function getOptions(
18641845
const isPolicyExpenseChat = option.isPolicyExpenseChat;
18651846
const isMoneyRequestReport = option.isMoneyRequestReport;
18661847
const isSelfDM = option.isSelfDM;
1867-
const isOneOnOneChat = option.isOneOnOneChat;
18681848
const isChatRoom = option.isChatRoom;
1869-
1870-
// For 1:1 chat, we don't want to include currentUser as participants in order to not mark 1:1 chats as having multiple participants
1871-
const accountIDs = Object.keys(report.participants ?? {})
1872-
.map(Number)
1873-
.filter((accountID) => accountID !== currentUserAccountID || !isOneOnOneChat);
1849+
const accountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report);
18741850

18751851
if (isPolicyExpenseChat && report.isOwnPolicyExpenseChat && !includeOwnedWorkspaceChats) {
18761852
return;

src/libs/ReportUtils.ts

+37-59
Original file line numberDiff line numberDiff line change
@@ -1619,13 +1619,7 @@ function getReportRecipientAccountIDs(report: OnyxEntry<Report>, currentLoginAcc
16191619
}
16201620

16211621
let finalParticipantAccountIDs: number[] = [];
1622-
if (isMoneyRequestReport(report)) {
1623-
// For money requests i.e the IOU (1:1 person) and Expense (1:* person) reports, use the full `participants`
1624-
// and add the `ownerAccountId`. Money request reports don't add `ownerAccountId` in `participants` array
1625-
const defaultParticipantAccountIDs = Object.keys(finalReport?.participants ?? {}).map(Number);
1626-
const setOfParticipantAccountIDs = new Set<number>(report?.ownerAccountID ? [...defaultParticipantAccountIDs, report.ownerAccountID] : defaultParticipantAccountIDs);
1627-
finalParticipantAccountIDs = [...setOfParticipantAccountIDs];
1628-
} else if (isTaskReport(report)) {
1622+
if (isTaskReport(report)) {
16291623
// Task reports `managerID` will change when assignee is changed, in that case the old `managerID` is still present in `participants`
16301624
// along with the new one. We only need the `managerID` as a participant here.
16311625
finalParticipantAccountIDs = report?.managerID ? [report?.managerID] : [];
@@ -1839,19 +1833,32 @@ function getDisplayNameForParticipant(accountID?: number, shouldUseShortForm = f
18391833
return shouldUseShortForm ? shortName : longName;
18401834
}
18411835

1842-
function getParticipantAccountIDs(reportID: string, includeOnlyActiveMembers = false) {
1843-
const report = getReport(reportID);
1844-
if (!report || !report.participants) {
1845-
return [];
1846-
}
1847-
const accountIDStrings = Object.keys(report.participants).filter((accountID) => {
1848-
if (!includeOnlyActiveMembers) {
1836+
function getParticipantsAccountIDsForDisplay(report: OnyxEntry<Report>, shouldExcludeHidden = false, shouldExcludeDeleted = false): number[] {
1837+
let participantsEntries = Object.entries(report?.participants ?? {});
1838+
1839+
// For 1:1 chat, we don't want to include the current user as a participant in order to not mark 1:1 chats as having multiple participants
1840+
// For system chat, we want to display Expensify as the only participant
1841+
const shouldExcludeCurrentUser = isOneOnOneChat(report) || isSystemChat(report);
1842+
1843+
if (shouldExcludeCurrentUser || shouldExcludeHidden || shouldExcludeDeleted) {
1844+
participantsEntries = participantsEntries.filter(([accountID, participant]) => {
1845+
if (shouldExcludeCurrentUser && Number(accountID) === currentUserAccountID) {
1846+
return false;
1847+
}
1848+
1849+
if (shouldExcludeHidden && participant.hidden) {
1850+
return false;
1851+
}
1852+
1853+
if (shouldExcludeDeleted && report?.pendingChatMembers?.findLast((member) => member.accountID === accountID)?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) {
1854+
return false;
1855+
}
1856+
18491857
return true;
1850-
}
1851-
const pendingMember = report?.pendingChatMembers?.findLast((member) => member.accountID === accountID.toString());
1852-
return !pendingMember || pendingMember.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE;
1853-
});
1854-
return accountIDStrings.map((accountID) => Number(accountID));
1858+
});
1859+
}
1860+
1861+
return participantsEntries.map(([accountID]) => Number(accountID));
18551862
}
18561863

18571864
function buildParticipantsFromAccountIDs(accountIDs: number[]): Participants {
@@ -1866,18 +1873,14 @@ function buildParticipantsFromAccountIDs(accountIDs: number[]): Participants {
18661873
/**
18671874
* Returns the report name if the report is a group chat
18681875
*/
1869-
function getGroupChatName(participantAccountIDs?: number[], shouldApplyLimit = false, reportID = ''): string | undefined {
1870-
// If we have a reportID always try to get the name from the report.
1871-
if (reportID) {
1872-
const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${reportID}`;
1873-
const reportName = allReports?.[reportKey]?.reportName;
1874-
if (reportName) {
1875-
return reportName;
1876-
}
1876+
function getGroupChatName(participantAccountIDs?: number[], shouldApplyLimit = false, report?: OnyxEntry<Report>): string | undefined {
1877+
// If we have a report always try to get the name from the report.
1878+
if (report?.reportName) {
1879+
return report.reportName;
18771880
}
18781881

18791882
// Get participantAccountIDs from participants object
1880-
let participants = participantAccountIDs ?? getParticipantAccountIDs(reportID);
1883+
let participants = participantAccountIDs ?? Object.keys(report?.participants ?? {}).map(Number);
18811884
if (shouldApplyLimit) {
18821885
participants = participants.slice(0, 5);
18831886
}
@@ -1894,20 +1897,6 @@ function getGroupChatName(participantAccountIDs?: number[], shouldApplyLimit = f
18941897
return Localize.translateLocal('groupChat.defaultReportName', {displayName: getDisplayNameForParticipant(participants[0], false)});
18951898
}
18961899

1897-
function getVisibleChatMemberAccountIDs(reportID: string): number[] {
1898-
const report = getReport(reportID);
1899-
if (!report || !report.participants) {
1900-
return [];
1901-
}
1902-
const visibleParticipantAccountIDs = Object.entries(report.participants).reduce<number[]>((accountIDs, [accountID, participant]) => {
1903-
if (participant && !participant.hidden) {
1904-
accountIDs.push(Number(accountID));
1905-
}
1906-
return accountIDs;
1907-
}, []);
1908-
return visibleParticipantAccountIDs;
1909-
}
1910-
19111900
function getParticipants(reportID: string) {
19121901
const report = getReport(reportID);
19131902
if (!report) {
@@ -2064,7 +2053,7 @@ function getIcons(
20642053
source: report.avatarUrl || getDefaultGroupAvatar(report.reportID),
20652054
id: -1,
20662055
type: CONST.ICON_TYPE_AVATAR,
2067-
name: getGroupChatName(undefined, true, report.reportID ?? '-1'),
2056+
name: getGroupChatName(undefined, true, report),
20682057
};
20692058
return [groupChatIcon];
20702059
}
@@ -3348,7 +3337,7 @@ function getReportName(report: OnyxEntry<Report>, policy?: OnyxEntry<Policy>): s
33483337
}
33493338

33503339
if (isGroupChat(report)) {
3351-
return getGroupChatName(undefined, true, report?.reportID) ?? '';
3340+
return getGroupChatName(undefined, true, report) ?? '';
33523341
}
33533342

33543343
if (isChatRoom(report) || isTaskReport(report)) {
@@ -3480,11 +3469,7 @@ function getParentNavigationSubtitle(report: OnyxEntry<Report>): ParentNavigatio
34803469
function navigateToDetailsPage(report: OnyxEntry<Report>) {
34813470
const isSelfDMReport = isSelfDM(report);
34823471
const isOneOnOneChatReport = isOneOnOneChat(report);
3483-
3484-
// For 1:1 chat, we don't want to include currentUser as participants in order to not mark 1:1 chats as having multiple participants
3485-
const participantAccountID = Object.keys(report?.participants ?? {})
3486-
.map(Number)
3487-
.filter((accountID) => accountID !== currentUserAccountID || !isOneOnOneChatReport);
3472+
const participantAccountID = getParticipantsAccountIDsForDisplay(report);
34883473

34893474
if (isSelfDMReport || isOneOnOneChatReport) {
34903475
Navigation.navigate(ROUTES.PROFILE.getRoute(participantAccountID[0]));
@@ -3501,11 +3486,7 @@ function navigateToDetailsPage(report: OnyxEntry<Report>) {
35013486
*/
35023487
function goBackToDetailsPage(report: OnyxEntry<Report>) {
35033488
const isOneOnOneChatReport = isOneOnOneChat(report);
3504-
3505-
// For 1:1 chat, we don't want to include currentUser as participants in order to not mark 1:1 chats as having multiple participants
3506-
const participantAccountID = Object.keys(report?.participants ?? {})
3507-
.map(Number)
3508-
.filter((accountID) => accountID !== currentUserAccountID || !isOneOnOneChatReport);
3489+
const participantAccountID = getParticipantsAccountIDsForDisplay(report);
35093490

35103491
if (isOneOnOneChatReport) {
35113492
Navigation.navigate(ROUTES.PROFILE.getRoute(participantAccountID[0]));
@@ -3524,9 +3505,7 @@ function goBackFromPrivateNotes(report: OnyxEntry<Report>, session: OnyxEntry<Se
35243505
}
35253506
const currentUserPrivateNote = report.privateNotes?.[session.accountID]?.note ?? '';
35263507
if (isEmpty(currentUserPrivateNote)) {
3527-
const participantAccountIDs = Object.keys(report?.participants ?? {})
3528-
.map(Number)
3529-
.filter((accountID) => accountID !== currentUserAccountID || !isOneOnOneChat(report));
3508+
const participantAccountIDs = getParticipantsAccountIDsForDisplay(report);
35303509

35313510
if (isOneOnOneChat(report)) {
35323511
Navigation.goBack(ROUTES.PROFILE.getRoute(participantAccountIDs[0]));
@@ -7066,7 +7045,7 @@ export {
70667045
getOutstandingChildRequest,
70677046
getParentNavigationSubtitle,
70687047
getParsedComment,
7069-
getParticipantAccountIDs,
7048+
getParticipantsAccountIDsForDisplay,
70707049
getParticipants,
70717050
getPendingChatMembers,
70727051
getPersonalDetailsForAccountID,
@@ -7098,7 +7077,6 @@ export {
70987077
getTransactionReportName,
70997078
getTransactionsWithReceipts,
71007079
getUserDetailTooltipText,
7101-
getVisibleChatMemberAccountIDs,
71027080
getWhisperDisplayNames,
71037081
getWorkspaceAvatar,
71047082
getWorkspaceChats,

src/libs/SidebarUtils.ts

+2-10
Original file line numberDiff line numberDiff line change
@@ -258,15 +258,8 @@ function getOptionData({
258258
isDeletedParentAction: false,
259259
};
260260

261-
// For 1:1 chat, we don't want to include currentUser as participants in order to not mark 1:1 chats as having multiple participants
262-
const isOneOnOneChat = ReportUtils.isOneOnOneChat(report);
263-
const participantAccountIDs = Object.keys(report.participants ?? {})
264-
.map(Number)
265-
.filter((accountID) => accountID !== currentUserAccountID || !isOneOnOneChat);
266-
const visibleParticipantAccountIDs = Object.entries(report.participants ?? {})
267-
.filter(([, participant]) => participant && !participant.hidden)
268-
.map(([accountID]) => Number(accountID))
269-
.filter((accountID) => accountID !== currentUserAccountID || !isOneOnOneChat);
261+
const participantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report);
262+
const visibleParticipantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report, true);
270263

271264
const participantPersonalDetailList = Object.values(OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, personalDetails)) as PersonalDetails[];
272265
const personalDetail = participantPersonalDetailList[0] ?? {};
@@ -305,7 +298,6 @@ function getOptionData({
305298
result.chatType = report.chatType;
306299
result.isDeletedParentAction = report.isDeletedParentAction;
307300
result.isSelfDM = ReportUtils.isSelfDM(report);
308-
result.isOneOnOneChat = isOneOnOneChat;
309301
result.tooltipText = ReportUtils.getReportParticipantsTitle(visibleParticipantAccountIDs);
310302

311303
const hasMultipleParticipants = participantPersonalDetailList.length > 1 || result.isChatRoom || result.isPolicyExpenseChat || ReportUtils.isExpenseReport(report);

src/libs/actions/Task.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -768,9 +768,7 @@ function getShareDestination(reportID: string, reports: OnyxCollection<OnyxTypes
768768

769769
const isOneOnOneChat = ReportUtils.isOneOnOneChat(report);
770770

771-
const participants = Object.keys(report?.participants ?? {})
772-
.map(Number)
773-
.filter((accountID) => accountID !== currentUserAccountID || !isOneOnOneChat);
771+
const participants = ReportUtils.getParticipantsAccountIDsForDisplay(report);
774772

775773
const isMultipleParticipant = participants.length > 1;
776774
const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs(participants, personalDetails), isMultipleParticipant);

src/pages/GroupChatNameEditPage.tsx

+5-8
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,11 @@ function GroupChatNameEditPage({groupChatDraft, report}: GroupChatNameEditPagePr
4545
const {inputCallbackRef} = useAutoFocusInput();
4646

4747
// We will try to get the chatName from the report or draft depending on what flow we are in
48-
const participantAccountIDs = useMemo(() => {
49-
if (reportID) {
50-
return ReportUtils.getParticipantAccountIDs(reportID);
51-
}
52-
53-
return (groupChatDraft?.participants ?? []).map((participant) => participant.accountID);
54-
}, [groupChatDraft, reportID]);
55-
const existingReportName = useMemo(() => ReportUtils.getGroupChatName(participantAccountIDs, false, reportID), [participantAccountIDs, reportID]);
48+
const draftParticipantAccountIDs = useMemo(() => (groupChatDraft?.participants ?? []).map((participant) => participant.accountID), [groupChatDraft?.participants]);
49+
const existingReportName = useMemo(
50+
() => (report ? ReportUtils.getGroupChatName(undefined, false, report) : ReportUtils.getGroupChatName(draftParticipantAccountIDs)),
51+
[draftParticipantAccountIDs, report],
52+
);
5653
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
5754
const currentChatName = reportID ? existingReportName : groupChatDraft?.reportName || existingReportName;
5855

0 commit comments

Comments
 (0)