diff --git a/app/lib/server/functions/notifications/audio.js b/app/lib/server/functions/notifications/audio.js index 38d84f82211e4..12ce5fb8d5fc8 100644 --- a/app/lib/server/functions/notifications/audio.js +++ b/app/lib/server/functions/notifications/audio.js @@ -15,7 +15,7 @@ export function shouldNotifyAudio({ roomType, isThread, }) { - if (disableAllMessageNotifications && audioNotifications == null && !hasReplyToThread) { + if (disableAllMessageNotifications && audioNotifications == null && !isHighlighted && !hasMentionToUser && !hasReplyToThread) { return false; } diff --git a/app/lib/server/lib/sendNotificationsOnMessage.js b/app/lib/server/lib/sendNotificationsOnMessage.js index 7b7e76b25a94e..cec7d55150c98 100644 --- a/app/lib/server/lib/sendNotificationsOnMessage.js +++ b/app/lib/server/lib/sendNotificationsOnMessage.js @@ -43,22 +43,19 @@ export const sendNotification = async ({ return; } - const user = Users.findOneById(subscription.u._id, { - fields: { - active: 1, - emails: 1, - language: 1, - status: 1, - statusConnection: 1, - username: 1, - settings: 1, - }, - }); - - const { settings, ...restUser } = user; - if (!subscription.receiver) { - subscription.receiver = [restUser]; + subscription.receiver = [ + Users.findOneById(subscription.u._id, { + fields: { + active: 1, + emails: 1, + language: 1, + status: 1, + statusConnection: 1, + username: 1, + }, + }), + ]; } const [receiver] = subscription.receiver; @@ -87,7 +84,7 @@ export const sendNotification = async ({ disableAllMessageNotifications, status: receiver.status, statusConnection: receiver.statusConnection, - audioNotifications: audioNotifications || settings?.preferences?.audioNotifications, + audioNotifications, hasMentionToAll, hasMentionToHere, isHighlighted, diff --git a/app/models/server/models/Subscriptions.js b/app/models/server/models/Subscriptions.js index a01a72cd6c273..c632de14df8ed 100644 --- a/app/models/server/models/Subscriptions.js +++ b/app/models/server/models/Subscriptions.js @@ -130,22 +130,6 @@ export class Subscriptions extends Base { return this.find(query, options); } - updateAudioNotificationsById(_id, audioNotifications) { - const query = { - _id, - }; - - const update = {}; - - if (audioNotifications === 'default') { - update.$unset = { audioNotifications: 1 }; - } else { - update.$set = { audioNotifications }; - } - - return this.update(query, update); - } - updateAudioNotificationValueById(_id, audioNotificationValue) { const query = { _id, @@ -160,68 +144,26 @@ export class Subscriptions extends Base { return this.update(query, update); } - updateDesktopNotificationsById(_id, desktopNotifications) { + updateNotificationsPrefById(_id, notificationPref, notificationField, notificationPrefOrigin) { const query = { _id, }; const update = {}; - if (desktopNotifications === null) { + if (notificationPref === null) { update.$unset = { - desktopNotifications: 1, - desktopPrefOrigin: 1, + [notificationField]: 1, + [notificationPrefOrigin]: 1, }; } else { update.$set = { - desktopNotifications: desktopNotifications.value, - desktopPrefOrigin: desktopNotifications.origin, + [notificationField]: notificationPref.value, + [notificationPrefOrigin]: notificationPref.origin, }; } - return this.update(query, update); - } - - updateMobilePushNotificationsById(_id, mobilePushNotifications) { - const query = { - _id, - }; - - const update = {}; - - if (mobilePushNotifications === null) { - update.$unset = { - mobilePushNotifications: 1, - mobilePrefOrigin: 1, - }; - } else { - update.$set = { - mobilePushNotifications: mobilePushNotifications.value, - mobilePrefOrigin: mobilePushNotifications.origin, - }; - } - - return this.update(query, update); - } - - updateEmailNotificationsById(_id, emailNotifications) { - const query = { - _id, - }; - - const update = {}; - - if (emailNotifications === null) { - update.$unset = { - emailNotifications: 1, - emailPrefOrigin: 1, - }; - } else { - update.$set = { - emailNotifications: emailNotifications.value, - emailPrefOrigin: emailNotifications.origin, - }; - } + console.log('updateNotificationsPrefById', JSON.stringify({ query, update }, null, 2)); return this.update(query, update); } @@ -1147,102 +1089,34 @@ export class Subscriptions extends Base { return this.update(query, update, { multi: true }); } - clearDesktopNotificationUserPreferences(userId) { + clearNotificationUserPreferences(userId, notificationField, notificationOriginField) { const query = { 'u._id': userId, - desktopPrefOrigin: 'user', + [notificationOriginField]: 'user', }; const update = { $unset: { - desktopNotifications: 1, - desktopPrefOrigin: 1, - }, - }; - - return this.update(query, update, { multi: true }); - } - - updateDesktopNotificationUserPreferences(userId, desktopNotifications) { - const query = { - 'u._id': userId, - desktopPrefOrigin: { - $ne: 'subscription', - }, - }; - - const update = { - $set: { - desktopNotifications, - desktopPrefOrigin: 'user', - }, - }; - - return this.update(query, update, { multi: true }); - } - - clearMobileNotificationUserPreferences(userId) { - const query = { - 'u._id': userId, - mobilePrefOrigin: 'user', - }; - - const update = { - $unset: { - mobilePushNotifications: 1, - mobilePrefOrigin: 1, - }, - }; - - return this.update(query, update, { multi: true }); - } - - updateMobileNotificationUserPreferences(userId, mobilePushNotifications) { - const query = { - 'u._id': userId, - mobilePrefOrigin: { - $ne: 'subscription', - }, - }; - - const update = { - $set: { - mobilePushNotifications, - mobilePrefOrigin: 'user', - }, - }; - - return this.update(query, update, { multi: true }); - } - - clearEmailNotificationUserPreferences(userId) { - const query = { - 'u._id': userId, - emailPrefOrigin: 'user', - }; - - const update = { - $unset: { - emailNotifications: 1, - emailPrefOrigin: 1, + [notificationOriginField]: 1, + [notificationField]: 1, }, }; return this.update(query, update, { multi: true }); } - updateEmailNotificationUserPreferences(userId, emailNotifications) { + updateNotificationUserPreferences(userId, userPref, notificationField, notificationOriginField) { const query = { 'u._id': userId, - emailPrefOrigin: { + [notificationOriginField]: { $ne: 'subscription', }, }; const update = { $set: { - emailNotifications, - emailPrefOrigin: 'user', + [notificationField]: userPref, + [notificationOriginField]: 'user', }, }; diff --git a/app/push-notifications/server/methods/saveNotificationSettings.js b/app/push-notifications/server/methods/saveNotificationSettings.js index faf879b7ed941..56537abd76834 100644 --- a/app/push-notifications/server/methods/saveNotificationSettings.js +++ b/app/push-notifications/server/methods/saveNotificationSettings.js @@ -1,7 +1,7 @@ import { Meteor } from 'meteor/meteor'; import { check } from 'meteor/check'; -import { Subscriptions } from '../../../models'; +import { Subscriptions } from '../../../models/server'; import { getUserNotificationPreference } from '../../../utils'; Meteor.methods({ @@ -13,39 +13,26 @@ Meteor.methods({ check(field, String); check(value, String); + const getNotificationPrefValue = (field, value) => { + if (value === 'default') { + const userPref = getUserNotificationPreference(Meteor.userId(), field); + return userPref.origin === 'server' ? null : userPref; + } + return { value, origin: 'subscription' }; + }; + const notifications = { audioNotifications: { - updateMethod: (subscription, value) => Subscriptions.updateAudioNotificationsById(subscription._id, value), + updateMethod: (subscription, value) => Subscriptions.updateNotificationsPrefById(subscription._id, getNotificationPrefValue('audio', value), 'audioNotifications', 'audioPrefOrigin'), }, desktopNotifications: { - updateMethod: (subscription, value) => { - if (value === 'default') { - const userPref = getUserNotificationPreference(Meteor.userId(), 'desktop'); - Subscriptions.updateDesktopNotificationsById(subscription._id, userPref.origin === 'server' ? null : userPref); - } else { - Subscriptions.updateDesktopNotificationsById(subscription._id, { value, origin: 'subscription' }); - } - }, + updateMethod: (subscription, value) => Subscriptions.updateNotificationsPrefById(subscription._id, getNotificationPrefValue('desktop', value), 'desktopNotifications', 'desktopPrefOrigin'), }, mobilePushNotifications: { - updateMethod: (subscription, value) => { - if (value === 'default') { - const userPref = getUserNotificationPreference(Meteor.userId(), 'mobile'); - Subscriptions.updateMobilePushNotificationsById(subscription._id, userPref.origin === 'server' ? null : userPref); - } else { - Subscriptions.updateMobilePushNotificationsById(subscription._id, { value, origin: 'subscription' }); - } - }, + updateMethod: (subscription, value) => Subscriptions.updateNotificationsPrefById(subscription._id, getNotificationPrefValue('mobile', value), 'mobilePushNotifications', 'mobilePrefOrigin'), }, emailNotifications: { - updateMethod: (subscription, value) => { - if (value === 'default') { - const userPref = getUserNotificationPreference(Meteor.userId(), 'email'); - Subscriptions.updateEmailNotificationsById(subscription._id, userPref.origin === 'server' ? null : userPref); - } else { - Subscriptions.updateEmailNotificationsById(subscription._id, { value, origin: 'subscription' }); - } - }, + updateMethod: (subscription, value) => Subscriptions.updateNotificationsPrefById(subscription._id, getNotificationPrefValue('email', value), 'emailNotifications', 'emailPrefOrigin'), }, unreadAlert: { updateMethod: (subscription, value) => Subscriptions.updateUnreadAlertById(subscription._id, value), diff --git a/app/utils/lib/getDefaultSubscriptionPref.js b/app/utils/lib/getDefaultSubscriptionPref.js index 294a7d50a734c..e0761ac55956a 100644 --- a/app/utils/lib/getDefaultSubscriptionPref.js +++ b/app/utils/lib/getDefaultSubscriptionPref.js @@ -5,6 +5,7 @@ export const getDefaultSubscriptionPref = (userPref) => { desktopNotifications, mobileNotifications, emailNotificationMode, + audioNotifications, highlights, } = (userPref.settings && userPref.settings.preferences) || {}; @@ -27,5 +28,10 @@ export const getDefaultSubscriptionPref = (userPref) => { subscription.emailPrefOrigin = 'user'; } + if (audioNotifications && audioNotifications !== 'default') { + subscription.audioNotifications = audioNotifications; + subscription.audioPrefOrigin = 'user'; + } + return subscription; }; diff --git a/app/utils/lib/getUserNotificationPreference.js b/app/utils/lib/getUserNotificationPreference.js index 9d5e5ac1018bb..ce80cd5befbb4 100644 --- a/app/utils/lib/getUserNotificationPreference.js +++ b/app/utils/lib/getUserNotificationPreference.js @@ -8,12 +8,13 @@ export const getUserNotificationPreference = (user, pref) => { let preferenceKey; switch (pref) { + case 'audio': preferenceKey = 'audioNotifications'; break; case 'desktop': preferenceKey = 'desktopNotifications'; break; case 'mobile': preferenceKey = 'mobileNotifications'; break; case 'email': preferenceKey = 'emailNotificationMode'; break; } - if (user && user.settings && user.settings.preferences && user.settings.preferences[preferenceKey] !== 'default') { + if (user?.settings?.preferences && typeof user.settings.preferences[preferenceKey] !== 'undefined' && user.settings.preferences[preferenceKey] !== 'default') { return { value: user.settings.preferences[preferenceKey], origin: 'user', diff --git a/client/views/room/contextualBar/NotificationPreferences/NotificationPreferences.js b/client/views/room/contextualBar/NotificationPreferences/NotificationPreferences.js index 1d2103846a5a6..71de0fae89541 100644 --- a/client/views/room/contextualBar/NotificationPreferences/NotificationPreferences.js +++ b/client/views/room/contextualBar/NotificationPreferences/NotificationPreferences.js @@ -3,7 +3,7 @@ import { Button, ButtonGroup, FieldGroup, Icon } from '@rocket.chat/fuselage'; import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; import { useForm } from '../../../../hooks/useForm'; -import { useUserSubscription, useUser } from '../../../../contexts/UserContext'; +import { useUserSubscription } from '../../../../contexts/UserContext'; import { useTranslation } from '../../../../contexts/TranslationContext'; import { useCustomSound } from '../../../../contexts/CustomSoundContext'; import { useEndpointActionExperimental } from '../../../../hooks/useEndpointAction'; @@ -65,7 +65,6 @@ export default React.memo(({ tabBar, rid }) => { const t = useTranslation(); const subscription = useUserSubscription(rid); - const userSettingsPreferences = useUser().settings.preferences; const customSound = useCustomSound(); @@ -77,11 +76,11 @@ export default React.memo(({ tabBar, rid }) => { turnOn: !subscription.disableNotifications, muteGroupMentions: subscription.muteGroupMentions, showCounter: !subscription.hideUnreadStatus, - desktopAlert: subscription.desktopNotifications || userSettingsPreferences.desktopNotifications, - desktopAudio: subscription.audioNotifications || 'default', - desktopSound: subscription.audioNotificationValue || userSettingsPreferences.newMessageNotification, - mobileAlert: subscription.mobilePushNotifications || userSettingsPreferences.mobileNotifications, - emailAlert: subscription.emailNotifications || userSettingsPreferences.emailNotificationMode, + desktopAlert: (subscription.desktopPrefOrigin === 'subscription' && subscription.desktopNotifications) || 'default', + desktopAudio: (subscription.audioPrefOrigin === 'subscription' && subscription.audioNotifications) || 'default', + desktopSound: subscription.audioNotificationValue || 'default', + mobileAlert: (subscription.mobilePrefOrigin === 'subscription' && subscription.mobilePushNotifications) || 'default', + emailAlert: (subscription.emailPrefOrigin === 'subscription' && subscription.emailNotifications) || 'default', }, ); @@ -100,7 +99,7 @@ export default React.memo(({ tabBar, rid }) => { audio: defaultOption, sound: [ ['none None', t('None')], - ['0 default', t('Default')], + ['default', t('Default')], ...customSoundAsset, ], }; diff --git a/server/methods/saveUserPreferences.js b/server/methods/saveUserPreferences.js index d2306abe0fd54..c29e2894c3ba4 100644 --- a/server/methods/saveUserPreferences.js +++ b/server/methods/saveUserPreferences.js @@ -1,7 +1,7 @@ import { Meteor } from 'meteor/meteor'; import { Match, check } from 'meteor/check'; -import { Users, Subscriptions } from '../../app/models'; +import { Users, Subscriptions } from '../../app/models/server'; Meteor.methods({ saveUserPreferences(settings) { @@ -77,25 +77,33 @@ Meteor.methods({ Meteor.defer(() => { if (settings.desktopNotifications && oldDesktopNotifications !== settings.desktopNotifications) { if (settings.desktopNotifications === 'default') { - Subscriptions.clearDesktopNotificationUserPreferences(user._id); + Subscriptions.clearNotificationUserPreferences(user._id, 'desktopNotifications', 'desktopPrefOrigin'); } else { - Subscriptions.updateDesktopNotificationUserPreferences(user._id, settings.desktopNotifications); + Subscriptions.updateNotificationUserPreferences(user._id, settings.desktopNotifications, 'desktopNotifications', 'desktopPrefOrigin'); } } if (settings.mobileNotifications && oldMobileNotifications !== settings.mobileNotifications) { if (settings.mobileNotifications === 'default') { - Subscriptions.clearMobileNotificationUserPreferences(user._id); + Subscriptions.clearNotificationUserPreferences(user._id, 'mobilePushNotifications', 'mobilePrefOrigin'); } else { - Subscriptions.updateMobileNotificationUserPreferences(user._id, settings.mobileNotifications); + Subscriptions.updateNotificationUserPreferences(user._id, settings.mobileNotifications, 'mobilePushNotifications', 'mobilePrefOrigin'); } } if (settings.emailNotificationMode && oldEmailNotifications !== settings.emailNotificationMode) { if (settings.emailNotificationMode === 'default') { - Subscriptions.clearEmailNotificationUserPreferences(user._id); + Subscriptions.clearNotificationUserPreferences(user._id, 'emailNotifications', 'emailPrefOrigin'); } else { - Subscriptions.updateEmailNotificationUserPreferences(user._id, settings.emailNotificationMode); + Subscriptions.updateNotificationUserPreferences(user._id, settings.emailNotificationMode, 'emailNotifications', 'emailPrefOrigin'); + } + } + + if (settings.audioNotifications && oldEmailNotifications !== settings.audioNotifications) { + if (settings.audioNotifications === 'default') { + Subscriptions.clearNotificationUserPreferences(user._id, 'audioNotifications', 'audioPrefOrigin'); + } else { + Subscriptions.updateNotificationUserPreferences(user._id, settings.audioNotifications, 'audioNotifications', 'audioPrefOrigin'); } }