mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-12-24 01:10:31 +01:00
part 1 of notif refactor
This commit is contained in:
@@ -71,6 +71,11 @@ define('notifications', ['sounds'], function(sound) {
|
|||||||
Tinycon.setBubble(count);
|
Tinycon.setBubble(count);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function increaseNotifCount() {
|
||||||
|
var count = parseInt(notifIcon.attr('data-content'), 10) + 1;
|
||||||
|
updateNotifCount(count);
|
||||||
|
}
|
||||||
|
|
||||||
socket.emit('notifications.getCount', function(err, count) {
|
socket.emit('notifications.getCount', function(err, count) {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
updateNotifCount(count);
|
updateNotifCount(count);
|
||||||
@@ -79,7 +84,7 @@ define('notifications', ['sounds'], function(sound) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('event:new_notification', function(notifData, notifCount) {
|
socket.on('event:new_notification', function(notifData) {
|
||||||
app.alert({
|
app.alert({
|
||||||
alert_id: 'new_notif',
|
alert_id: 'new_notif',
|
||||||
title: '[[notifications:new_notification]]',
|
title: '[[notifications:new_notification]]',
|
||||||
@@ -93,10 +98,11 @@ define('notifications', ['sounds'], function(sound) {
|
|||||||
ajaxify.refresh();
|
ajaxify.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateNotifCount(notifCount);
|
increaseNotifCount();
|
||||||
|
|
||||||
sound.play('notification');
|
sound.play('notification');
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('event:notifications.updateCount', function(count) {
|
socket.on('event:notifications.updateCount', function(count) {
|
||||||
updateNotifCount(count);
|
updateNotifCount(count);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -480,7 +480,10 @@ accountsController.uploadPicture = function (req, res, next) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
accountsController.getNotifications = function(req, res, next) {
|
accountsController.getNotifications = function(req, res, next) {
|
||||||
user.notifications.getAll(req.user.uid, 25, function(err, notifications) {
|
user.notifications.getAll(req.user.uid, 40, function(err, notifications) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
res.render('notifications', {
|
res.render('notifications', {
|
||||||
notifications: notifications
|
notifications: notifications
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ module.exports = function(db, module) {
|
|||||||
var helpers = module.helpers.level;
|
var helpers = module.helpers.level;
|
||||||
|
|
||||||
module.sortedSetAdd = function(key, score, value, callback) {
|
module.sortedSetAdd = function(key, score, value, callback) {
|
||||||
|
if (Array.isArray(score) && Array.isArray(value)) {
|
||||||
|
return sortedSetAddMulti(key, score, value, callback);
|
||||||
|
}
|
||||||
module.getListRange(key, 0, -1, function(err, set) {
|
module.getListRange(key, 0, -1, function(err, set) {
|
||||||
set = set.filter(function(a) {return a.value !== value.toString();});
|
set = set.filter(function(a) {return a.value !== value.toString();});
|
||||||
|
|
||||||
@@ -20,6 +23,10 @@ module.exports = function(db, module) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function sortedSetAddMulti(key, scores, values, callback) {
|
||||||
|
throw new Error('not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
module.sortedSetsAdd = function(keys, score, value, callback) {
|
module.sortedSetsAdd = function(keys, score, value, callback) {
|
||||||
async.each(keys, function(key, next) {
|
async.each(keys, function(key, next) {
|
||||||
module.sortedSetAdd(key, score, value, next);
|
module.sortedSetAdd(key, score, value, next);
|
||||||
@@ -29,8 +36,11 @@ module.exports = function(db, module) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.sortedSetRemove = function(key, value, callback) {
|
module.sortedSetRemove = function(key, value, callback) {
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
value = [value];
|
||||||
|
}
|
||||||
module.getListRange(key, 0, -1, function(err, set) {
|
module.getListRange(key, 0, -1, function(err, set) {
|
||||||
set = set.filter(function(a) {return a.value !== value.toString();});
|
set = set.filter(function(a) { return value.indexOf(a) === -1;});
|
||||||
module.set(key, set, callback);
|
module.set(key, set, callback);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ module.exports = function(db, module) {
|
|||||||
|
|
||||||
module.sortedSetAdd = function(key, score, value, callback) {
|
module.sortedSetAdd = function(key, score, value, callback) {
|
||||||
callback = callback || helpers.noop;
|
callback = callback || helpers.noop;
|
||||||
|
if (Array.isArray(score) && Array.isArray(value)) {
|
||||||
|
return sortedSetAddBulk(key, score, value, callback);
|
||||||
|
}
|
||||||
|
|
||||||
value = helpers.valueToString(value);
|
value = helpers.valueToString(value);
|
||||||
var data = {
|
var data = {
|
||||||
score: parseInt(score, 10),
|
score: parseInt(score, 10),
|
||||||
@@ -18,6 +22,24 @@ module.exports = function(db, module) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function sortedSetAddBulk(key, scores, values, callback) {
|
||||||
|
if (scores.length !== values.length) {
|
||||||
|
return callback(new Error('[[error:invalid-data]]'));
|
||||||
|
}
|
||||||
|
|
||||||
|
values = values.map(helpers.valueToString);
|
||||||
|
|
||||||
|
var bulk = db.collection('objects').initializeUnorderedBulkOp();
|
||||||
|
|
||||||
|
for(var i=0; i<scores.length; ++i) {
|
||||||
|
bulk.find({_key: key, value: values[i]}).upsert().updateOne({$set: {score: scores[i], value: values[i]}});
|
||||||
|
}
|
||||||
|
|
||||||
|
bulk.execute(function(err, result) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.sortedSetsAdd = function(keys, score, value, callback) {
|
module.sortedSetsAdd = function(keys, score, value, callback) {
|
||||||
callback = callback || helpers.noop;
|
callback = callback || helpers.noop;
|
||||||
|
|
||||||
@@ -40,9 +62,12 @@ module.exports = function(db, module) {
|
|||||||
|
|
||||||
module.sortedSetRemove = function(key, value, callback) {
|
module.sortedSetRemove = function(key, value, callback) {
|
||||||
callback = callback || helpers.noop;
|
callback = callback || helpers.noop;
|
||||||
value = helpers.valueToString(value);
|
if (!Array.isArray(value)) {
|
||||||
|
value = [value];
|
||||||
|
}
|
||||||
|
value = value.map(helpers.valueToString);
|
||||||
|
|
||||||
db.collection('objects').remove({_key: key, value: value}, function(err) {
|
db.collection('objects').remove({_key: key, value: {$in: value}}, function(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,11 +3,27 @@
|
|||||||
module.exports = function(redisClient, module) {
|
module.exports = function(redisClient, module) {
|
||||||
module.sortedSetAdd = function(key, score, value, callback) {
|
module.sortedSetAdd = function(key, score, value, callback) {
|
||||||
callback = callback || function() {};
|
callback = callback || function() {};
|
||||||
|
if (Array.isArray(score) && Array.isArray(value)) {
|
||||||
|
return sortedSetAddMulti(key, score, value, callback);
|
||||||
|
}
|
||||||
redisClient.zadd(key, score, value, function(err) {
|
redisClient.zadd(key, score, value, function(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function sortedSetAddMulti(key, scores, values, callback) {
|
||||||
|
if (scores.length !== values.length) {
|
||||||
|
return callback(new Error('[[error:invalid-data]]'));
|
||||||
|
}
|
||||||
|
var multi = redisClient.multi();
|
||||||
|
for(var i=0; i<scores.lenth; ++i) {
|
||||||
|
multi.zadd(key, scores[i], values[i]);
|
||||||
|
}
|
||||||
|
multi.exec(function(err, result) {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.sortedSetsAdd = function(keys, score, value, callback) {
|
module.sortedSetsAdd = function(keys, score, value, callback) {
|
||||||
callback = callback || function() {};
|
callback = callback || function() {};
|
||||||
var multi = redisClient.multi();
|
var multi = redisClient.multi();
|
||||||
@@ -23,7 +39,14 @@ module.exports = function(redisClient, module) {
|
|||||||
|
|
||||||
module.sortedSetRemove = function(key, value, callback) {
|
module.sortedSetRemove = function(key, value, callback) {
|
||||||
callback = callback || function() {};
|
callback = callback || function() {};
|
||||||
redisClient.zrem(key, value, function(err) {
|
if (!Array.isArray(value)) {
|
||||||
|
value = [value];
|
||||||
|
}
|
||||||
|
var multi = redisClient.multi();
|
||||||
|
for(var i=0; i<value.length; ++i) {
|
||||||
|
multi.zrem(key, value[i]);
|
||||||
|
}
|
||||||
|
multi.exec(function(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -102,8 +102,7 @@ var db = require('./database'),
|
|||||||
getMessages(mids, fromuid, touid, isNew, callback);
|
getMessages(mids, fromuid, touid, isNew, callback);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mark any chat notifications pertaining to this chat as read
|
notifications.markRead('chat_' + touid + '_' + fromuid, fromuid, function(err) {
|
||||||
notifications.markReadByUniqueId(fromuid, 'chat_' + touid + '_' + fromuid, function(err) {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
winston.error('[messaging] Could not mark notifications related to this chat as read: ' + err.message);
|
winston.error('[messaging] Could not mark notifications related to this chat as read: ' + err.message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,8 +53,12 @@ var async = require('async'),
|
|||||||
notification.text = S(notification.text).escapeHTML().s;
|
notification.text = S(notification.text).escapeHTML().s;
|
||||||
}
|
}
|
||||||
|
|
||||||
notification.bodyShort = S(notification.bodyShort).escapeHTML().s;
|
if (notification.bodyShort) {
|
||||||
notification.bodyLong = S(notification.bodyLong).escapeHTML().s;
|
notification.bodyShort = S(notification.bodyShort).escapeHTML().s;
|
||||||
|
}
|
||||||
|
if (notification.bodyLong) {
|
||||||
|
notification.bodyLong = S(notification.bodyLong).escapeHTML().s;
|
||||||
|
}
|
||||||
|
|
||||||
if (notification.from && !notification.image) {
|
if (notification.from && !notification.image) {
|
||||||
User.getUserField(notification.from, 'picture', function(err, picture) {
|
User.getUserField(notification.from, 'picture', function(err, picture) {
|
||||||
@@ -80,203 +84,134 @@ var async = require('async'),
|
|||||||
};
|
};
|
||||||
|
|
||||||
Notifications.create = function(data, callback) {
|
Notifications.create = function(data, callback) {
|
||||||
// Add default values to data Object if not already set
|
if (!data.nid) {
|
||||||
var defaults = {
|
return callback(new Error('no-notification-id'));
|
||||||
bodyShort: '',
|
|
||||||
bodyLong: '',
|
|
||||||
importance: 5,
|
|
||||||
datetime: Date.now(),
|
|
||||||
uniqueId: utils.generateUUID()
|
|
||||||
};
|
|
||||||
|
|
||||||
for(var v in defaults) {
|
|
||||||
if (defaults.hasOwnProperty(v) && !data[v]) {
|
|
||||||
data[v] = defaults[v];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
data.importance = data.importance || 5;
|
||||||
// Backwards compatibility for old notification schema
|
db.getObject('notifications:' + data.nid, function(err, oldNotification) {
|
||||||
// Remove this block for NodeBB v0.6.0
|
|
||||||
if (data.hasOwnProperty('text')) {
|
|
||||||
data.bodyShort = data.text;
|
|
||||||
data.bodyLong = '';
|
|
||||||
delete data.text;
|
|
||||||
}
|
|
||||||
|
|
||||||
db.incrObjectField('global', 'nextNid', function(err, nid) {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
data.nid = nid;
|
if (oldNotification) {
|
||||||
db.setAdd('notifications', nid);
|
if (parseInt(oldNotification.pid, 10) === parseInt(data.pid, 10) && parseInt(oldNotification.importance, 10) > parseInt(data.importance, 10)) {
|
||||||
db.setObject('notifications:' + nid, data, function(err) {
|
return callback(null, null);
|
||||||
callback(err, nid);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var now = Date.now();
|
||||||
|
data.datetime = now;
|
||||||
|
async.parallel([
|
||||||
|
function(next) {
|
||||||
|
db.sortedSetAdd('notifications', now, data.nid, next);
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
db.setObject('notifications:' + data.nid, data, next);
|
||||||
|
}
|
||||||
|
], function(err) {
|
||||||
|
callback(err, data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Notifications.push = function(nid, uids, callback) {
|
Notifications.push = function(notification, uids, callback) {
|
||||||
callback = callback || function() {};
|
callback = callback || function() {};
|
||||||
var websockets = require('./socket.io');
|
var websockets = require('./socket.io');
|
||||||
if (!Array.isArray(uids)) {
|
if (!Array.isArray(uids)) {
|
||||||
uids = [uids];
|
uids = [uids];
|
||||||
}
|
}
|
||||||
|
|
||||||
Notifications.get(nid, function(err, notif_data) {
|
var unreadKeys = [];
|
||||||
|
var readKeys = [];
|
||||||
|
|
||||||
|
uids.filter(Boolean).forEach(function(uid) {
|
||||||
|
unreadKeys.push('uid:' + uid + ':notifications:unread');
|
||||||
|
readKeys.push('uid:' + uid + ':notifications:read');
|
||||||
|
});
|
||||||
|
|
||||||
|
async.parallel([
|
||||||
|
function(next) {
|
||||||
|
db.sortedSetsAdd(unreadKeys, notification.datetime, notification.nid, next);
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
db.sortedSetsRemove(readKeys, notification.nid, next);
|
||||||
|
}
|
||||||
|
], function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
async.eachLimit(uids, 10, function(uid, next) {
|
plugins.fireHook('action:notification.pushed', {notification: notification, uids: uids});
|
||||||
if (!parseInt(uid, 10)) {
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldPush(uid, notif_data, function(err, shouldPush) {
|
for(var i=0; i<uids.length; ++i) {
|
||||||
if (err || !shouldPush) {
|
websockets.in('uid_' + uids[i]).emit('event:new_notification', notification);
|
||||||
return callback(err);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async.parallel([
|
|
||||||
async.apply(db.setObjectField, 'uid:' + uid + ':notifications:uniqueId:nid', notif_data.uniqueId, nid),
|
|
||||||
async.apply(db.sortedSetAdd, 'uid:' + uid + ':notifications:unread', notif_data.datetime, notif_data.uniqueId),
|
|
||||||
async.apply(db.sortedSetRemove, 'uid:' + uid + ':notifications:read', notif_data.uniqueId)
|
|
||||||
], function(err) {
|
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
User.notifications.getUnreadCount(uid, function(err, count) {
|
|
||||||
if (!err) {
|
|
||||||
websockets.in('uid_' + uid).emit('event:new_notification', notif_data, count);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Plugins
|
|
||||||
notif_data.uid = uid;
|
|
||||||
plugins.fireHook('action:notification.pushed', notif_data);
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}, callback);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function shouldPush(uid, newNotifObj, callback) {
|
Notifications.pushGroup = function(notification, groupName, callback) {
|
||||||
if (!newNotifObj) {
|
|
||||||
return callback(null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
hasNotification(newNotifObj.uniqueId, uid, function(err, hasNotification) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasNotification) {
|
|
||||||
return callback(null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
db.getObjectField('uid:' + uid + ':notifications:uniqueId:nid', newNotifObj.uniqueId, function(err, nid) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
db.getObjectFields('notifications:' + nid, ['nid', 'uniqueId', 'importance'], function(err, oldNotifObj) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!oldNotifObj || newNotifObj.uniqueId !== oldNotifObj.uniqueId) {
|
|
||||||
return callback(null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(null, parseInt(newNotifObj.importance, 10) >= parseInt(oldNotifObj.importance, 10));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasNotification(uniqueId, uid, callback) {
|
|
||||||
async.parallel([
|
|
||||||
async.apply(db.isSortedSetMember, 'uid:' + uid + ':notifications:unread', uniqueId),
|
|
||||||
async.apply(db.isSortedSetMember, 'uid:' + uid + ':notifications:read', uniqueId)
|
|
||||||
], function(err, results) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(null, results[0] || results[1]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Notifications.pushGroup = function(nid, groupName, callback) {
|
|
||||||
callback = callback || function() {};
|
callback = callback || function() {};
|
||||||
groups.get(groupName, {}, function(err, groupObj) {
|
groups.get(groupName, {}, function(err, groupObj) {
|
||||||
if (err || !groupObj || !Array.isArray(groupObj.members) || !groupObj.members.length) {
|
if (err || !groupObj || !Array.isArray(groupObj.members) || !groupObj.members.length) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
Notifications.push(nid, groupObj.members, callback);
|
Notifications.push(notification, groupObj.members, callback);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Notifications.markRead = function(nid, uid, callback) {
|
Notifications.markRead = function(nid, uid, callback) {
|
||||||
callback = callback || function() {};
|
callback = callback || function() {};
|
||||||
if (!parseInt(uid, 10) || !parseInt(nid, 10)) {
|
if (!parseInt(uid, 10) || !parseInt(nid, 10)) {
|
||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
|
Notifications.markReadMultiple([nid], uid, callback);
|
||||||
db.getObjectFields('notifications:' + nid, ['uniqueId', 'datetime'], function(err, notificationData) {
|
|
||||||
if (err || !notificationData) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
async.parallel([
|
|
||||||
async.apply(db.sortedSetRemove, 'uid:' + uid + ':notifications:unread', notificationData.uniqueId),
|
|
||||||
async.apply(db.sortedSetAdd, 'uid:' + uid + ':notifications:read', notificationData.datetime, notificationData.uniqueId)
|
|
||||||
], callback);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Notifications.markReadMultiple = function(nids, uid, callback) {
|
Notifications.markReadMultiple = function(nids, uid, callback) {
|
||||||
callback = callback || function() {};
|
callback = callback || function() {};
|
||||||
if (!nids) {
|
if (!Array.isArray(nids) || !nids.length) {
|
||||||
return callback(null);
|
return callback();
|
||||||
}
|
|
||||||
if (!Array.isArray(nids) && parseInt(nids, 10) > 0) {
|
|
||||||
nids = [nids];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async.each(nids, function(nid, next) {
|
var notificationKeys = nids.map(function(nid) {
|
||||||
Notifications.markRead(nid, uid, next);
|
return 'notifications:' + nid;
|
||||||
}, callback);
|
});
|
||||||
|
|
||||||
|
db.getObjectsFields(notificationKeys, ['datetime'], function(err, notificationData) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
var datetimes = notificationData.map(function(notification) {
|
||||||
|
return notification && notification.datetime;
|
||||||
|
});
|
||||||
|
|
||||||
|
async.parallel([
|
||||||
|
function(next) {
|
||||||
|
db.sortedSetRemove('uid:' + uid + ':notifications:unread', nids, next);
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
db.sortedSetAdd('uid:' + uid + ':notifications:read', datetimes, nids, next);
|
||||||
|
}
|
||||||
|
], callback);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Notifications.markAllRead = function(uid, callback) {
|
Notifications.markAllRead = function(uid, callback) {
|
||||||
db.getObjectValues('uid:' + uid + ':notifications:uniqueId:nid', function(err, nids) {
|
db.getSortedSetRange('uid:' + uid + ':notifications:unread', 0, 99, function(err, nids) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Array.isArray(nids) || !nids.length) {
|
if (!Array.isArray(nids) || !nids.length) {
|
||||||
return callback(err);
|
return callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
Notifications.markReadMultiple(nids, uid, callback);
|
Notifications.markReadMultiple(nids, uid, callback);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Notifications.markReadByUniqueId = function(uid, uniqueId, callback) {
|
|
||||||
async.waterfall([
|
|
||||||
async.apply(db.getObjectField, 'uid:' + uid + ':notifications:uniqueId:nid', uniqueId),
|
|
||||||
function(nid, next) {
|
|
||||||
Notifications.markRead(nid, uid, next);
|
|
||||||
}
|
|
||||||
], callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
Notifications.prune = function() {
|
Notifications.prune = function() {
|
||||||
var start = process.hrtime();
|
var start = process.hrtime();
|
||||||
|
|
||||||
@@ -289,12 +224,14 @@ var async = require('async'),
|
|||||||
|
|
||||||
var cutoffTime = Date.now() - week;
|
var cutoffTime = Date.now() - week;
|
||||||
|
|
||||||
db.getSetMembers('notifications', function(err, nids) {
|
db.getSortedSetRange('notifications', 0, 499, function(err, nids) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return winston.error(err.message);
|
return winston.error(err.message);
|
||||||
}
|
}
|
||||||
|
if (!Array.isArray(nids) || !nids.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
var totalNidCount = nids.length;
|
var totalNidCount = nids.length;
|
||||||
nids = _.sortBy(nids, function(num) { return parseInt(num, 10); }).slice(0, 500);
|
|
||||||
|
|
||||||
var keys = nids.map(function(nid) {
|
var keys = nids.map(function(nid) {
|
||||||
return 'notifications:' + nid;
|
return 'notifications:' + nid;
|
||||||
@@ -319,7 +256,7 @@ var async = require('async'),
|
|||||||
|
|
||||||
async.parallel([
|
async.parallel([
|
||||||
function(next) {
|
function(next) {
|
||||||
db.setRemove('notifications', expiredNids, next);
|
db.sortedSetRemove('notifications', expiredNids, next);
|
||||||
},
|
},
|
||||||
function(next) {
|
function(next) {
|
||||||
db.deleteAll(keys, next);
|
db.deleteAll(keys, next);
|
||||||
|
|||||||
@@ -224,11 +224,11 @@ function sendChatNotification(fromuid, touid, messageObj) {
|
|||||||
bodyShort: '[[notifications:new_message_from, ' + messageObj.fromUser.username + ']]',
|
bodyShort: '[[notifications:new_message_from, ' + messageObj.fromUser.username + ']]',
|
||||||
bodyLong: messageObj.content,
|
bodyLong: messageObj.content,
|
||||||
path: nconf.get('relative_path') + '/chats/' + utils.slugify(messageObj.fromUser.username),
|
path: nconf.get('relative_path') + '/chats/' + utils.slugify(messageObj.fromUser.username),
|
||||||
uniqueId: 'chat_' + fromuid + '_' + touid,
|
nid: 'chat_' + fromuid + '_' + touid,
|
||||||
from: fromuid
|
from: fromuid
|
||||||
}, function(err, nid) {
|
}, function(err, notification) {
|
||||||
if (!err) {
|
if (!err && notification) {
|
||||||
notifications.push(nid, [touid]);
|
notifications.push(notification, [touid]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,11 +135,11 @@ SocketPosts.sendNotificationToPostOwner = function(pid, fromuid, notification) {
|
|||||||
bodyShort: '[[' + notification + ', ' + results.username + ']]',
|
bodyShort: '[[' + notification + ', ' + results.username + ']]',
|
||||||
bodyLong: results.postContent,
|
bodyLong: results.postContent,
|
||||||
pid: pid,
|
pid: pid,
|
||||||
uniqueId: 'post:' + pid + ':uid:' + fromuid,
|
nid: 'post:' + pid + ':uid:' + fromuid,
|
||||||
from: fromuid
|
from: fromuid
|
||||||
}, function(err, nid) {
|
}, function(err, notification) {
|
||||||
if (!err) {
|
if (!err && notification) {
|
||||||
notifications.push(nid, [postData.uid]);
|
notifications.push(notification, [postData.uid]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -310,13 +310,13 @@ SocketPosts.flag = function(socket, pid, callback) {
|
|||||||
bodyShort: message,
|
bodyShort: message,
|
||||||
bodyLong: post.content,
|
bodyLong: post.content,
|
||||||
pid: pid,
|
pid: pid,
|
||||||
uniqueId: 'post_flag:' + pid,
|
nid: 'post_flag:' + pid + ':uid:' + socket.uid,
|
||||||
from: socket.uid
|
from: socket.uid
|
||||||
}, function(err, nid) {
|
}, function(err, notification) {
|
||||||
if (err) {
|
if (err || !notification) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
notifications.push(nid, adminGroup.members, next);
|
notifications.push(notification, adminGroup.members, next);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function(next) {
|
function(next) {
|
||||||
|
|||||||
@@ -353,11 +353,11 @@ SocketTopics.sendNotificationToTopicOwner = function(tid, fromuid, notification)
|
|||||||
notifications.create({
|
notifications.create({
|
||||||
bodyShort: '[[' + notification + ', ' + results.username + ']]',
|
bodyShort: '[[' + notification + ', ' + results.username + ']]',
|
||||||
path: nconf.get('relative_path') + '/topic/' + results.topicData.slug,
|
path: nconf.get('relative_path') + '/topic/' + results.topicData.slug,
|
||||||
uniqueId: 'topic:' + tid + ':uid:' + fromuid,
|
nid: 'topic:' + tid + ':uid:' + fromuid,
|
||||||
from: fromuid
|
from: fromuid
|
||||||
}, function(err, nid) {
|
}, function(err, notification) {
|
||||||
if (!err) {
|
if (!err && notification) {
|
||||||
notifications.push(nid, [results.topicData.uid]);
|
notifications.push(notification, [results.topicData.uid]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -181,31 +181,33 @@ SocketUser.changePicture = function(socket, data, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SocketUser.follow = function(socket, data, callback) {
|
SocketUser.follow = function(socket, data, callback) {
|
||||||
if (socket.uid && data) {
|
if (!socket.uid || !data) {
|
||||||
toggleFollow('follow', socket.uid, data.uid, function(err) {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleFollow('follow', socket.uid, data.uid, function(err) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
user.getUserFields(socket.uid, ['username', 'userslug'], function(err, userData) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
user.getUserFields(socket.uid, ['username', 'userslug'], function(err, userData) {
|
notifications.create({
|
||||||
if (err) {
|
bodyShort: '[[notifications:user_started_following_you, ' + userData.username + ']]',
|
||||||
return callback(err);
|
path: nconf.get('relative_path') + '/user/' + userData.userslug,
|
||||||
|
nid: 'follow:uid:' + socket.uid,
|
||||||
|
from: socket.uid
|
||||||
|
}, function(err, notification) {
|
||||||
|
if (!err && notification) {
|
||||||
|
notifications.push(notification, [data.uid]);
|
||||||
}
|
}
|
||||||
|
callback(err);
|
||||||
notifications.create({
|
|
||||||
bodyShort: '[[notifications:user_started_following_you, ' + userData.username + ']]',
|
|
||||||
path: nconf.get('relative_path') + '/user/' + userData.userslug,
|
|
||||||
uniqueId: 'follow:uid:' + socket.uid,
|
|
||||||
from: socket.uid
|
|
||||||
}, function(err, nid) {
|
|
||||||
if (!err) {
|
|
||||||
notifications.push(nid, [data.uid]);
|
|
||||||
}
|
|
||||||
callback(err);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
SocketUser.unfollow = function(socket, data, callback) {
|
SocketUser.unfollow = function(socket, data, callback) {
|
||||||
|
|||||||
@@ -56,12 +56,12 @@ module.exports = function(Topics) {
|
|||||||
bodyShort: '[[notifications:user_posted_to, ' + results.username + ', ' + results.title + ']]',
|
bodyShort: '[[notifications:user_posted_to, ' + results.username + ', ' + results.title + ']]',
|
||||||
bodyLong: results.postContent,
|
bodyLong: results.postContent,
|
||||||
pid: pid,
|
pid: pid,
|
||||||
uniqueId: 'topic:' + tid + ':uid:' + exceptUid,
|
nid: 'topic:' + tid + ':uid:' + exceptUid,
|
||||||
tid: tid,
|
tid: tid,
|
||||||
from: exceptUid
|
from: exceptUid
|
||||||
}, function(err, nid) {
|
}, function(err, notification) {
|
||||||
if (!err) {
|
if (!err && notification) {
|
||||||
notifications.push(nid, followers);
|
notifications.push(notification, followers);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -234,6 +234,9 @@ module.exports = function(Topics) {
|
|||||||
|
|
||||||
Topics.markTopicNotificationsRead = function(tid, uid) {
|
Topics.markTopicNotificationsRead = function(tid, uid) {
|
||||||
user.notifications.getUnreadByField(uid, 'tid', tid, function(err, nids) {
|
user.notifications.getUnreadByField(uid, 'tid', tid, function(err, nids) {
|
||||||
|
if (err) {
|
||||||
|
return winston.error(err.stack);
|
||||||
|
}
|
||||||
notifications.markReadMultiple(nids, uid, function() {
|
notifications.markReadMultiple(nids, uid, function() {
|
||||||
user.notifications.pushCount(uid);
|
user.notifications.pushCount(uid);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ var db = require('./database'),
|
|||||||
schemaDate, thisSchemaDate,
|
schemaDate, thisSchemaDate,
|
||||||
|
|
||||||
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
|
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
|
||||||
latestSchema = Date.UTC(2014, 6, 24);
|
latestSchema = Date.UTC(2014, 8, 8);
|
||||||
|
|
||||||
Upgrade.check = function(callback) {
|
Upgrade.check = function(callback) {
|
||||||
db.get('schemaDate', function(err, value) {
|
db.get('schemaDate', function(err, value) {
|
||||||
@@ -963,6 +963,56 @@ Upgrade.upgrade = function(callback) {
|
|||||||
winston.info('[2014/7/24] Upgrading chats to sorted set - skipped');
|
winston.info('[2014/7/24] Upgrading chats to sorted set - skipped');
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
thisSchemaDate = Date.UTC(2014, 8, 8);
|
||||||
|
|
||||||
|
if (schemaDate < thisSchemaDate) {
|
||||||
|
winston.info('[2014/9/8] Deleting old notifications...');
|
||||||
|
|
||||||
|
async.parallel({
|
||||||
|
uids: function(next) {
|
||||||
|
db.getSortedSetRange('users:joindate', 0, -1, next);
|
||||||
|
},
|
||||||
|
nids: function(next) {
|
||||||
|
db.getSetMembers('notifications', next);
|
||||||
|
}
|
||||||
|
}, function(err, results) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
var uidKeys = results.uids.map(function(uid) {
|
||||||
|
return 'uid:' + uid + ':notifications:uniqueId:nid';
|
||||||
|
});
|
||||||
|
|
||||||
|
var nidKeys = results.nids.filter(Boolean).map(function(nid) {
|
||||||
|
return 'notifications:' + nid;
|
||||||
|
});
|
||||||
|
|
||||||
|
async.series([
|
||||||
|
function(next) {
|
||||||
|
db.deleteAll(nidKeys, next);
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
db.deleteAll(uidKeys, next);
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
db.delete('notifications', next);
|
||||||
|
}
|
||||||
|
], function(err, results) {
|
||||||
|
if (err) {
|
||||||
|
winston.error('[2014/9/8] Error encountered while deleting notifications');
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
winston.info('[2014/9/8] Deleted old notifications');
|
||||||
|
Upgrade.update(thisSchemaDate, next);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
winston.info('[2014/9/8] Deleting old notifications skipped');
|
||||||
|
next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Add new schema updates here
|
// Add new schema updates here
|
||||||
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 22!!!
|
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 22!!!
|
||||||
|
|||||||
@@ -165,10 +165,11 @@ module.exports = function(User) {
|
|||||||
bodyShort: '[[user:username_taken_workaround, ' + userData.username + ']]',
|
bodyShort: '[[user:username_taken_workaround, ' + userData.username + ']]',
|
||||||
bodyLong: '',
|
bodyLong: '',
|
||||||
image: 'brand:logo',
|
image: 'brand:logo',
|
||||||
|
nid: 'username_taken:' + uid,
|
||||||
datetime: Date.now()
|
datetime: Date.now()
|
||||||
}, function(err, nid) {
|
}, function(err, notification) {
|
||||||
if (!err) {
|
if (!err && notification) {
|
||||||
notifications.push(nid, uid);
|
notifications.push(notification, uid);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,9 +65,6 @@ module.exports = function(User) {
|
|||||||
function(next) {
|
function(next) {
|
||||||
db.delete('uid:' + uid + ':notifications:unread', next);
|
db.delete('uid:' + uid + ':notifications:unread', next);
|
||||||
},
|
},
|
||||||
function(next) {
|
|
||||||
db.delete('uid:' + uid + ':notifications:uniqueId:nid', next);
|
|
||||||
},
|
|
||||||
function(next) {
|
function(next) {
|
||||||
db.sortedSetRemove('users:joindate', uid, next);
|
db.sortedSetRemove('users:joindate', uid, next);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -45,63 +45,61 @@ var async = require('async'),
|
|||||||
};
|
};
|
||||||
|
|
||||||
function getNotificationsFromSet(set, uid, start, stop, max, callback) {
|
function getNotificationsFromSet(set, uid, start, stop, max, callback) {
|
||||||
db.getSortedSetRevRange(set, start, stop, function(err, uniqueIds) {
|
db.getSortedSetRevRange(set, start, stop, function(err, nids) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Array.isArray(uniqueIds) || !uniqueIds.length) {
|
if(!Array.isArray(nids) || !nids.length) {
|
||||||
return callback(null, []);
|
return callback(null, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uniqueIds.length > max) {
|
if (nids.length > max) {
|
||||||
uniqueIds.length = max;
|
nids.length = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
db.getObjectFields('uid:' + uid + ':notifications:uniqueId:nid', uniqueIds, function(err, uniqueIdToNids) {
|
UserNotifications.getNotifications(nids, uid, function(err, notifications) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
var nidsToUniqueIds = {};
|
var deletedNids = [];
|
||||||
var nids = [];
|
|
||||||
uniqueIds.forEach(function(uniqueId) {
|
|
||||||
nidsToUniqueIds[uniqueIdToNids[uniqueId]] = uniqueId;
|
|
||||||
nids.push(uniqueIdToNids[uniqueId]);
|
|
||||||
});
|
|
||||||
|
|
||||||
UserNotifications.getNotifications(nids, uid, function(err, notifications) {
|
notifications.forEach(function(notification, index) {
|
||||||
if (err) {
|
if (!notification) {
|
||||||
return callback(err);
|
if (process.env.NODE_ENV === 'development') {
|
||||||
}
|
winston.info('[notifications.get] nid ' + nids[index] + ' not found. Removing.');
|
||||||
|
|
||||||
notifications.forEach(function(notification, index) {
|
|
||||||
if (!notification) {
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
|
||||||
winston.info('[notifications.get] nid ' + nids[index] + ' not found. Removing.');
|
|
||||||
}
|
|
||||||
|
|
||||||
db.sortedSetRemove(set, nidsToUniqueIds[nids[index]]);
|
|
||||||
db.deleteObjectField('uid:' + uid + ':notifications:uniqueId:nid', nidsToUniqueIds[nids[index]]);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
callback(null, notifications);
|
if (nids[index]) {
|
||||||
|
deletedNids.push(nids[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (deletedNids.length) {
|
||||||
|
db.sortedSetRemove(set, deletedNids);
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null, notifications);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
UserNotifications.getAll = function(uid, limit, callback) {
|
UserNotifications.getAll = function(uid, count, callback) {
|
||||||
if (!limit || parseInt(limit, 10) <= 0) {
|
async.parallel({
|
||||||
limit = 25;
|
unread: function(next) {
|
||||||
}
|
db.getSortedSetRevRange('uid:' + uid + ':notifications:unread', 0, count, next);
|
||||||
|
},
|
||||||
db.getObjectValues('uid:' + uid + ':notifications:uniqueId:nid', function(err, nids) {
|
read: function(next) {
|
||||||
|
db.getSortedSetRevRange('uid:' + uid + ':notifications:read', 0, count, next);
|
||||||
|
}
|
||||||
|
}, function(err, results) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var nids = results.unread.concat(results.read);
|
||||||
UserNotifications.getNotifications(nids, uid, function(err, notifs) {
|
UserNotifications.getNotifications(nids, uid, function(err, notifs) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
@@ -122,11 +120,7 @@ var async = require('async'),
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
var uniqueIds = notifications.map(function(notification) {
|
db.isSortedSetMembers('uid:' + uid + ':notifications:read', nids, function(err, hasRead) {
|
||||||
return notification ? notification.uniqueId : null;
|
|
||||||
});
|
|
||||||
|
|
||||||
db.isSortedSetMembers('uid:' + uid + ':notifications:read', uniqueIds, function(err, hasRead) {
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
@@ -159,7 +153,8 @@ var async = require('async'),
|
|||||||
};
|
};
|
||||||
|
|
||||||
function generatePostPaths(pids, uid, callback) {
|
function generatePostPaths(pids, uid, callback) {
|
||||||
var postKeys = pids.filter(Boolean).map(function(pid) {
|
pids = pids.filter(Boolean);
|
||||||
|
var postKeys = pids.map(function(pid) {
|
||||||
return 'post:' + pid;
|
return 'post:' + pid;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -193,6 +188,7 @@ var async = require('async'),
|
|||||||
pidToPaths[pid] = nconf.get('relative_path') + '/topic/' + slug + '/' + postIndex;
|
pidToPaths[pid] = nconf.get('relative_path') + '/topic/' + slug + '/' + postIndex;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
callback(null, pidToPaths);
|
callback(null, pidToPaths);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -202,26 +198,16 @@ var async = require('async'),
|
|||||||
var now = Date.now(),
|
var now = Date.now(),
|
||||||
yesterday = now - (1000*60*60*24); // Approximate, can be more or less depending on time changes, makes no difference really.
|
yesterday = now - (1000*60*60*24); // Approximate, can be more or less depending on time changes, makes no difference really.
|
||||||
|
|
||||||
db.getSortedSetRangeByScore('uid:' + uid + ':notifications:unread', 0, 20, yesterday, now, function(err, uniqueIds) {
|
db.getSortedSetRangeByScore('uid:' + uid + ':notifications:unread', 0, 20, yesterday, now, function(err, nids) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Array.isArray(uniqueIds) || !uniqueIds.length) {
|
if (!Array.isArray(nids) || !nids.length) {
|
||||||
return callback(null, []);
|
return callback(null, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
db.getObjectFields('uid:' + uid + ':notifications:uniqueId:nid', uniqueIds, function(err, uniqueIdToNids) {
|
UserNotifications.getNotifications(nids, uid, callback);
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
var nids = Object.keys(uniqueIdToNids).map(function(uniqueId) {
|
|
||||||
return uniqueIdToNids[uniqueId];
|
|
||||||
});
|
|
||||||
|
|
||||||
UserNotifications.getNotifications(nids, uid, callback);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -230,46 +216,35 @@ var async = require('async'),
|
|||||||
};
|
};
|
||||||
|
|
||||||
UserNotifications.getUnreadByField = function(uid, field, value, callback) {
|
UserNotifications.getUnreadByField = function(uid, field, value, callback) {
|
||||||
db.getSortedSetRange('uid:' + uid + ':notifications:unread', 0, -1, function(err, uniqueIds) {
|
db.getSortedSetRange('uid:' + uid + ':notifications:unread', 0, -1, function(err, nids) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Array.isArray(uniqueIds) || !uniqueIds.length) {
|
if (!Array.isArray(nids) || !nids.length) {
|
||||||
return callback(null, []);
|
return callback(null, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
db.getObjectFields('uid:' + uid + ':notifications:uniqueId:nid', uniqueIds, function(err, uniqueIdsToNids) {
|
UserNotifications.getNotifications(nids, uid, function(err, notifications) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
var nids = Object.keys(uniqueIdsToNids).map(function(uniqueId) {
|
nids = notifications.filter(function(notification) {
|
||||||
return uniqueIdsToNids[uniqueId];
|
return notification && notification[field] !== value.toString();
|
||||||
|
}).map(function(notification) {
|
||||||
|
return notification.nid;
|
||||||
});
|
});
|
||||||
|
|
||||||
UserNotifications.getNotifications(nids, uid, function(err, notifications) {
|
callback(null, nids);
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
notifications = notifications.filter(function(notification) {
|
|
||||||
return notification && notification[field] !== value.toString();
|
|
||||||
}).map(function(notification) {
|
|
||||||
return notification.nid;
|
|
||||||
});
|
|
||||||
|
|
||||||
callback(null, nids);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
UserNotifications.sendPostNotificationToFollowers = function(uid, tid, pid) {
|
UserNotifications.sendPostNotificationToFollowers = function(uid, tid, pid) {
|
||||||
return;
|
|
||||||
db.getSetMembers('followers:' + uid, function(err, followers) {
|
db.getSetMembers('followers:' + uid, function(err, followers) {
|
||||||
if (err || !followers || !followers.length) {
|
if (err || !Array.isArray(followers) || !followers.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,23 +271,30 @@ var async = require('async'),
|
|||||||
return !results.topicFollowers[index];
|
return !results.topicFollowers[index];
|
||||||
});
|
});
|
||||||
|
|
||||||
notifications.create({
|
if (!followers.length) {
|
||||||
bodyShort: '[[notifications:user_posted_to, ' + results.username + ', ' + results.topic.title + ']]',
|
return;
|
||||||
bodyLong: results.postContent,
|
}
|
||||||
pid: pid,
|
|
||||||
uniqueId: 'topic:' + tid + ':uid:' + uid,
|
async.filter(followers, function(uid, next) {
|
||||||
tid: tid,
|
privileges.categories.can('read', results.topic.cid, uid, function(err, canRead) {
|
||||||
from: uid
|
next(!err && canRead);
|
||||||
}, function(err, nid) {
|
});
|
||||||
if (err) {
|
}, function(followers) {
|
||||||
|
if (!followers.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
async.filter(followers, function(uid, next) {
|
|
||||||
privileges.categories.can('read', results.topic.cid, uid, function(err, canRead) {
|
notifications.create({
|
||||||
next(!err && canRead);
|
bodyShort: '[[notifications:user_posted_to, ' + results.username + ', ' + results.topic.title + ']]',
|
||||||
});
|
bodyLong: results.postContent,
|
||||||
}, function(followers){
|
pid: pid,
|
||||||
notifications.push(nid, followers);
|
nid: 'topic:' + tid + ':uid:' + uid,
|
||||||
|
tid: tid,
|
||||||
|
from: uid
|
||||||
|
}, function(err, notification) {
|
||||||
|
if (!err && notification) {
|
||||||
|
notifications.push(notification, followers);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user