Jelajahi Sumber

Improve PR, adding more comments

floatinghotpot 9 tahun lalu
induk
melakukan
39e1cc0237
3 mengubah file dengan 32 tambahan dan 26 penghapusan
  1. 10 10
      models/activities.js
  2. 7 7
      models/users.js
  3. 15 9
      server/notifications/email.js

+ 10 - 10
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) => {

+ 7 - 7
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': [],
       },
     };
   },

+ 15 - 9
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);
   });
 });