diff options
-rw-r--r-- | client/components/notifications/notificationsDrawer.jade | 4 | ||||
-rw-r--r-- | client/components/notifications/notificationsDrawer.js | 15 | ||||
-rw-r--r-- | client/components/notifications/notificationsDrawer.styl | 13 | ||||
-rw-r--r-- | i18n/en.i18n.json | 1 | ||||
-rw-r--r-- | models/activities.js | 5 | ||||
-rw-r--r-- | models/users.js | 36 |
6 files changed, 72 insertions, 2 deletions
diff --git a/client/components/notifications/notificationsDrawer.jade b/client/components/notifications/notificationsDrawer.jade index 01117009..fee6aef6 100644 --- a/client/components/notifications/notificationsDrawer.jade +++ b/client/components/notifications/notificationsDrawer.jade @@ -14,3 +14,7 @@ template(name='notificationsDrawer') +notification(activityData=activity index=dbIndex read=read) if($gt unreadNotifications 0) a.all-read {{_ 'mark-all-as-read'}} + if ($and ($.Session.get 'showReadNotifications') ($gt readNotifications 0)) + a.remove-read + i.fa.fa-trash + | {{_ 'remove-all-read'}} diff --git a/client/components/notifications/notificationsDrawer.js b/client/components/notifications/notificationsDrawer.js index 98d4750d..76abeea7 100644 --- a/client/components/notifications/notificationsDrawer.js +++ b/client/components/notifications/notificationsDrawer.js @@ -16,6 +16,13 @@ Template.notificationsDrawer.helpers({ transformedProfile() { return Users.findOne(Meteor.userId()); }, + readNotifications() { + const readNotifications = _.filter( + Meteor.user().profile.notifications, + v => !!v.read, + ); + return readNotifications.length; + }, }); Template.notificationsDrawer.events({ @@ -35,4 +42,12 @@ Template.notificationsDrawer.events({ 'click .toggle-read'() { Session.set('showReadNotifications', !Session.get('showReadNotifications')); }, + 'click .remove-read'() { + const user = Meteor.user(); + for (const notification of user.profile.notifications) { + if (notification.read) { + user.removeNotification(notification.activity); + } + } + }, }); diff --git a/client/components/notifications/notificationsDrawer.styl b/client/components/notifications/notificationsDrawer.styl index a26b5e4a..b64f13f4 100644 --- a/client/components/notifications/notificationsDrawer.styl +++ b/client/components/notifications/notificationsDrawer.styl @@ -45,12 +45,23 @@ section#notifications-drawer line-height: 24px opacity 1 - .all-read + .all-read, + .remove-read color belize background-color: #fafafa margin 8px 16px 12px display inline-block + .remove-read + float right + + &:hover + color #eb4646 !important + + i.fa + color inherit + + ul.notifications display: block padding: 0px 16px diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 68e30193..0b194042 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -774,6 +774,7 @@ "view-all": "View All", "filter-by-unread": "Filter by Unread", "mark-all-as-read": "Mark all as read", + "remove-all-read": "Remove all read", "allow-rename": "Allow Rename", "allowRenamePopup-title": "Allow Rename" } diff --git a/models/activities.js b/models/activities.js index 568859a9..b5fcb7d8 100644 --- a/models/activities.js +++ b/models/activities.js @@ -282,7 +282,10 @@ if (Meteor.isServer) { ); } Notifications.getUsers(watchers).forEach(user => { - Notifications.notify(user, title, description, params); + // don't notify a user of their own behavior + if (user._id !== userId) { + Notifications.notify(user, title, description, params); + } }); const integrations = Integrations.find({ diff --git a/models/users.js b/models/users.js index 20581e65..9b2a5465 100644 --- a/models/users.js +++ b/models/users.js @@ -1,3 +1,5 @@ +import { SyncedCron } from 'meteor/percolate:synced-cron'; + // Sandstorm context is detected using the METEOR_SETTINGS environment variable // in the package definition. const isSandstorm = @@ -926,6 +928,37 @@ if (Meteor.isServer) { }); } +const addCronJob = _.debounce( + Meteor.bindEnvironment(function notificationCleanupDebounced() { + // passed in the removeAge has to be a number standing for the number of days after a notification is read before we remove it + const envRemoveAge = process.env.NOTIFICATION_REMOVAL_AGE; + // default notifications will be removed 2 days after they are read + const defaultRemoveAge = 2; + const removeAge = parseInt(envRemoveAge, 10) || defaultRemoveAge; + + SyncedCron.add({ + name: 'notification_cleanup', + schedule: parser => parser.text('every 1 days'), + job: () => { + for (const user of Users.find()) { + for (const notification of user.profile.notifications) { + if (notification.read) { + const removeDate = new Date(notification.read); + removeDate.setDate(removeDate.getDate() + removeAge); + if (removeDate <= new Date()) { + user.removeNotification(notification.activity); + } + } + } + } + }, + }); + + SyncedCron.start(); + }), + 500, +); + if (Meteor.isServer) { // Let mongoDB ensure username unicity Meteor.startup(() => { @@ -939,6 +972,9 @@ if (Meteor.isServer) { }, { unique: true }, ); + Meteor.defer(() => { + addCronJob(); + }); }); // OLD WAY THIS CODE DID WORK: When user is last admin of board, |