-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add notification preference for all the reports and update the design for the group chats #28200
Changes from all commits
32df987
78bcb7e
d122a0d
c5946e3
cf82041
083c924
994140d
5910aa9
d4f11fa
3df0e95
89fc4ae
5b731c0
491e044
f050e20
d21f21c
3c880c6
79560ff
626ec91
4417b5c
b8a66ed
e2ee8df
ac77a36
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -37,6 +37,7 @@ import variables from '../styles/variables'; | |||||||||||||||||||
import * as ValidationUtils from '../libs/ValidationUtils'; | ||||||||||||||||||||
import Permissions from '../libs/Permissions'; | ||||||||||||||||||||
import ROUTES from '../ROUTES'; | ||||||||||||||||||||
import MenuItemWithTopDescription from '../components/MenuItemWithTopDescription'; | ||||||||||||||||||||
|
||||||||||||||||||||
const matchType = PropTypes.shape({ | ||||||||||||||||||||
params: PropTypes.shape({ | ||||||||||||||||||||
|
@@ -135,7 +136,7 @@ function ProfilePage(props) { | |||||||||||||||||||
|
||||||||||||||||||||
const navigateBackTo = lodashGet(props.route, 'params.backTo', ROUTES.HOME); | ||||||||||||||||||||
|
||||||||||||||||||||
const chatReportWithCurrentUser = !isCurrentUser && !Session.isAnonymousUser() ? ReportUtils.getChatByParticipants([accountID]) : 0; | ||||||||||||||||||||
const notificationPreference = !_.isEmpty(props.report) ? props.translate(`notificationPreferencesPage.notificationPreferences.${props.report.notificationPreference}`) : ''; | ||||||||||||||||||||
|
||||||||||||||||||||
// eslint-disable-next-line rulesdir/prefer-early-return | ||||||||||||||||||||
useEffect(() => { | ||||||||||||||||||||
|
@@ -231,6 +232,15 @@ function ProfilePage(props) { | |||||||||||||||||||
) : null} | ||||||||||||||||||||
{shouldShowLocalTime && <AutoUpdateTime timezone={timezone} />} | ||||||||||||||||||||
</View> | ||||||||||||||||||||
{!_.isEmpty(props.report) && notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN && ( | ||||||||||||||||||||
<MenuItemWithTopDescription | ||||||||||||||||||||
techievivek marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||
shouldShowRightIcon | ||||||||||||||||||||
title={notificationPreference} | ||||||||||||||||||||
techievivek marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||
description={props.translate('notificationPreferencesPage.label')} | ||||||||||||||||||||
onPress={() => Navigation.navigate(ROUTES.REPORT_SETTINGS_NOTIFICATION_PREFERENCES.getRoute(props.report.reportID))} | ||||||||||||||||||||
wrapperStyle={[styles.mtn6, styles.mb5]} | ||||||||||||||||||||
/> | ||||||||||||||||||||
)} | ||||||||||||||||||||
{!isCurrentUser && !Session.isAnonymousUser() && ( | ||||||||||||||||||||
<MenuItem | ||||||||||||||||||||
title={`${props.translate('common.message')}${displayName}`} | ||||||||||||||||||||
|
@@ -241,15 +251,15 @@ function ProfilePage(props) { | |||||||||||||||||||
shouldShowRightIcon | ||||||||||||||||||||
/> | ||||||||||||||||||||
)} | ||||||||||||||||||||
{!_.isEmpty(chatReportWithCurrentUser) && ( | ||||||||||||||||||||
{!_.isEmpty(props.report) && ( | ||||||||||||||||||||
<MenuItem | ||||||||||||||||||||
title={`${props.translate('privateNotes.title')}`} | ||||||||||||||||||||
titleStyle={styles.flex1} | ||||||||||||||||||||
icon={Expensicons.Pencil} | ||||||||||||||||||||
onPress={() => Navigation.navigate(ROUTES.PRIVATE_NOTES_LIST.getRoute(chatReportWithCurrentUser.reportID))} | ||||||||||||||||||||
onPress={() => Navigation.navigate(ROUTES.PRIVATE_NOTES_LIST.getRoute(props.report.reportID))} | ||||||||||||||||||||
wrapperStyle={styles.breakAll} | ||||||||||||||||||||
shouldShowRightIcon | ||||||||||||||||||||
brickRoadIndicator={Report.hasErrorInPrivateNotes(chatReportWithCurrentUser) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : ''} | ||||||||||||||||||||
brickRoadIndicator={Report.hasErrorInPrivateNotes(props.report) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : ''} | ||||||||||||||||||||
/> | ||||||||||||||||||||
)} | ||||||||||||||||||||
</ScrollView> | ||||||||||||||||||||
|
@@ -289,5 +299,20 @@ export default compose( | |||||||||||||||||||
betas: { | ||||||||||||||||||||
key: ONYXKEYS.BETAS, | ||||||||||||||||||||
}, | ||||||||||||||||||||
session: { | ||||||||||||||||||||
key: ONYXKEYS.SESSION, | ||||||||||||||||||||
}, | ||||||||||||||||||||
}), | ||||||||||||||||||||
// eslint-disable-next-line rulesdir/no-multiple-onyx-in-file | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm having second thoughts about this. What was the reason for adding the second There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Because we are dependent on the value of
Users can have multiple private notes. On each chat, they have a different note. To say, private notes are report rNVPs characterized by the user's accountID(so each participant) can have their notes on chats they belong to.
So do you think we can still add the key to the user's session? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I honestly didn't pay attention to the second call of
From #27463 we created a rule to prevent multiple uses I know that having a report key listener here is to re-render the page and show the latest value for the preference menu item. So I think it's better we find another way to do this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm okay it sounds like these private notes reportIDs should probably go in it's own key/collection. Something like In the meantime, did we really need to change the way we load this to begin with? What was wrong with the logic we had before here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yeah, I did bring that up in the design doc but we went with adding it as a key to report object. See here: https://docs.google.com/document/d/1StLBx3Y6yJsZp54rHMu-mGo20pUt1niV6Y0MPNDR6A4/edit?disco=AAAA0B4ClCw There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
If I'm understanding correctly, It sounds like these private note reports are tied to accounts not reports right? If so I think the concerns in that thread were misguided 😄. Ideally we shouldn't have to load a report just to get the privateNotesReportID for an account. Either way, I guess there's no problem with the revert so we can probably just :donothing:. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Each user can have private notes on all the chat reports they are part of. If I have access to reports 1 and 2, then I can have private notes on both report 1 and report 2. We also discussed bringing public notes, so in that case, they won't be tied to accounts but only to the reports.
💯 agree with this. But it looks like we do that for a couple more things, no? like lastReadTime and stuff? Since there are no major concerns with how we are handling the data, I too will just stick with :donothing: for now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Now I know why I made that change There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure I understand that comment, but it sounds like there's urgency behind this so I won't be a blocker. However, can we create a follow up issue to clean this up and remove the need for a second Onyx subscription? I'm not sure exactly how it should be cleaned up but it definitely doesn't need to be like this. Thanks! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let me just reiterate the problem statement so it's clear for you. We have now added the notification preference option on the profile page. The challenge is that the profile page doesn't subscribe to any report by default. Instead, it depends on the user profile you've navigated to. It's not just about fetching the chat report between you and another user; the ProfilePage needs to actively subscribe to it. This subscription is crucial because when you update your notification preference, the component should re-render and display the updated notification preference from the report. This was first reported here: #28200 (comment) and we did figure out a better solution for this here #28200 (comment), which involved creating a separate component for the notification preference. This new component would subscribe to the DM chat report using Onyx, ensuring that when you update your notification preference, it automatically re-renders and displays the updated data. We agreed that it might be overkill #28200 (comment) so we just so we opted to stick with a double Onyx call for now. A future solution is to create a dedicated notification preference page component, which can be reused throughout the entire application as needed. |
||||||||||||||||||||
withOnyx({ | ||||||||||||||||||||
report: { | ||||||||||||||||||||
key: ({route, session}) => { | ||||||||||||||||||||
const accountID = Number(lodashGet(route.params, 'accountID', 0)); | ||||||||||||||||||||
if (Number(session.accountID) === accountID || Session.isAnonymousUser()) { | ||||||||||||||||||||
return null; | ||||||||||||||||||||
} | ||||||||||||||||||||
return `${ONYXKEYS.COLLECTION.REPORT}${lodashGet(ReportUtils.getChatByParticipants([accountID]), 'reportID', '')}`; | ||||||||||||||||||||
Comment on lines
+311
to
+314
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This caused regression when user opens new user profile link first time.
Suggested change
Right now, app crashes and will be a deploy blocker soon There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. raised PR for the quick fix There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You haven't taken into account the dependency of |
||||||||||||||||||||
}, | ||||||||||||||||||||
}, | ||||||||||||||||||||
}), | ||||||||||||||||||||
)(ProfilePage); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,8 +61,7 @@ const defaultProps = { | |
function ReportDetailsPage(props) { | ||
const policy = useMemo(() => props.policies[`${ONYXKEYS.COLLECTION.POLICY}${props.report.policyID}`], [props.policies, props.report.policyID]); | ||
const isPolicyAdmin = useMemo(() => PolicyUtils.isPolicyAdmin(policy), [policy]); | ||
const shouldDisableSettings = useMemo(() => ReportUtils.shouldDisableSettings(props.report), [props.report]); | ||
const shouldUseFullTitle = !shouldDisableSettings || ReportUtils.isTaskReport(props.report); | ||
const shouldUseFullTitle = ReportUtils.isTaskReport(props.report); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
const isChatRoom = useMemo(() => ReportUtils.isChatRoom(props.report), [props.report]); | ||
const isThread = useMemo(() => ReportUtils.isChatThread(props.report), [props.report]); | ||
const isUserCreatedPolicyRoom = useMemo(() => ReportUtils.isUserCreatedPolicyRoom(props.report), [props.report]); | ||
|
@@ -75,16 +74,20 @@ function ReportDetailsPage(props) { | |
const canLeaveRoom = useMemo(() => ReportUtils.canLeaveRoom(props.report, !_.isEmpty(policy)), [policy, props.report]); | ||
const participants = useMemo(() => ReportUtils.getParticipantsIDs(props.report), [props.report]); | ||
|
||
const isGroupDMChat = useMemo(() => ReportUtils.isDM(props.report) && participants.length > 1, [props.report, participants.length]); | ||
techievivek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const menuItems = useMemo(() => { | ||
const items = [ | ||
{ | ||
const items = []; | ||
|
||
if (!isGroupDMChat) { | ||
items.push({ | ||
key: CONST.REPORT_DETAILS_MENU_ITEM.SHARE_CODE, | ||
translationKey: 'common.shareCode', | ||
icon: Expensicons.QrCode, | ||
isAnonymousAction: true, | ||
action: () => Navigation.navigate(ROUTES.REPORT_WITH_ID_DETAILS_SHARE_CODE.getRoute(props.report.reportID)), | ||
}, | ||
]; | ||
}); | ||
} | ||
|
||
if (isArchivedRoom) { | ||
return items; | ||
|
@@ -103,17 +106,15 @@ function ReportDetailsPage(props) { | |
}); | ||
} | ||
|
||
if (!shouldDisableSettings) { | ||
items.push({ | ||
key: CONST.REPORT_DETAILS_MENU_ITEM.SETTINGS, | ||
translationKey: 'common.settings', | ||
icon: Expensicons.Gear, | ||
isAnonymousAction: false, | ||
action: () => { | ||
Navigation.navigate(ROUTES.REPORT_SETTINGS.getRoute(props.report.reportID)); | ||
}, | ||
}); | ||
} | ||
items.push({ | ||
key: CONST.REPORT_DETAILS_MENU_ITEM.SETTINGS, | ||
translationKey: 'common.settings', | ||
icon: Expensicons.Gear, | ||
isAnonymousAction: false, | ||
action: () => { | ||
Navigation.navigate(ROUTES.REPORT_SETTINGS.getRoute(props.report.reportID)); | ||
}, | ||
}); | ||
|
||
// Prevent displaying private notes option for threads and task reports | ||
if (!isThread && !isMoneyRequestReport && !ReportUtils.isTaskReport(props.report)) { | ||
|
@@ -138,7 +139,7 @@ function ReportDetailsPage(props) { | |
} | ||
|
||
return items; | ||
}, [isArchivedRoom, participants.length, shouldDisableSettings, isThread, isMoneyRequestReport, props.report, isUserCreatedPolicyRoom, canLeaveRoom]); | ||
}, [isArchivedRoom, participants.length, isThread, isMoneyRequestReport, props.report, isUserCreatedPolicyRoom, canLeaveRoom, isGroupDMChat]); | ||
|
||
const displayNamesWithTooltips = useMemo(() => { | ||
const hasMultipleParticipants = participants.length > 1; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,7 +64,7 @@ function ReportSettingsPage(props) { | |
const shouldDisableWelcomeMessage = | ||
isMoneyRequestReport || ReportUtils.isArchivedRoom(report) || !ReportUtils.isChatRoom(report) || _.isEmpty(linkedWorkspace) || linkedWorkspace.role !== CONST.POLICY.ROLE.ADMIN; | ||
|
||
const shouldDisableSettings = _.isEmpty(report) || ReportUtils.shouldDisableSettings(report) || ReportUtils.isArchivedRoom(report); | ||
const shouldDisableSettings = _.isEmpty(report) || ReportUtils.isArchivedRoom(report); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After enabling settings for all the reports and revealing access to the notification preference page. We had to test the offline behavior for the newly enabled reports. Coming from #29334 this caused a regression where the creation of a new task missed the optimistic prop |
||
const shouldShowRoomName = !ReportUtils.isPolicyExpenseChat(report) && !ReportUtils.isChatThread(report); | ||
const notificationPreference = | ||
report.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -207,6 +207,10 @@ export default { | |
marginTop: 'auto', | ||
}, | ||
|
||
mtn6: { | ||
marginTop: -24, | ||
}, | ||
|
||
mb0: { | ||
marginBottom: 0, | ||
}, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This created a regression which is fixed in #30182