Merge pull request #7479 from SKA-T/develop

[NEW] Add admin and user setting for notifications #4339
pull/7193/merge
Rodrigo Nascimento 8 years ago committed by GitHub
commit 78b39015e0
  1. 6
      packages/rocketchat-i18n/i18n/en.i18n.json
  2. 44
      packages/rocketchat-lib/server/lib/sendNotificationsOnMessage.js
  3. 9
      packages/rocketchat-lib/server/models/Users.js
  4. 38
      packages/rocketchat-lib/server/startup/settings.js
  5. 8
      packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.html
  6. 35
      packages/rocketchat-push-notifications/client/views/pushNotificationsFlexTab.js
  7. 39
      packages/rocketchat-push-notifications/server/models/Subscriptions.js
  8. 24
      packages/rocketchat-ui-account/client/accountPreferences.html
  9. 18
      packages/rocketchat-ui-account/client/accountPreferences.js
  10. 7
      server/methods/saveUserPreferences.js

@ -419,6 +419,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.",
@ -1049,6 +1050,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",
@ -1105,9 +1107,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)",
"Notifications_Sound_Volume": "Notifications sound volume",
"Notify_all_in_this_room": "Notify all in this room",
"Notify_active_in_this_room": "Notify active users in this room",

@ -144,20 +144,41 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room, userId) {
return (settings[types[type][0]].indexOf(id) === -1 || settings[types[type][1]].indexOf(id) !== -1);
}
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);
}
}
@ -176,22 +197,17 @@ RocketChat.callbacks.add('afterSaveMessage', function(message, room, userId) {
}
});
let push_message;
let push_message = ' ';
//Set variables depending on Push Notification settings
if (RocketChat.settings.get('Push_show_message')) {
push_message = parseMessageText(message, userId);
} else {
push_message = ' ';
}
let push_username;
let push_room;
let push_username = '';
let push_room = '';
if (RocketChat.settings.get('Push_show_username_room')) {
push_username = user.username;
push_room = `#${ room.name }`;
} else {
push_username = '';
push_room = '';
}
if (room.t == null || room.t === 'd') {

@ -229,6 +229,15 @@ class ModelUsers extends RocketChat.models._Base {
return this.find(query, options);
}
findUsersByIds(ids, options) {
const query = {
_id: {
$in: ids
}
};
return this.find(query, options);
}
// UPDATE
addImportIds(_id, importIds) {
importIds = [].concat(importIds);

@ -414,11 +414,47 @@ 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', 'mentions', {
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
});
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, {

@ -38,12 +38,13 @@
<label>{{_ "Desktop"}}</label>
<div>
{{#if editing 'desktopNotifications'}}
<label><input type="radio" name="desktopNotifications" value="default" checked="{{$eq desktopNotifications 'default'}}" /> {{_ "Default"}} ({{_ defaultDesktopNotification}})</label>
<label><input type="radio" name="desktopNotifications" value="all" checked="{{$eq desktopNotifications 'all'}}" /> {{_ "All_messages"}}</label>
<label><input type="radio" name="desktopNotifications" value="mentions" checked="{{$eq desktopNotifications 'mentions'}}" /> {{_ "Mentions_default"}}</label>
<label><input type="radio" name="desktopNotifications" value="mentions" checked="{{$eq desktopNotifications 'mentions'}}" /> {{_ "Mentions"}}</label>
<label><input type="radio" name="desktopNotifications" value="nothing" checked="{{$eq desktopNotifications 'nothing'}}" /> {{_ "Nothing"}}</label>
<br />
{{#if desktopNotificationDuration}}
<label>{{_ "Duration"}} ({{_ "seconds"}}) <input type="number" name="duration" min="0" value="{{desktopNotificationDuration}}"></label>
<label>{{_ "Duration"}} ({{_ "seconds"}}) <input type="number" name="duration" min="0" value="{{desktopNotificationDuration}}" class="content-background-color"></label>
{{else}}
<label>{{_ "Duration"}} ({{_ "seconds"}}) <input type="number" name="duration" min="0" value="" placeholder="{{_ "Use_User_Preferences_or_Global_Settings"}}"></label>
{{/if}}
@ -67,8 +68,9 @@
<label>{{_ "Mobile"}}</label>
<div>
{{#if editing 'mobilePushNotifications'}}
<label><input type="radio" name="mobilePushNotifications" value="default" checked="{{$eq mobilePushNotifications 'default'}}" /> {{_ "Default"}} ({{_ defaultMobileNotification}})</label>
<label><input type="radio" name="mobilePushNotifications" value="all" checked="{{$eq mobilePushNotifications 'all'}}" /> {{_ "All_messages"}}</label>
<label><input type="radio" name="mobilePushNotifications" value="mentions" checked="{{$eq mobilePushNotifications 'mentions'}}" /> {{_ "Mentions_default"}}</label>
<label><input type="radio" name="mobilePushNotifications" value="mentions" checked="{{$eq mobilePushNotifications 'mentions'}}" /> {{_ "Mentions"}}</label>
<label><input type="radio" name="mobilePushNotifications" value="nothing" checked="{{$eq mobilePushNotifications 'nothing'}}" /> {{_ "Nothing"}}</label>
<button type="button" class="button cancel">{{_ "Cancel"}}</button>
<button type="button" class="button primary save">{{_ "Save"}}</button>

@ -1,6 +1,17 @@
import toastr from 'toastr';
/* globals ChatSubscription */
const notificationLabels = {
all: 'All_messages',
mentions: 'Mentions',
nothing: 'Nothing'
};
function getUserPreference(preference) {
const user = Meteor.user();
return user && user.settings && user.settings.preferences && user.settings.preferences[preference];
}
Template.pushNotificationsFlexTab.helpers({
audioAssets() {
return RocketChat.CustomSounds && RocketChat.CustomSounds.getList && RocketChat.CustomSounds.getList() || [];
@ -43,7 +54,7 @@ Template.pushNotificationsFlexTab.helpers({
desktopNotifications: 1
}
});
return sub ? sub.desktopNotifications : '';
return sub ? sub.desktopNotifications || 'default' : 'default';
},
mobilePushNotifications() {
const sub = ChatSubscription.findOne({
@ -53,7 +64,7 @@ Template.pushNotificationsFlexTab.helpers({
mobilePushNotifications: 1
}
});
return sub ? sub.mobilePushNotifications : '';
return sub ? sub.mobilePushNotifications || 'default' : 'default';
},
emailNotifications() {
const sub = ChatSubscription.findOne({
@ -144,11 +155,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');
}
}
},
@ -171,6 +178,20 @@ Template.pushNotificationsFlexTab.helpers({
},
emailVerified() {
return Meteor.user().emails && Meteor.user().emails[0] && Meteor.user().emails[0].verified;
},
defaultDesktopNotification() {
let preference = getUserPreference('desktopNotifications');
if (preference === 'default' || preference == null) {
preference = RocketChat.settings.get('Desktop_Notifications_Default_Alert');
}
return notificationLabels[preference];
},
defaultMobileNotification() {
let preference = getUserPreference('mobileNotifications');
if (preference === 'default' || preference == null) {
preference = RocketChat.settings.get('Mobile_Notifications_Default_Alert');
}
return notificationLabels[preference];
}
});

@ -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) {

@ -48,10 +48,32 @@
{{#if desktopNotificationDuration}}
<input type="number" name="desktopNotificationDuration" min="0" value="{{desktopNotificationDuration}}">
{{else}}
<input type="number" name="desktopNotificationDuration" min="0" value="" placeholder="{{_ "Use_Global_Settings"}}">
<input type="number" name="desktopNotificationDuration" min="0" value="" placeholder="{{_ "Use_Global_Settings"}} ({{defaultDesktopNotificationDuration}})">
{{/if}}
</div>
</div>
<div class="input-line double-col" id="desktopNotifications">
<label>{{_ "Notification_Desktop_Default_For"}}</label>
<div>
<select class="input-monitor" name="desktopNotifications">
<option value="default" selected="{{selected 'desktopNotifications' 'default' true}}">{{_ "Default"}} ({{_ defaultDesktopNotification}})</option>
<option value="all" selected="{{selected 'desktopNotifications' 'all' false}}">{{_ "All_messages"}}</option>
<option value="mentions" selected="{{selected 'desktopNotifications' 'mentions' false}}">{{_ "Mentions"}}</option>
<option value="nothing" selected="{{selected 'desktopNotifications' 'nothing' false}}">{{_ "Nothing"}}</option>
</select>
</div>
</div>
<div class="input-line double-col" id="mobileNotifications">
<label>{{_ "Notification_Mobile_Default_For"}}</label>
<div>
<select class="input-monitor" name="mobileNotifications">
<option value="default" selected="{{selected 'mobileNotifications' 'default' true}}">{{_ "Default"}} ({{_ defaultMobileNotification}})</option>
<option value="all" selected="{{selected 'mobileNotifications' 'all' false}}">{{_ "All_messages"}}</option>
<option value="mentions" selected="{{selected 'mobileNotifications' 'mentions' false}}">{{_ "Mentions"}}</option>
<option value="nothing" selected="{{selected 'mobileNotifications' 'nothing' false}}">{{_ "Nothing"}}</option>
</select>
</div>
</div>
<div class="input-line double-col" id="unreadAlert">
<label>{{_ "Unread_Tray_Icon_Alert"}}</label>
<div>

@ -1,5 +1,12 @@
/*globals defaultUserLanguage, KonchatNotification */
import toastr from 'toastr';
const notificationLabels = {
all: 'All_messages',
mentions: 'Mentions',
nothing: 'Nothing'
};
Template.accountPreferences.helpers({
audioAssets() {
return (RocketChat.CustomSounds && RocketChat.CustomSounds.getList && RocketChat.CustomSounds.getList()) || [];
@ -66,6 +73,15 @@ Template.accountPreferences.helpers({
const user = Meteor.user();
return user && user.settings && user.settings.preferences && user.settings.preferences.desktopNotificationDuration;
},
defaultDesktopNotificationDuration() {
return RocketChat.settings.get('Desktop_Notifications_Duration');
},
defaultDesktopNotification() {
return notificationLabels[RocketChat.settings.get('Desktop_Notifications_Default_Alert')];
},
defaultMobileNotification() {
return notificationLabels[RocketChat.settings.get('Mobile_Notifications_Default_Alert')];
},
showRoles() {
return RocketChat.settings.get('UI_DisplayRoles');
},
@ -126,6 +142,8 @@ Template.accountPreferences.onCreated(function() {
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();
data.notificationsSoundVolume = parseInt($('#notificationsSoundVolume').val());

@ -59,6 +59,13 @@ Meteor.methods({
preferences.notificationsSoundVolume = settings.notificationsSoundVolume;
}
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';

Loading…
Cancel
Save