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