diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 1d18d31ef923..0d057f3a85f1 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -413,6 +413,7 @@ "Desktop": "Desktop", "Desktop_Notification_Test": "Desktop Notification Test", "Desktop_Notifications": "Desktop Notifications", + "Desktop_Notifications_Default_Alert" : "Desktop Notifications Default Alert", "Desktop_Notifications_Disabled": "Desktop Notifications are Disabled. Change your browser preferences if you need Notifications enabled.", "Desktop_Notifications_Duration": "Desktop Notifications Duration", "Desktop_Notifications_Duration_Description": "Seconds to display desktop notification. This may affect OS X Notification Center. Enter 0 to use default browser settings and not affect OS X Notification Center.", @@ -965,7 +966,6 @@ "Max_length_is": "Max length is %s", "Members_List": "Members List", "Mentions": "Mentions", - "Mentions_default": "Mentions (default)", "Message": "Message", "Message_AllowBadWordsFilter": "Allow Message bad words filtering", "Message_AllowDeleting": "Allow Message Deleting", @@ -1029,6 +1029,7 @@ "Min_length_is": "Min length is %s", "minutes": "minutes", "Mobile": "Mobile", + "Mobile_Notifications_Default_Alert" : "Mobile Notifications Default Alert", "Monday": "Monday", "Monitor_history_for_changes_on": "Monitor history for changes on", "More_channels": "More channels", @@ -1085,9 +1086,13 @@ "Not_found_or_not_allowed": "Not Found or Not Allowed", "Nothing": "Nothing", "Nothing_found": "Nothing found", + "Notification_Desktop_Default_For" : "Show Desktop Notifications For", + "Notification_Mobile_Default_For" : "Push Mobile Notifications For", "Notification_Duration": "Notification Duration", "Notifications": "Notifications", "Notifications_Muted_Description": "If you choose to mute everything, you won't see the room highlight in the list when there are new messages, except for mentions. Muting notifications will override notifications settings.", + "Notifications_Max_Room_Members" : "Max room members before disabling all message notifications", + "Notifications_Max_Room_Members_Description" : "Max number of members in room when notifications for all messages gets disabled. Users can still change per room setting to receive all notifications on an individual basis. (0 to disable)", "Notify_all_in_this_room": "Notify all in this room", "Notify_active_in_this_room": "Notify active users in this room", "Num_Agents": "# Agents", @@ -1719,4 +1724,4 @@ "your_message_optional": "your message (optional)", "Your_password_is_wrong": "Your password is wrong!", "Your_push_was_sent_to_s_devices": "Your push was sent to %s devices" -} \ No newline at end of file +} diff --git a/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js b/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js index ea6ef470118a..362fa7c4f4dc 100644 --- a/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js +++ b/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js @@ -64,20 +64,41 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room) { settings.dontNotifyMobileUsers = []; settings.desktopNotificationDurations = {}; - const notificationPreferencesByRoom = RocketChat.models.Subscriptions.findNotificationPreferencesByRoom(room._id); - notificationPreferencesByRoom.forEach(function(subscription) { + // Don't fetch all users if room exceeds max members + const maxMembersForNotification = RocketChat.settings.get('Notifications_Max_Room_Members'); + const disableAllMessageNotifications = room.usernames.length > maxMembersForNotification && maxMembersForNotification !== 0; + const subscriptions = RocketChat.models.Subscriptions.findNotificationPreferencesByRoom(room._id, disableAllMessageNotifications); + const userIds = []; + subscriptions.forEach((s) => { + userIds.push(s.u._id); + }); + const userSettings = {}; + RocketChat.models.Users.findUsersByIds(userIds, { fields: { 'settings.preferences.desktopNotifications': 1, 'settings.preferences.mobileNotifications': 1 } }).forEach((user) => { + userSettings[user._id] = user.settings; + }); + + subscriptions.forEach((subscription) => { if (subscription.disableNotifications) { settings.dontNotifyDesktopUsers.push(subscription.u._id); settings.dontNotifyMobileUsers.push(subscription.u._id); } else { - if (subscription.desktopNotifications === 'all') { + const preferences = userSettings[subscription.u._id] ? userSettings[subscription.u._id].preferences || {} : {}; + const userDesktopNotificationPreference = preferences.desktopNotifications !== 'default' ? preferences.desktopNotifications : undefined; + const userMobileNotificationPreference = preferences.mobileNotifications !== 'default' ? preferences.mobileNotifications : undefined; + // Set defaults if they don't exist + const { + desktopNotifications = userDesktopNotificationPreference || RocketChat.settings.get('Desktop_Notifications_Default_Alert'), + mobilePushNotifications = userMobileNotificationPreference || RocketChat.settings.get('Mobile_Notifications_Default_Alert') + } = subscription; + + if (desktopNotifications === 'all' && !disableAllMessageNotifications) { settings.alwaysNotifyDesktopUsers.push(subscription.u._id); - } else if (subscription.desktopNotifications === 'nothing') { + } else if (desktopNotifications === 'nothing') { settings.dontNotifyDesktopUsers.push(subscription.u._id); } - if (subscription.mobilePushNotifications === 'all') { + if (mobilePushNotifications === 'all' && !disableAllMessageNotifications) { settings.alwaysNotifyMobileUsers.push(subscription.u._id); - } else if (subscription.mobilePushNotifications === 'nothing') { + } else if (mobilePushNotifications === 'nothing') { settings.dontNotifyMobileUsers.push(subscription.u._id); } } diff --git a/packages/rocketchat-lib/server/models/Users.coffee b/packages/rocketchat-lib/server/models/Users.coffee index 83519874f9fa..6821525ecdba 100644 --- a/packages/rocketchat-lib/server/models/Users.coffee +++ b/packages/rocketchat-lib/server/models/Users.coffee @@ -189,6 +189,13 @@ class ModelUsers extends RocketChat.models._Base return @find query, options + findUsersByIds: (ids, options) -> + query = + _id: + $in: ids + + return @find query, options + # UPDATE addImportIds: (_id, importIds) -> importIds = [].concat(importIds) diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index f222176bb388..a72076ae4f24 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -413,11 +413,42 @@ RocketChat.settings.addGroup('General', function() { }); }); this.section('Notifications', function() { - return this.add('Desktop_Notifications_Duration', 0, { + this.add('Desktop_Notifications_Duration', 0, { type: 'int', 'public': true, i18nDescription: 'Desktop_Notification_Durations_Description' }); + this.add('Desktop_Notifications_Default_Alert', 'all', { + type: 'select', + values: [{ + key: 'all', + i18nLabel: 'All_messages' + }, { + key: 'mentions', + i18nLabel: 'Mentions' + }, { + key: 'nothing', + i18nLabel: 'Nothing' + }], + public: true + }); + + this.add('Mobile_Notifications_Default_Alert', 'mentions', { + type: 'select', + values: [{ + key: 'all', + i18nLabel: 'All_messages' + }, { + key: 'mentions', + i18nLabel: 'Mentions' + }, { + key: 'nothing', + i18nLabel: 'Nothing' + }], + public: true + }); + + return this.add('Notifications_Max_Room_Members', 100, { type: 'int', public: true, i18nDescription: 'Notifications_Max_Room_Members_Description' }); }); this.section('REST API', function() { return this.add('API_User_Limit', 500, { diff --git a/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.html b/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.html index 8b051ec36ae0..4abdf969c0be 100644 --- a/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.html +++ b/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.html @@ -39,16 +39,16 @@

{{_ "Notifications"}}

{{#if editing 'desktopNotifications'}} + - +
{{#if desktopNotificationDuration}} - + {{else}} {{/if}} - {{else}} @@ -68,8 +68,9 @@

{{_ "Notifications"}}

{{#if editing 'mobilePushNotifications'}} + - + diff --git a/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.js b/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.js index fe793bae3c70..3fe7517b8ef6 100644 --- a/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.js +++ b/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.js @@ -43,7 +43,7 @@ Template.pushNotificationsFlexTab.helpers({ desktopNotifications: 1 } }); - return sub ? sub.desktopNotifications : ''; + return sub ? sub.desktopNotifications || 'default' : 'default'; }, mobilePushNotifications() { const sub = ChatSubscription.findOne({ @@ -53,7 +53,7 @@ Template.pushNotificationsFlexTab.helpers({ mobilePushNotifications: 1 } }); - return sub ? sub.mobilePushNotifications : ''; + return sub ? sub.mobilePushNotifications || 'default' : 'default'; }, emailNotifications() { const sub = ChatSubscription.findOne({ @@ -144,11 +144,7 @@ Template.pushNotificationsFlexTab.helpers({ case 'mentions': return t('Mentions'); default: - if (field === 'emailNotifications') { - return t('Use_account_preference'); - } else { - return t('Mentions'); - } + return t('Use_account_preference'); } } }, diff --git a/packages/rocketchat-push-notifications/server/models/Subscriptions.js b/packages/rocketchat-push-notifications/server/models/Subscriptions.js index 5a78bc875545..e55c965afd10 100644 --- a/packages/rocketchat-push-notifications/server/models/Subscriptions.js +++ b/packages/rocketchat-push-notifications/server/models/Subscriptions.js @@ -17,11 +17,13 @@ RocketChat.models.Subscriptions.updateDesktopNotificationsById = function(_id, d _id }; - const update = { - $set: { - desktopNotifications - } - }; + const update = {}; + + if (desktopNotifications === 'default') { + update.$unset = { desktopNotifications: 1 }; + } else { + update.$set = { desktopNotifications }; + } return this.update(query, update); }; @@ -45,11 +47,13 @@ RocketChat.models.Subscriptions.updateMobilePushNotificationsById = function(_id _id }; - const update = { - $set: { - mobilePushNotifications - } - }; + const update = {}; + + if (mobilePushNotifications === 'default') { + update.$unset = { mobilePushNotifications: 1 }; + } else { + update.$set = { mobilePushNotifications }; + } return this.update(query, update); }; @@ -146,20 +150,23 @@ RocketChat.models.Subscriptions.findDontNotifyMobileUsersByRoomId = function(roo return this.find(query); }; -RocketChat.models.Subscriptions.findNotificationPreferencesByRoom = function(roomId) { +RocketChat.models.Subscriptions.findNotificationPreferencesByRoom = function(roomId, explicit) { const query = { rid: roomId, - 'u._id': {$exists: true}, - $or: [ + 'u._id': {$exists: true} + }; + + if (explicit) { + query.$or = [ {audioNotification: {$exists: true}}, {desktopNotifications: {$exists: true}}, {desktopNotificationDuration: {$exists: true}}, {mobilePushNotifications: {$exists: true}}, {disableNotifications: {$exists: true}} - ] - }; + ]; + } - return this.find(query); + return this.find(query, { fields: { 'u._id': 1, desktopNotificationDuration: 1, desktopNotifications: 1, mobilePushNotifications: 1 } }); }; RocketChat.models.Subscriptions.findWithSendEmailByRoomId = function(roomId) { diff --git a/packages/rocketchat-ui-account/client/accountPreferences.coffee b/packages/rocketchat-ui-account/client/accountPreferences.coffee index 5ed2003c658c..51f03ed129dc 100644 --- a/packages/rocketchat-ui-account/client/accountPreferences.coffee +++ b/packages/rocketchat-ui-account/client/accountPreferences.coffee @@ -96,6 +96,8 @@ Template.accountPreferences.onCreated -> data.emailNotificationMode = $('select[name=emailNotificationMode]').val() data.highlights = _.compact(_.map($('[name=highlights]').val().split(','), (e) -> return _.trim(e))) data.desktopNotificationDuration = $('input[name=desktopNotificationDuration]').val() + data.desktopNotifications = $('#desktopNotifications').find('select').val() + data.mobileNotifications = $('#mobileNotifications').find('select').val() data.unreadAlert = $('#unreadAlert').find('input:checked').val() Meteor.call 'saveUserPreferences', data, (error, results) -> diff --git a/packages/rocketchat-ui-account/client/accountPreferences.html b/packages/rocketchat-ui-account/client/accountPreferences.html index 8d3bd2116dbc..cbbca1f26eb7 100644 --- a/packages/rocketchat-ui-account/client/accountPreferences.html +++ b/packages/rocketchat-ui-account/client/accountPreferences.html @@ -52,6 +52,28 @@

{{_ "Messages"}}

{{/if}}
+
+ +
+ +
+
+
+ +
+ +
+
diff --git a/server/methods/saveUserPreferences.js b/server/methods/saveUserPreferences.js index 2d951fd35a66..c4c5c722b599 100644 --- a/server/methods/saveUserPreferences.js +++ b/server/methods/saveUserPreferences.js @@ -55,6 +55,14 @@ Meteor.methods({ preferences.unreadAlert = settings.unreadAlert === '1' ? true : false; } + if (settings.desktopNotifications) { + preferences.desktopNotifications = settings.desktopNotifications; + } + + if (settings.mobileNotifications) { + preferences.mobileNotifications = settings.mobileNotifications; + } + preferences.desktopNotificationDuration = settings.desktopNotificationDuration - 0; preferences.viewMode = settings.viewMode || 0; preferences.hideUsernames = settings.hideUsernames === '1';