diff --git a/client/notifications/notification.js b/client/notifications/notification.js index 85364e99dc4..76ce45419a7 100644 --- a/client/notifications/notification.js +++ b/client/notifications/notification.js @@ -7,7 +7,7 @@ Meteor.startup(function() { Tracker.autorun(function() { if (Meteor.userId()) { - RocketChat.Notifications.onUser('notification', function(notification) { + RocketChat.Notifications.onUser('desktopNotification', function(notification) { let openedRoomId = undefined; if (['channel', 'group', 'direct'].includes(FlowRouter.getRouteName())) { @@ -36,6 +36,34 @@ Meteor.startup(function() { KonchatNotification.showDesktop(notification); } }); + + RocketChat.Notifications.onUser('audioNotification', function(notification) { + + let openedRoomId = undefined; + if (['channel', 'group', 'direct'].includes(FlowRouter.getRouteName())) { + openedRoomId = Session.get('openedRoom'); + } + + // This logic is duplicated in /client/startup/unread.coffee. + const hasFocus = readMessage.isEnable(); + const messageIsInOpenedRoom = openedRoomId === notification.payload.rid; + + fireGlobalEvent('notification', { + notification, + fromOpenedRoom: messageIsInOpenedRoom, + hasFocus + }); + + if (RocketChat.Layout.isEmbedded()) { + if (!hasFocus && messageIsInOpenedRoom) { + // Play a sound and show a notification. + KonchatNotification.newMessage(notification.payload.rid); + } + } else if (!(hasFocus && messageIsInOpenedRoom)) { + // Play a sound and show a notification. + KonchatNotification.newMessage(notification.payload.rid); + } + }); } }); }); diff --git a/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js b/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js index 7f4479d86c7..e5804ceb7d7 100644 --- a/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js +++ b/packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js @@ -46,7 +46,7 @@ function parseMessageText(message, userId) { * @param {object} room The room send from * @param {number} duration Duration of notification */ -function notifyUser(userId, user, message, room, duration) { +function notifyDesktopUser(userId, user, message, room, duration) { const UI_Use_Real_Name = RocketChat.settings.get('UI_Use_Real_Name') === true; message.msg = parseMessageText(message, userId); @@ -58,7 +58,7 @@ function notifyUser(userId, user, message, room, duration) { if (room.t !== 'd' && room.name) { title += ` @ #${ room.name }`; } - RocketChat.Notifications.notifyUser(userId, 'notification', { + RocketChat.Notifications.notifyUser(userId, 'desktopNotification', { title, text: message.msg, duration, @@ -72,6 +72,31 @@ function notifyUser(userId, user, message, room, duration) { }); } +function notifyAudioUser(userId, user, message, room) { + + const UI_Use_Real_Name = RocketChat.settings.get('UI_Use_Real_Name') === true; + message.msg = parseMessageText(message, userId); + + if (UI_Use_Real_Name) { + message.msg = replaceMentionedUsernamesWithFullNames(message.msg, message.mentions); + } + let title = UI_Use_Real_Name ? user.name : `@${ user.username }`; + if (room.t !== 'd' && room.name) { + title += ` @ #${ room.name }`; + } + RocketChat.Notifications.notifyUser(userId, 'audioNotification', { + title, + text: message.msg, + payload: { + _id: message._id, + rid: message.rid, + sender: message.u, + type: room.t, + name: room.name + } + }); +} + /** * Checks if a message contains a user highlight * @@ -124,7 +149,10 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room, userId) { dontNotifyDesktopUsers: [], alwaysNotifyMobileUsers: [], dontNotifyMobileUsers: [], - desktopNotificationDurations: {} + desktopNotificationDurations: {}, + alwaysNotifyAudioUsers: [], + dontNotifyAudioUsers: [], + audioNotificationValues: {} }; /** @@ -138,7 +166,8 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room, userId) { function canBeNotified(id, type) { const types = { mobile: [ 'dontNotifyDesktopUsers', 'alwaysNotifyDesktopUsers' ], - desktop: [ 'dontNotifyMobileUsers', 'alwaysNotifyMobileUsers' ] + desktop: [ 'dontNotifyMobileUsers', 'alwaysNotifyMobileUsers' ], + audio: [ 'dontNotifyAudioUsers', 'alwaysNotifyAudioUsers' ] }; return (settings[types[type][0]].indexOf(id) === -1 || settings[types[type][1]].indexOf(id) !== -1); @@ -153,7 +182,7 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room, userId) { userIds.push(s.u._id); }); const userSettings = {}; - RocketChat.models.Users.findUsersByIds(userIds, { fields: { 'settings.preferences.desktopNotifications': 1, 'settings.preferences.mobileNotifications': 1 } }).forEach((user) => { + RocketChat.models.Users.findUsersByIds(userIds, { fields: { 'settings.preferences.audioNotifications': 1, 'settings.preferences.desktopNotifications': 1, 'settings.preferences.mobileNotifications': 1 } }).forEach((user) => { userSettings[user._id] = user.settings; }); @@ -161,16 +190,22 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room, userId) { if (subscription.disableNotifications) { settings.dontNotifyDesktopUsers.push(subscription.u._id); settings.dontNotifyMobileUsers.push(subscription.u._id); + settings.dontNotifyAudioUsers.push(subscription.u._id); } else { const preferences = userSettings[subscription.u._id] ? userSettings[subscription.u._id].preferences || {} : {}; + const userAudioNotificationPreference = preferences.audioNotifications !== 'default' ? preferences.audioNotifications : undefined; const userDesktopNotificationPreference = preferences.desktopNotifications !== 'default' ? preferences.desktopNotifications : undefined; const userMobileNotificationPreference = preferences.mobileNotifications !== 'default' ? preferences.mobileNotifications : undefined; // Set defaults if they don't exist const { + audioNotifications = userAudioNotificationPreference || RocketChat.settings.get('Audio_Notifications_Default_Alert'), desktopNotifications = userDesktopNotificationPreference || RocketChat.settings.get('Desktop_Notifications_Default_Alert'), mobilePushNotifications = userMobileNotificationPreference || RocketChat.settings.get('Mobile_Notifications_Default_Alert') } = subscription; + if (audioNotifications === 'all' && !disableAllMessageNotifications) { + settings.alwaysNotifyAudioUsers.push(subscription.u._id); + } if (desktopNotifications === 'all' && !disableAllMessageNotifications) { settings.alwaysNotifyDesktopUsers.push(subscription.u._id); } else if (desktopNotifications === 'nothing') { @@ -182,11 +217,13 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room, userId) { settings.dontNotifyMobileUsers.push(subscription.u._id); } } + settings.audioNotificationValues[subscription.u._id] = subscription.audioNotificationValue; settings.desktopNotificationDurations[subscription.u._id] = subscription.desktopNotificationDuration; }); - + let userIdsForAudio = []; let userIdsToNotify = []; let userIdsToPushNotify = []; + const usersWithHighlights = []; const highlights = RocketChat.models.Users.findUsersByUsernamesWithHighlights(room.usernames, { fields: { '_id': 1, 'settings.preferences.highlights': 1 }}).fetch(); @@ -229,7 +266,7 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room, userId) { } if ((userOfMention != null) && canBeNotified(userOfMentionId, 'mobile')) { const duration = settings.desktopNotificationDurations[userOfMention._id]; - notifyUser(userOfMention._id, user, message, room, duration); + notifyDesktopUser(userOfMention._id, user, message, room, duration); } if ((userOfMention != null) && canBeNotified(userOfMentionId, 'desktop')) { @@ -329,6 +366,45 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room, userId) { }), '_id'); } + if (mentionIds.length > 0 || settings.alwaysNotifyAudioUsers.length > 0) { + let audioMentionIds = _.union(mentionIds, settings.alwaysNotifyAudioUsers); + audioMentionIds = _.difference(audioMentionIds, userIdsToNotify); + + let usersOfAudioMentions = RocketChat.models.Users.find({ + _id: { + $in: audioMentionIds + } + }, { + fields: { + _id: 1, + username: 1, + active: 1 + } + }).fetch(); + if (room.t === 'c' && !toAll) { + const callJoin = function(usersOfMentionItem) { + if (usersOfMentionItem.active) { + Meteor.runAsUser(usersOfMentionItem._id, function() { + return Meteor.call('joinRoom', room._id); + }); + } + }; + for (const usersOfMentionItem of usersOfAudioMentions) { + if (room.usernames.indexOf(usersOfMentionItem.username) === -1) { + callJoin(usersOfMentionItem); + } + } + } + + if (room.t !== 'c') { + usersOfAudioMentions = _.reject(usersOfAudioMentions, (usersOfMentionItem) => { + return room.usernames.indexOf(usersOfMentionItem.username) === -1; + }); + } + + userIdsForAudio = _.pluck(usersOfAudioMentions, '_id'); + } + if ((toAll || toHere) && room.usernames && room.usernames.length > 0) { RocketChat.models.Users.find({ username: { @@ -347,26 +423,38 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room, userId) { }).forEach(function(user) { if (['online', 'away', 'busy'].includes(user.status) && (settings.dontNotifyDesktopUsers || []).includes(user._id) === false) { userIdsToNotify.push(user._id); + userIdsForAudio.push(user._id); } if (toAll && user.statusConnection !== 'online' && (settings.dontNotifyMobileUsers || []).includes(user._id) === false) { return userIdsToPushNotify.push(user._id); } + if (toAll && user.statusConnection !== 'online') { + userIdsForAudio.push(user._id); + } }); } if (usersWithHighlights.length > 0) { const highlightsIds = _.pluck(usersWithHighlights, '_id'); + userIdsForAudio = userIdsForAudio.concat(highlightsIds); userIdsToNotify = userIdsToNotify.concat(highlightsIds); userIdsToPushNotify = userIdsToPushNotify.concat(highlightsIds); } userIdsToNotify = _.without(_.compact(_.unique(userIdsToNotify)), message.u._id); userIdsToPushNotify = _.without(_.compact(_.unique(userIdsToPushNotify)), message.u._id); + userIdsForAudio = _.without(_.compact(_.unique(userIdsForAudio)), message.u._id); if (userIdsToNotify.length > 0) { for (const usersOfMentionId of userIdsToNotify) { const duration = settings.desktopNotificationDurations[usersOfMentionId]; - notifyUser(usersOfMentionId, user, message, room, duration); + notifyDesktopUser(usersOfMentionId, user, message, room, duration); + } + } + + if (userIdsForAudio.length > 0) { + for (const usersOfMentionId of userIdsForAudio) { + notifyAudioUser(usersOfMentionId, user, message, room); } } diff --git a/packages/rocketchat-lib/server/models/Subscriptions.js b/packages/rocketchat-lib/server/models/Subscriptions.js index 8485a9b2aa8..667855282b4 100644 --- a/packages/rocketchat-lib/server/models/Subscriptions.js +++ b/packages/rocketchat-lib/server/models/Subscriptions.js @@ -12,7 +12,7 @@ class ModelSubscriptions extends RocketChat.models._Base { this.tryEnsureIndex({ 'unread': 1 }); this.tryEnsureIndex({ 'ts': 1 }); this.tryEnsureIndex({ 'ls': 1 }); - this.tryEnsureIndex({ 'audioNotification': 1 }, { sparse: 1 }); + this.tryEnsureIndex({ 'audioNotifications': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'desktopNotifications': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'mobilePushNotifications': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'emailNotifications': 1 }, { sparse: 1 }); diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index 325ff3d7e74..28e956f53c9 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -433,6 +433,27 @@ RocketChat.settings.addGroup('General', function() { i18nDescription: 'Desktop_Notification_Durations_Description' }); + this.add('Audio_Notifications_Value', 'chime', { + type: 'int', + 'public': true, + i18nDescription: 'Audio_Notification_Value_Description' + }); + + this.add('Audio_Notifications_Default_Alert', 'mentions', { + type: 'select', + values: [{ + key: 'all', + i18nLabel: 'All_messages' + }, { + key: 'mentions', + i18nLabel: 'Mentions' + }, { + key: 'nothing', + i18nLabel: 'Nothing' + }], + public: true + }); + this.add('Desktop_Notifications_Default_Alert', 'mentions', { type: 'select', values: [{ diff --git a/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.html b/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.html index dc46fb79ebf..b91574e260a 100644 --- a/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.html +++ b/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.html @@ -16,21 +16,26 @@
  • - {{#if editing 'audioNotification'}} + {{#if editing 'audioNotifications'}} + + + +
    + {{else}} - {{audioValue}} + {{subValue 'audioNotifications'}} : {{audioNotificationValue}} {{/if}}
  • diff --git a/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.js b/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.js index 6687cf1f663..ca1cbccef86 100644 --- a/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.js +++ b/packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.js @@ -16,35 +16,35 @@ Template.pushNotificationsFlexTab.helpers({ audioAssets() { return RocketChat.CustomSounds && RocketChat.CustomSounds.getList && RocketChat.CustomSounds.getList() || []; }, - audioNotification() { + disableNotifications() { const sub = ChatSubscription.findOne({ rid: Session.get('openedRoom') }, { fields: { - audioNotification: 1 + disableNotifications: 1 } }); - return sub ? sub.audioNotification || '' : ''; + return sub ? sub.disableNotifications || false : false; }, - disableNotifications() { + hideUnreadStatus() { const sub = ChatSubscription.findOne({ rid: Session.get('openedRoom') }, { fields: { - disableNotifications: 1 + hideUnreadStatus: 1 } }); - return sub ? sub.disableNotifications || false : false; + return sub ? sub.hideUnreadStatus || false : false; }, - hideUnreadStatus() { + audioNotifications() { const sub = ChatSubscription.findOne({ rid: Session.get('openedRoom') }, { fields: { - hideUnreadStatus: 1 + audioNotifications: 1 } }); - return sub ? sub.hideUnreadStatus || false : false; + return sub ? sub.audioNotifications || 'default' : 'default'; }, desktopNotifications() { const sub = ChatSubscription.findOne({ @@ -114,27 +114,6 @@ Template.pushNotificationsFlexTab.helpers({ } return t('Use_account_preference'); }, - audioValue() { - const sub = ChatSubscription.findOne({ - rid: Session.get('openedRoom') - }, { - fields: { - audioNotification: 1 - } - }); - const audio = sub ? sub.audioNotification || '': ''; - if (audio === 'none') { - return t('None'); - } else if (audio === '') { - return t('Use_account_preference'); - } else if (audio === 'chime') { - return 'Chime'; - } else { - const audioAssets = RocketChat.CustomSounds && RocketChat.CustomSounds.getList && RocketChat.CustomSounds.getList() || []; - const asset = _.findWhere(audioAssets, { _id: audio }); - return asset && asset.name; - } - }, subValue(field) { const sub = ChatSubscription.findOne({ rid: Session.get('openedRoom') @@ -159,6 +138,20 @@ Template.pushNotificationsFlexTab.helpers({ } } }, + audioNotificationValue() { + const sub = ChatSubscription.findOne({ + rid: Session.get('openedRoom') + }, { + fields: { + audioNotificationValue: 1 + } + }); + const audio = sub ? sub.audioNotificationValue || 'default' : 'default'; + if (audio === 'default') { + return t('Use_account_preference'); + } + return audio; + }, desktopNotificationDuration() { const sub = ChatSubscription.findOne({ rid: Session.get('openedRoom') @@ -179,6 +172,13 @@ Template.pushNotificationsFlexTab.helpers({ emailVerified() { return Meteor.user().emails && Meteor.user().emails[0] && Meteor.user().emails[0].verified; }, + defaultAudioNotification() { + let preference = getUserPreference('audioNotifications'); + if (preference === 'default' || preference == null) { + preference = RocketChat.settings.get('Audio_Notifications_Default_Alert'); + } + return notificationLabels[preference]; + }, defaultDesktopNotification() { let preference = getUserPreference('desktopNotifications'); if (preference === 'default' || preference == null) { @@ -200,7 +200,8 @@ Template.pushNotificationsFlexTab.onCreated(function() { this.validateSetting = (field) => { switch (field) { - case 'audioNotification': + case 'audioNotificationValue': + return true; case 'hideUnreadStatus': case 'disableNotifications': return true; @@ -218,9 +219,6 @@ Template.pushNotificationsFlexTab.onCreated(function() { const field = this.editing.get(); let value; switch (field) { - case 'audioNotification': - value = this.$(`select[name=${ field }]`).val(); - break; case 'hideUnreadStatus': case 'disableNotifications': value = this.$(`input[name=${ field }]:checked`).val() ? '1' : '0'; @@ -229,22 +227,26 @@ Template.pushNotificationsFlexTab.onCreated(function() { value = this.$(`input[name=${ field }]:checked`).val(); break; } + const soundVal = $('select').val(); const duration = $('input[name=duration]').val(); if (this.validateSetting(field)) { Meteor.call('saveNotificationSettings', Session.get('openedRoom'), field, value, (err/*, result*/) => { if (err) { return handleError(err); - } - if (duration !== undefined) { + } else if (duration !== undefined) { Meteor.call('saveDesktopNotificationDuration', Session.get('openedRoom'), duration, (err) => { if (err) { return handleError(err); } - this.editing.set(); }); - } else { - this.editing.set(); + } else if (soundVal!==undefined) { + Meteor.call('saveAudioNotificationValue', Session.get('openedRoom'), soundVal, (err) => { + if (err) { + return handleError(err); + } + }); } + this.editing.set(); }); } }; @@ -280,7 +282,7 @@ Template.pushNotificationsFlexTab.events({ let audio = $(e.currentTarget).data('play'); const user = Meteor.user(); - if (!audio || audio === 'none') { + if (audio === 'Use account preference' || audio === 'none') { audio = user && user.settings && user.settings.preferences && user.settings.preferences.newMessageNotification || 'chime'; } @@ -295,12 +297,15 @@ Template.pushNotificationsFlexTab.events({ } }, - 'change select[name=audioNotification]'(e) { + 'change select[name=audioNotificationValue]'(e) { e.preventDefault(); - const audio = $(e.currentTarget).val(); + let audio = $(e.currentTarget).val(); const user = Meteor.user(); + if (audio==='') { + audio = user && user.settings && user.settings.preferences && user.settings.preferences.newMessageNotification || 'chime'; + } if (audio && audio !== 'none') { const audioVolume = user && user.settings && user.settings.preferences && user.settings.preferences.notificationsSoundVolume || 100; const $audio = $(`audio#${ audio }`); diff --git a/packages/rocketchat-push-notifications/server/methods/saveNotificationSettings.js b/packages/rocketchat-push-notifications/server/methods/saveNotificationSettings.js index f559db2ff31..365d0b3f6c5 100644 --- a/packages/rocketchat-push-notifications/server/methods/saveNotificationSettings.js +++ b/packages/rocketchat-push-notifications/server/methods/saveNotificationSettings.js @@ -8,11 +8,11 @@ Meteor.methods({ check(field, String); check(value, String); - if (['audioNotification', 'desktopNotifications', 'mobilePushNotifications', 'emailNotifications', 'unreadAlert', 'disableNotifications', 'hideUnreadStatus'].indexOf(field) === -1) { + if (['audioNotifications', 'desktopNotifications', 'mobilePushNotifications', 'emailNotifications', 'unreadAlert', 'disableNotifications', 'hideUnreadStatus'].indexOf(field) === -1) { throw new Meteor.Error('error-invalid-settings', 'Invalid settings field', { method: 'saveNotificationSettings' }); } - if (field !== 'audioNotification' && field !== 'hideUnreadStatus' && field !== 'disableNotifications' && ['all', 'mentions', 'nothing', 'default'].indexOf(value) === -1) { + if (field !== 'hideUnreadStatus' && field !== 'disableNotifications' && ['all', 'mentions', 'nothing', 'default'].indexOf(value) === -1) { throw new Meteor.Error('error-invalid-settings', 'Invalid settings value', { method: 'saveNotificationSettings' }); } @@ -22,8 +22,8 @@ Meteor.methods({ } switch (field) { - case 'audioNotification': - RocketChat.models.Subscriptions.updateAudioNotificationById(subscription._id, value); + case 'audioNotifications': + RocketChat.models.Subscriptions.updateAudioNotificationsById(subscription._id, value); break; case 'desktopNotifications': RocketChat.models.Subscriptions.updateDesktopNotificationsById(subscription._id, value); @@ -48,6 +48,15 @@ Meteor.methods({ return true; }, + saveAudioNotificationValue(rid, value) { + const subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(rid, Meteor.userId()); + if (!subscription) { + throw new Meteor.Error('error-invalid-subscription', 'Invalid subscription', { method: 'saveAudioNotificationValue' }); + } + RocketChat.models.Subscriptions.updateAudioNotificationValueById(subscription._id, value); + return true; + }, + saveDesktopNotificationDuration(rid, value) { const subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(rid, Meteor.userId()); if (!subscription) { diff --git a/packages/rocketchat-push-notifications/server/models/Subscriptions.js b/packages/rocketchat-push-notifications/server/models/Subscriptions.js index e55c965afd1..8a9356bef04 100644 --- a/packages/rocketchat-push-notifications/server/models/Subscriptions.js +++ b/packages/rocketchat-push-notifications/server/models/Subscriptions.js @@ -1,11 +1,27 @@ -RocketChat.models.Subscriptions.updateAudioNotificationById = function(_id, audioNotification) { +RocketChat.models.Subscriptions.updateAudioNotificationsById = function(_id, audioNotifications) { + const query = { + _id + }; + + const update = {}; + + if (audioNotifications === 'default') { + update.$unset = { audioNotifications: 1 }; + } else { + update.$set = { audioNotifications }; + } + + return this.update(query, update); +}; + +RocketChat.models.Subscriptions.updateAudioNotificationValueById = function(_id, audioNotificationValue) { const query = { _id }; const update = { $set: { - audioNotification + audioNotificationValue } }; @@ -114,6 +130,15 @@ RocketChat.models.Subscriptions.updateHideUnreadStatusById = function(_id, hideU return this.update(query, update); }; +RocketChat.models.Subscriptions.findAlwaysNotifyAudioUsersByRoomId = function(roomId) { + const query = { + rid: roomId, + audioNotifications: 'all' + }; + + return this.find(query); +}; + RocketChat.models.Subscriptions.findAlwaysNotifyDesktopUsersByRoomId = function(roomId) { const query = { rid: roomId, @@ -158,7 +183,8 @@ RocketChat.models.Subscriptions.findNotificationPreferencesByRoom = function(roo if (explicit) { query.$or = [ - {audioNotification: {$exists: true}}, + {audioNotifications: {$exists: true}}, + {audioNotificationValue: {$exists: true}}, {desktopNotifications: {$exists: true}}, {desktopNotificationDuration: {$exists: true}}, {mobilePushNotifications: {$exists: true}}, @@ -166,7 +192,7 @@ RocketChat.models.Subscriptions.findNotificationPreferencesByRoom = function(roo ]; } - return this.find(query, { fields: { 'u._id': 1, desktopNotificationDuration: 1, desktopNotifications: 1, mobilePushNotifications: 1 } }); + return this.find(query, { fields: { 'u._id': 1, audioNotifications: 1, audioNotificationValue: 1, desktopNotificationDuration: 1, desktopNotifications: 1, mobilePushNotifications: 1 } }); }; RocketChat.models.Subscriptions.findWithSendEmailByRoomId = function(roomId) { diff --git a/packages/rocketchat-ui-account/client/accountPreferences.js b/packages/rocketchat-ui-account/client/accountPreferences.js index 97042a43506..1239dfac1e8 100644 --- a/packages/rocketchat-ui-account/client/accountPreferences.js +++ b/packages/rocketchat-ui-account/client/accountPreferences.js @@ -72,6 +72,12 @@ Template.accountPreferences.helpers({ desktopNotificationDisabled() { return KonchatNotification.notificationStatus.get() === 'denied' || (window.Notification && Notification.permission === 'denied'); }, + defaultAudioNotification() { + return notificationLabels[RocketChat.settings.get('Audio_Notifications_Default_Alert')]; + }, + defaultAudioNotificationValue() { + return RocketChat.settings.get('Audio_Notifications_Value'); + }, desktopNotificationDuration() { const user = Meteor.user(); return user && user.settings && user.settings.preferences && user.settings.preferences.desktopNotificationDuration; diff --git a/packages/rocketchat-ui/client/lib/notification.js b/packages/rocketchat-ui/client/lib/notification.js index e94ae6556a4..af8519ecfcb 100644 --- a/packages/rocketchat-ui/client/lib/notification.js +++ b/packages/rocketchat-ui/client/lib/notification.js @@ -82,11 +82,11 @@ const KonchatNotification = { const newMessageNotification = user && user.settings && user.settings.preferences && user.settings.preferences.newMessageNotification || 'chime'; const audioVolume = user && user.settings && user.settings.preferences && user.settings.preferences.notificationsSoundVolume || 100; - const sub = ChatSubscription.findOne({ rid }, { fields: { audioNotification: 1 } }); + const sub = ChatSubscription.findOne({ rid }, { fields: { audioNotificationValue: 1 } }); - if (sub && sub.audioNotification !== 'none') { - if (sub && sub.audioNotification) { - const [audio] = $(`audio#${ sub.audioNotification }`); + if (sub && sub.audioNotificationValue !== 'none') { + if (sub && sub.audioNotificationValue) { + const [audio] = $(`audio#${ sub.audioNotificationValue }`); if (audio && audio.play) { audio.volume = Number((audioVolume/100).toPrecision(2)); return audio.play(); diff --git a/server/methods/saveUserPreferences.js b/server/methods/saveUserPreferences.js index 08c61a22a01..1255fa0e331 100644 --- a/server/methods/saveUserPreferences.js +++ b/server/methods/saveUserPreferences.js @@ -63,6 +63,9 @@ Meteor.methods({ preferences.notificationsSoundVolume = settings.notificationsSoundVolume; } + if (settings.audioNotifications) { + preferences.audioNotifications = settings.audioNotifications; + } if (settings.desktopNotifications) { preferences.desktopNotifications = settings.desktopNotifications; } @@ -70,6 +73,7 @@ Meteor.methods({ preferences.mobileNotifications = settings.mobileNotifications; } + preferences.audioNotificationValue = settings.audioNotificationValue - 0; preferences.desktopNotificationDuration = settings.desktopNotificationDuration - 0; preferences.viewMode = settings.viewMode || 0; preferences.hideUsernames = settings.hideUsernames === '1'; diff --git a/server/publications/subscription.js b/server/publications/subscription.js index 22982aa7a05..89222ed32bc 100644 --- a/server/publications/subscription.js +++ b/server/publications/subscription.js @@ -16,7 +16,8 @@ const fields = { userMentions: 1, groupMentions: 1, archived: 1, - audioNotification: 1, + audioNotifications: 1, + audioNotificationValue: 1, desktopNotifications: 1, desktopNotificationDuration: 1, mobilePushNotifications: 1,