Skip to content

Commit 7ebfaa0

Browse files
authored
Merge pull request #47577 from shubham1206agra/migrate-notification-preference
Migrate notification preference
2 parents 7537bfb + 26f8695 commit 7ebfaa0

23 files changed

+258
-181
lines changed

src/libs/OptionsListUtils.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ function createOption(
755755
result.isWaitingOnBankAccount = report.isWaitingOnBankAccount;
756756
result.policyID = report.policyID;
757757
result.isSelfDM = ReportUtils.isSelfDM(report);
758-
result.notificationPreference = report.notificationPreference;
758+
result.notificationPreference = ReportUtils.getReportNotificationPreference(report);
759759

760760
const visibleParticipantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report, true);
761761

@@ -849,7 +849,7 @@ function getPolicyExpenseReportOption(participant: Participant | ReportUtils.Opt
849849
const expenseReport = ReportUtils.isPolicyExpenseChat(participant) ? ReportUtils.getReportOrDraftReport(participant.reportID) : null;
850850

851851
const visibleParticipantAccountIDs = Object.entries(expenseReport?.participants ?? {})
852-
.filter(([, reportParticipant]) => reportParticipant && !reportParticipant.hidden)
852+
.filter(([, reportParticipant]) => reportParticipant && reportParticipant.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN)
853853
.map(([accountID]) => Number(accountID));
854854

855855
const option = createOption(
@@ -2500,7 +2500,7 @@ function getEmptyOptions(): Options {
25002500
}
25012501

25022502
function shouldUseBoldText(report: ReportUtils.OptionData): boolean {
2503-
return report.isUnread === true && report.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.MUTE;
2503+
return report.isUnread === true && ReportUtils.getReportNotificationPreference(report) !== CONST.REPORT.NOTIFICATION_PREFERENCE.MUTE;
25042504
}
25052505

25062506
export {

src/libs/ReportUtils.ts

+52-37
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,10 @@ type OptimisticExpenseReport = Pick<
154154
| 'statusNum'
155155
| 'total'
156156
| 'nonReimbursableTotal'
157-
| 'notificationPreference'
158157
| 'parentReportID'
159158
| 'lastVisibleActionCreated'
160159
| 'parentReportActionID'
160+
| 'participants'
161161
| 'fieldList'
162162
>;
163163

@@ -274,7 +274,6 @@ type OptimisticChatReport = Pick<
274274
| 'lastMessageText'
275275
| 'lastReadTime'
276276
| 'lastVisibleActionCreated'
277-
| 'notificationPreference'
278277
| 'oldPolicyName'
279278
| 'ownerAccountID'
280279
| 'pendingFields'
@@ -355,7 +354,6 @@ type OptimisticTaskReport = Pick<
355354
| 'policyID'
356355
| 'stateNum'
357356
| 'statusNum'
358-
| 'notificationPreference'
359357
| 'parentReportActionID'
360358
| 'lastVisibleActionCreated'
361359
| 'hasParentAccess'
@@ -395,7 +393,6 @@ type OptimisticIOUReport = Pick<
395393
| 'statusNum'
396394
| 'total'
397395
| 'reportName'
398-
| 'notificationPreference'
399396
| 'parentReportID'
400397
| 'lastVisibleActionCreated'
401398
| 'fieldList'
@@ -1147,6 +1144,32 @@ function isSystemChat(report: OnyxEntry<Report>): boolean {
11471144
return getChatType(report) === CONST.REPORT.CHAT_TYPE.SYSTEM;
11481145
}
11491146

1147+
function getDefaultNotificationPreferenceForReport(report: OnyxEntry<Report>): ValueOf<typeof CONST.REPORT.NOTIFICATION_PREFERENCE> {
1148+
if (isAnnounceRoom(report)) {
1149+
return CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS;
1150+
}
1151+
if (isPublicRoom(report)) {
1152+
return CONST.REPORT.NOTIFICATION_PREFERENCE.DAILY;
1153+
}
1154+
if (!getChatType(report) || isGroupChat(report)) {
1155+
return CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS;
1156+
}
1157+
if (isAdminRoom(report) || isPolicyExpenseChat(report) || isInvoiceRoom(report)) {
1158+
return CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS;
1159+
}
1160+
if (isSelfDM(report)) {
1161+
return CONST.REPORT.NOTIFICATION_PREFERENCE.MUTE;
1162+
}
1163+
return CONST.REPORT.NOTIFICATION_PREFERENCE.DAILY;
1164+
}
1165+
1166+
/**
1167+
* Get the notification preference given a report
1168+
*/
1169+
function getReportNotificationPreference(report: OnyxEntry<Report>): ValueOf<typeof CONST.REPORT.NOTIFICATION_PREFERENCE> {
1170+
return report?.participants?.[currentUserAccountID ?? -1]?.notificationPreference ?? getDefaultNotificationPreferenceForReport(report);
1171+
}
1172+
11501173
const CONCIERGE_ACCOUNT_ID_STRING = CONST.ACCOUNT_ID.CONCIERGE.toString();
11511174
/**
11521175
* Only returns true if this is our main 1:1 DM report with Concierge.
@@ -1252,7 +1275,7 @@ function hasExpensifyGuidesEmails(accountIDs: number[]): boolean {
12521275

12531276
function getMostRecentlyVisitedReport(reports: Array<OnyxEntry<Report>>, reportMetadata: OnyxCollection<ReportMetadata>): OnyxEntry<Report> {
12541277
const filteredReports = reports.filter((report) => {
1255-
const shouldKeep = !isChatThread(report) || report?.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN;
1278+
const shouldKeep = !isChatThread(report) || getReportNotificationPreference(report) !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN;
12561279
return shouldKeep && !!report?.reportID && !!(reportMetadata?.[`${ONYXKEYS.COLLECTION.REPORT_METADATA}${report.reportID}`]?.lastVisitTime ?? report?.lastReadTime);
12571280
});
12581281
return lodashMaxBy(filteredReports, (a) => new Date(reportMetadata?.[`${ONYXKEYS.COLLECTION.REPORT_METADATA}${a?.reportID}`]?.lastVisitTime ?? a?.lastReadTime ?? '').valueOf());
@@ -1622,13 +1645,6 @@ function isPayer(session: OnyxEntry<Session>, iouReport: OnyxEntry<Report>) {
16221645
return isAdmin || (isMoneyRequestReport(iouReport) && isManager);
16231646
}
16241647

1625-
/**
1626-
* Get the notification preference given a report
1627-
*/
1628-
function getReportNotificationPreference(report: OnyxEntry<Report>): string | number {
1629-
return report?.notificationPreference ?? '';
1630-
}
1631-
16321648
/**
16331649
* Checks if the current user is the action's author
16341650
*/
@@ -2063,7 +2079,7 @@ function getParticipantsAccountIDsForDisplay(report: OnyxEntry<Report>, shouldEx
20632079
return false;
20642080
}
20652081

2066-
if (shouldExcludeHidden && reportParticipants[accountID]?.hidden) {
2082+
if (shouldExcludeHidden && reportParticipants[accountID]?.notificationPreference === CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN) {
20672083
return false;
20682084
}
20692085

@@ -2116,7 +2132,7 @@ function buildParticipantsFromAccountIDs(accountIDs: number[]): Participants {
21162132
const finalParticipants: Participants = {};
21172133
return accountIDs.reduce((participants, accountID) => {
21182134
// eslint-disable-next-line no-param-reassign
2119-
participants[accountID] = {hidden: false};
2135+
participants[accountID] = {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS};
21202136
return participants;
21212137
}, finalParticipants);
21222138
}
@@ -4254,8 +4270,8 @@ function buildOptimisticIOUReport(payeeAccountID: number, payerAccountID: number
42544270
const policy = getPolicy(policyID);
42554271

42564272
const participants: Participants = {
4257-
[payeeAccountID]: {hidden: true},
4258-
[payerAccountID]: {hidden: true},
4273+
[payeeAccountID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN},
4274+
[payerAccountID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN},
42594275
};
42604276

42614277
return {
@@ -4273,7 +4289,6 @@ function buildOptimisticIOUReport(payeeAccountID: number, payerAccountID: number
42734289

42744290
// We don't translate reportName because the server response is always in English
42754291
reportName: `${payerEmail} owes ${formattedTotal}`,
4276-
notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN,
42774292
parentReportID: chatReportID,
42784293
lastVisibleActionCreated: DateUtils.getDBTime(),
42794294
fieldList: policy?.fieldList,
@@ -4328,7 +4343,11 @@ function buildOptimisticInvoiceReport(chatReportID: string, policyID: string, re
43284343
stateNum: CONST.REPORT.STATE_NUM.SUBMITTED,
43294344
statusNum: CONST.REPORT.STATUS_NUM.OPEN,
43304345
total,
4331-
notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN,
4346+
participants: {
4347+
[currentUserAccountID ?? -1]: {
4348+
notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN,
4349+
},
4350+
},
43324351
parentReportID: chatReportID,
43334352
lastVisibleActionCreated: DateUtils.getDBTime(),
43344353
};
@@ -4378,7 +4397,11 @@ function buildOptimisticExpenseReport(
43784397
statusNum,
43794398
total: storedTotal,
43804399
nonReimbursableTotal: reimbursable ? 0 : storedTotal,
4381-
notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN,
4400+
participants: {
4401+
[payeeAccountID]: {
4402+
notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN,
4403+
},
4404+
},
43824405
parentReportID: chatReportID,
43834406
lastVisibleActionCreated: DateUtils.getDBTime(),
43844407
parentReportActionID,
@@ -5038,12 +5061,11 @@ function buildOptimisticChatReport(
50385061
description = '',
50395062
avatarUrl = '',
50405063
optimisticReportID = '',
5041-
shouldShowParticipants = true,
50425064
): OptimisticChatReport {
50435065
const isWorkspaceChatType = chatType && isWorkspaceChat(chatType);
50445066
const participants = participantList.reduce((reportParticipants: Participants, accountID: number) => {
50455067
const participant: ReportParticipant = {
5046-
hidden: !shouldShowParticipants,
5068+
notificationPreference,
50475069
...(!isWorkspaceChatType && {role: accountID === currentUserAccountID ? CONST.REPORT.ROLE.ADMIN : CONST.REPORT.ROLE.MEMBER}),
50485070
};
50495071
// eslint-disable-next-line no-param-reassign
@@ -5064,7 +5086,6 @@ function buildOptimisticChatReport(
50645086
lastMessageText: undefined,
50655087
lastReadTime: currentTime,
50665088
lastVisibleActionCreated: currentTime,
5067-
notificationPreference,
50685089
oldPolicyName,
50695090
ownerAccountID: ownerAccountID || CONST.REPORT.OWNER_ACCOUNT_ID_FAKE,
50705091
parentReportActionID,
@@ -5482,9 +5503,7 @@ function buildOptimisticWorkspaceChats(policyID: string, policyName: string, exp
54825503
policyName,
54835504
undefined,
54845505
undefined,
5485-
5486-
// #announce contains all policy members so notifying always should be opt-in only.
5487-
CONST.REPORT.NOTIFICATION_PREFERENCE.DAILY,
5506+
CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS,
54885507
);
54895508
const announceChatReportID = announceChatData.reportID;
54905509
const announceCreatedAction = buildOptimisticCreatedReportAction(CONST.POLICY.OWNER_EMAIL_FAKE);
@@ -5571,12 +5590,12 @@ function buildOptimisticTaskReport(
55715590
): OptimisticTaskReport {
55725591
const participants: Participants = {
55735592
[ownerAccountID]: {
5574-
hidden: false,
5593+
notificationPreference,
55755594
},
55765595
};
55775596

55785597
if (assigneeAccountID) {
5579-
participants[assigneeAccountID] = {hidden: false};
5598+
participants[assigneeAccountID] = {notificationPreference};
55805599
}
55815600

55825601
return {
@@ -5591,7 +5610,6 @@ function buildOptimisticTaskReport(
55915610
policyID,
55925611
stateNum: CONST.REPORT.STATE_NUM.OPEN,
55935612
statusNum: CONST.REPORT.STATUS_NUM.OPEN,
5594-
notificationPreference,
55955613
lastVisibleActionCreated: DateUtils.getDBTime(),
55965614
hasParentAccess: true,
55975615
};
@@ -5669,10 +5687,6 @@ function buildTransactionThread(
56695687
CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN,
56705688
reportAction?.reportActionID,
56715689
moneyRequestReport?.reportID,
5672-
'',
5673-
'',
5674-
'',
5675-
false,
56765690
);
56775691
}
56785692

@@ -6049,7 +6063,7 @@ function shouldReportBeInOptionList({
60496063

60506064
// All unread chats (even archived ones) in GSD mode will be shown. This is because GSD mode is specifically for focusing the user on the most relevant chats, primarily, the unread ones
60516065
if (isInFocusMode) {
6052-
return isUnread(report) && report.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.MUTE;
6066+
return isUnread(report) && getReportNotificationPreference(report) !== CONST.REPORT.NOTIFICATION_PREFERENCE.MUTE;
60536067
}
60546068

60556069
// Archived reports should always be shown when in default (most recent) mode. This is because you should still be able to access and search for the chats to find them.
@@ -7441,15 +7455,15 @@ function isAdminOwnerApproverOrReportOwner(report: OnyxEntry<Report>, policy: On
74417455
/**
74427456
* Whether the user can join a report
74437457
*/
7444-
function canJoinChat(report: OnyxInputOrEntry<Report>, parentReportAction: OnyxInputOrEntry<ReportAction>, policy: OnyxInputOrEntry<Policy>): boolean {
7458+
function canJoinChat(report: OnyxEntry<Report>, parentReportAction: OnyxInputOrEntry<ReportAction>, policy: OnyxInputOrEntry<Policy>): boolean {
74457459
// We disabled thread functions for whisper action
74467460
// So we should not show join option for existing thread on whisper message that has already been left, or manually leave it
74477461
if (ReportActionsUtils.isWhisperAction(parentReportAction)) {
74487462
return false;
74497463
}
74507464

74517465
// If the notification preference of the chat is not hidden that means we have already joined the chat
7452-
if (report?.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN) {
7466+
if (getReportNotificationPreference(report) !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN) {
74537467
return false;
74547468
}
74557469

@@ -7483,7 +7497,7 @@ function canLeaveChat(report: OnyxEntry<Report>, policy: OnyxEntry<Policy>): boo
74837497
return false;
74847498
}
74857499

7486-
if (report?.notificationPreference === CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN) {
7500+
if (getReportNotificationPreference(report) === CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN) {
74877501
return false;
74887502
}
74897503

@@ -7501,7 +7515,7 @@ function canLeaveChat(report: OnyxEntry<Report>, policy: OnyxEntry<Policy>): boo
75017515
return canLeaveInvoiceRoom(report);
75027516
}
75037517

7504-
return (isChatThread(report) && !!report?.notificationPreference?.length) || isUserCreatedPolicyRoom(report) || isNonAdminOrOwnerOfPolicyExpenseChat(report, policy);
7518+
return (isChatThread(report) && !!getReportNotificationPreference(report)) || isUserCreatedPolicyRoom(report) || isNonAdminOrOwnerOfPolicyExpenseChat(report, policy);
75057519
}
75067520

75077521
function getReportActionActorAccountID(reportAction: OnyxInputOrEntry<ReportAction>, iouReport: OnyxInputOrEntry<Report> | undefined): number | undefined {
@@ -8034,6 +8048,7 @@ export {
80348048
isInvoiceRoomWithID,
80358049
isInvoiceReport,
80368050
isOpenInvoiceReport,
8051+
getDefaultNotificationPreferenceForReport,
80378052
canWriteInReport,
80388053
navigateToDetailsPage,
80398054
navigateToPrivateNotes,

src/libs/SidebarUtils.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ function getOrderedReportIDs(
103103
const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`] ?? {};
104104
const parentReportAction = ReportActionsUtils.getReportAction(report?.parentReportID ?? '-1', report?.parentReportActionID ?? '-1');
105105
const doesReportHaveViolations = OptionsListUtils.shouldShowViolations(report, transactionViolations);
106-
const isHidden = report.notificationPreference === CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN;
106+
const isHidden = ReportUtils.getReportNotificationPreference(report) === CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN;
107107
const isFocused = report.reportID === currentReportId;
108108
const allReportErrors = OptionsListUtils.getAllReportErrors(report, reportActions) ?? {};
109109
const transactionReportActions = ReportActionsUtils.getAllReportActions(report.reportID);
@@ -343,7 +343,7 @@ function getOptionData({
343343
result.hasOutstandingChildRequest = report.hasOutstandingChildRequest;
344344
result.parentReportID = report.parentReportID ?? '-1';
345345
result.isWaitingOnBankAccount = report.isWaitingOnBankAccount;
346-
result.notificationPreference = report.notificationPreference;
346+
result.notificationPreference = ReportUtils.getReportNotificationPreference(report);
347347
result.isAllowedToComment = ReportUtils.canUserPerformWriteAction(report);
348348
result.chatType = report.chatType;
349349
result.isDeletedParentAction = report.isDeletedParentAction;

src/libs/UnreadIndicatorUpdater/index.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ import type {Report} from '@src/types/onyx';
99
import updateUnread from './updateUnread';
1010

1111
function getUnreadReportsForUnreadIndicator(reports: OnyxCollection<Report>, currentReportID: string) {
12-
return Object.values(reports ?? {}).filter(
13-
(report) =>
12+
return Object.values(reports ?? {}).filter((report) => {
13+
const notificationPreference = ReportUtils.getReportNotificationPreference(report);
14+
return (
1415
ReportUtils.isUnread(report) &&
1516
ReportUtils.shouldReportBeInOptionList({
1617
report,
@@ -29,9 +30,10 @@ function getUnreadReportsForUnreadIndicator(reports: OnyxCollection<Report>, cur
2930
* Furthermore, muted reports may or may not appear in the LHN depending on priority mode,
3031
* but they should not be considered in the unread indicator count.
3132
*/
32-
report?.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN &&
33-
report?.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.MUTE,
34-
);
33+
notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN &&
34+
notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.MUTE
35+
);
36+
});
3537
}
3638

3739
const memoizedGetUnreadReportsForUnreadIndicator = memoize(getUnreadReportsForUnreadIndicator, {maxArgs: 1});

src/libs/actions/IOU.ts

+2-10
Original file line numberDiff line numberDiff line change
@@ -3867,7 +3867,7 @@ function getOrCreateOptimisticSplitChatReport(existingSplitChatReportID: string,
38673867
undefined,
38683868
undefined,
38693869
undefined,
3870-
CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN,
3870+
CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS,
38713871
);
38723872
return {existingSplitChatReport: null, splitChatReport};
38733873
}
@@ -3967,11 +3967,6 @@ function createSplitsAndOnyxData(
39673967
splitChatReport.lastActorAccountID = currentUserAccountID;
39683968
splitChatReport.lastVisibleActionCreated = splitIOUReportAction.created;
39693969

3970-
let splitChatReportNotificationPreference = splitChatReport.notificationPreference;
3971-
if (splitChatReportNotificationPreference === CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN) {
3972-
splitChatReportNotificationPreference = CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS;
3973-
}
3974-
39753970
// If we have an existing splitChatReport (group chat or workspace) use it's pending fields, otherwise indicate that we are adding a chat
39763971
if (!existingSplitChatReport) {
39773972
splitChatReport.pendingFields = {
@@ -3985,10 +3980,7 @@ function createSplitsAndOnyxData(
39853980
// and we need the data to be available when we navigate to the chat page
39863981
onyxMethod: existingSplitChatReport ? Onyx.METHOD.MERGE : Onyx.METHOD.SET,
39873982
key: `${ONYXKEYS.COLLECTION.REPORT}${splitChatReport.reportID}`,
3988-
value: {
3989-
...splitChatReport,
3990-
notificationPreference: splitChatReportNotificationPreference,
3991-
},
3983+
value: splitChatReport,
39923984
},
39933985
{
39943986
onyxMethod: Onyx.METHOD.SET,

0 commit comments

Comments
 (0)