From 39e1cc02374b3a379de87bdcb95a7a343b698a05 Mon Sep 17 00:00:00 2001 From: floatinghotpot Date: Wed, 6 Jan 2016 16:59:25 +0800 Subject: Improve PR, adding more comments --- models/activities.js | 20 ++++++++++---------- models/users.js | 14 +++++++------- server/notifications/email.js | 24 +++++++++++++++--------- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/models/activities.js b/models/activities.js index 0aa4fa54..ad920149 100644 --- a/models/activities.js +++ b/models/activities.js @@ -50,10 +50,10 @@ if (Meteor.isServer) { }); Activities.after.insert((userId, doc) => { - const activity = Activities.findOne(doc._id); + const activity = Activities._transform(doc); let participants = []; let watchers = []; - let title = 'Wekan Notification'; + let title = 'act-activity-notify'; let board = null; const description = `act-${activity.activityType}`; const params = { @@ -101,20 +101,20 @@ if (Meteor.isServer) { params.attachment = attachment._id; } if (board) { - const boardWatching = _.pluck(_.where(board.watchers, {level: 'watching'}), 'userId'); - const boardTracking = _.pluck(_.where(board.watchers, {level: 'tracking'}), 'userId'); - const boardMuted = _.pluck(_.where(board.watchers, {level: 'muted'}), 'userId'); + const watchingUsers = _.pluck(_.where(board.watchers, {level: 'watching'}), 'userId'); + const trackingUsers = _.pluck(_.where(board.watchers, {level: 'tracking'}), 'userId'); + const mutedUsers = _.pluck(_.where(board.watchers, {level: 'muted'}), 'userId'); switch(board.getWatchDefault()) { case 'muted': - participants = _.intersection(participants, boardTracking); - watchers = _.intersection(watchers, boardTracking); + participants = _.intersection(participants, trackingUsers); + watchers = _.intersection(watchers, trackingUsers); break; case 'tracking': - participants = _.difference(participants, boardMuted); - watchers = _.difference(watchers, boardMuted); + participants = _.difference(participants, mutedUsers); + watchers = _.difference(watchers, mutedUsers); break; } - watchers = _.union(watchers, boardWatching || []); + watchers = _.union(watchers, watchingUsers || []); } Notifications.getUsers(participants, watchers).forEach((user) => { diff --git a/models/users.js b/models/users.js index 3bb7324f..89220a11 100644 --- a/models/users.js +++ b/models/users.js @@ -57,9 +57,9 @@ Users.helpers({ return _.contains(notifications, activityId); }, - getEmailCache() { - const {emailCache = []} = this.profile; - return emailCache; + getEmailBuffer() { + const {emailBuffer = []} = this.profile; + return emailBuffer; }, getInitials() { @@ -153,18 +153,18 @@ Users.mutations({ }; }, - addEmailCache(text) { + addEmailBuffer(text) { return { $addToSet: { - 'profile.emailCache': text, + 'profile.emailBuffer': text, }, }; }, - clearEmailCache() { + clearEmailBuffer() { return { $set: { - 'profile.emailCache': [], + 'profile.emailBuffer': [], }, }; }, diff --git a/server/notifications/email.js b/server/notifications/email.js index 40968329..551d2923 100644 --- a/server/notifications/email.js +++ b/server/notifications/email.js @@ -1,6 +1,6 @@ -// cache the email text in a queue, and send them in a batch +// buffer each user's email text in a queue, then flush them in single email Meteor.startup(() => { - Notifications.subscribe('cachedEmail', (user, title, description, params) => { + Notifications.subscribe('email', (user, title, description, params) => { // add quote to make titles easier to read in email text const quoteParams = _.clone(params); ['card', 'list', 'oldList', 'board', 'comment'].forEach((key) => { @@ -8,28 +8,34 @@ Meteor.startup(() => { }); const text = `${params.user} ${TAPi18n.__(description, quoteParams, user.getLanguage())}\n${params.url}`; - user.addEmailCache(text); + user.addEmailBuffer(text); + // unlike setTimeout(func, delay, args), + // Meteor.setTimeout(func, delay) does not accept args :-( + // so we pass userId with closure const userId = user._id; Meteor.setTimeout(() => { const user = Users.findOne(userId); - const emailCache = user.getEmailCache(); - if (emailCache.length === 0) return; + // for each user, in the timed period, only the first call will get the cached content, + // other calls will get nothing + const texts = user.getEmailBuffer(); + if (texts.length === 0) return; - const text = emailCache.join('\n\n'); - user.clearEmailCache(); + // merge the cached content into single email and flush + const text = texts.join('\n\n'); + user.clearEmailBuffer(); try { Email.send({ to: user.emails[0].address, from: Accounts.emailTemplates.from, - subject : TAPi18n.__('act-activity-notify', {}, user.getLanguage()), + subject: TAPi18n.__('act-activity-notify', {}, user.getLanguage()), text, }); } catch (e) { return; } - }, 30000, user._id); + }, 30000); }); }); -- cgit v1.2.3-1-g7c22