diff --git a/public/language/en_GB/notifications.json b/public/language/en_GB/notifications.json index f9b569170d..3048f082b9 100644 --- a/public/language/en_GB/notifications.json +++ b/public/language/en_GB/notifications.json @@ -17,6 +17,8 @@ "moved_your_post": "%1 has moved your post to %2", "moved_your_topic": "%1 has moved %2", "favourited_your_post_in": "%1 has favourited your post in %2.", + "favourited_your_post_in_dual": "%1 and %2 have favourited your post in %3.", + "favourited_your_post_in_multiple": "%1 and %2 others have favourited your post in %3.", "user_flagged_post_in": "%1 flagged a post in %2", "user_posted_to" : "%1 has posted a reply to: %2", "user_posted_topic": "%1 has posted a new topic: %2", diff --git a/src/notifications.js b/src/notifications.js index 2cd372923e..ec77cb4a99 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -331,5 +331,50 @@ var async = require('async'), }); }; + Notifications.merge = function(notifications, callback) { + // When passed a set of notification objects, merge any that can be merged + var mergeIds = ['notifications:favourited_your_post_in'], + isolated, modifyIndex; + + notifications = mergeIds.reduce(function(notifications, mergeId) { + isolated = notifications.filter(function(notifObj) { + return notifObj.mergeId === mergeId; + }); + + if (isolated.length <= 1) { + return notifications; // Nothing to merge + } + + modifyIndex = notifications.indexOf(isolated[0]); + + switch(mergeId) { + case 'notifications:favourited_your_post_in': + var usernames = isolated.map(function(notifObj) { + return notifObj.user.username; + }); + var numUsers = usernames.length; + + // Update bodyShort + if (numUsers === 2) { + isolated[0].bodyShort = '[[notifications:favourited_your_post_in_dual, ' + usernames.join(', ') + ', Welcome to your NodeBB!]]' + } else { + isolated[0].bodyShort = '[[notifications:favourited_your_post_in_multiple, ' + usernames[0] + ', ' + (numUsers-1) + ', Welcome to your NodeBB!]]' + } + break; + } + + // Filter out duplicates + return notifications.filter(function(notifObj, idx) { + return notifObj.mergeId !== mergeId || idx === modifyIndex; + }); + }, notifications); + + plugins.fireHook('filter:notifications.merge', { + notifications: notifications + }, function(err, data) { + callback(err, data.notifications); + }); + }; + }(exports)); diff --git a/src/socket.io/helpers.js b/src/socket.io/helpers.js index 5b6a2a2e67..19e46871b3 100644 --- a/src/socket.io/helpers.js +++ b/src/socket.io/helpers.js @@ -69,7 +69,8 @@ SocketHelpers.sendNotificationToPostOwner = function(pid, fromuid, notification) bodyLong: results.postObj.content, pid: pid, nid: 'post:' + pid + ':uid:' + fromuid, - from: fromuid + from: fromuid, + mergeId: notification }, function(err, notification) { if (!err && notification) { notifications.push(notification, [postData.uid]); diff --git a/src/user/notifications.js b/src/user/notifications.js index 477a9cf53f..5a30149eef 100644 --- a/src/user/notifications.js +++ b/src/user/notifications.js @@ -64,28 +64,21 @@ var async = require('async'), } function getNotificationsFromSet(set, read, uid, start, stop, callback) { - db.getSortedSetRevRange(set, start, stop, function(err, nids) { - if (err) { - return callback(err); - } - - if(!Array.isArray(nids) || !nids.length) { - return callback(null, []); - } - - UserNotifications.getNotifications(nids, uid, function(err, notifications) { - if (err) { - return callback(err); + async.waterfall([ + async.apply(db.getSortedSetRevRange, set, start, stop), + function(nids, next) { + if(!Array.isArray(nids) || !nids.length) { + return callback(null, []); } + UserNotifications.getNotifications(nids, uid, next); + }, + function(notifs, next) { var deletedNids = []; - notifications.forEach(function(notification, index) { + notifs.forEach(function(notification, index) { if (!notification) { - if (process.env.NODE_ENV === 'development') { - winston.info('[notifications.get] nid ' + nids[index] + ' not found. Removing.'); - } - + winston.verbose('[notifications.get] nid ' + nids[index] + ' not found. Removing.'); deletedNids.push(nids[index]); } else { notification.read = read; @@ -97,9 +90,9 @@ var async = require('async'), db.sortedSetRemove(set, deletedNids); } - callback(null, notifications); - }); - }); + notifications.merge(notifs, next); + } + ], callback); } UserNotifications.getNotifications = function(nids, uid, callback) {