mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 11:35:55 +01:00
notification changes
-only send a notification when the person you follow creates a topic -you still get a notification per post if you are following a topic -changed notifications.push so that it sends the notifications over a period of time, currently to 50 users per second -optimized topics.notifyFollowers and user.notifications.sendTopicNotification, they no longer query the database for the topic and post data instead they get it as params -you can no longer follow yourself :) -changed mongo sortedSetRemove so that it doesn't use $in if there is only a single value to remove
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
"favourited_your_post_in": "<strong>%1</strong> has favourited your post in <strong>%2</strong>.",
|
||||
"user_flagged_post_in": "<strong>%1</strong> flagged a post in <strong>%2</strong>",
|
||||
"user_posted_to" : "<strong>%1</strong> has posted a reply to: <strong>%2</strong>",
|
||||
"user_posted_topic": "<strong>%1</strong> has posted a new topic: <strong>%2</strong>",
|
||||
"user_mentioned_you_in": "<strong>%1</strong> mentioned you in <strong>%2</strong>",
|
||||
"user_started_following_you": "<strong>%1</strong> started following you.",
|
||||
|
||||
|
||||
@@ -61,18 +61,21 @@ module.exports = function(db, module) {
|
||||
};
|
||||
|
||||
module.sortedSetRemove = function(key, value, callback) {
|
||||
function done(err) {
|
||||
callback(err);
|
||||
}
|
||||
callback = callback || helpers.noop;
|
||||
if (!key) {
|
||||
return callback();
|
||||
}
|
||||
if (!Array.isArray(value)) {
|
||||
value = [value];
|
||||
}
|
||||
value = value.map(helpers.valueToString);
|
||||
|
||||
db.collection('objects').remove({_key: key, value: {$in: value}}, function(err) {
|
||||
callback(err);
|
||||
});
|
||||
if (Array.isArray(value)) {
|
||||
value = value.map(helpers.valueToString);
|
||||
db.collection('objects').remove({_key: key, value: {$in: value}}, done);
|
||||
} else {
|
||||
value = helpers.valueToString(value);
|
||||
db.collection('objects').remove({_key: key, value: value}, done);
|
||||
}
|
||||
};
|
||||
|
||||
module.sortedSetsRemove = function(keys, value, callback) {
|
||||
|
||||
@@ -128,17 +128,58 @@ var async = require('async'),
|
||||
return callback();
|
||||
}
|
||||
|
||||
var websockets = require('./socket.io');
|
||||
if (!Array.isArray(uids)) {
|
||||
uids = [uids];
|
||||
}
|
||||
|
||||
uids = uids.filter(function(uid) {
|
||||
return parseInt(uid, 10);
|
||||
});
|
||||
|
||||
if (!uids.length) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
var done = false;
|
||||
var start = 0;
|
||||
var batchSize = 50;
|
||||
|
||||
setTimeout(function() {
|
||||
async.whilst(
|
||||
function() {
|
||||
return !done;
|
||||
},
|
||||
function(next) {
|
||||
var currentUids = uids.slice(start, start + batchSize);
|
||||
if (!currentUids.length) {
|
||||
done = true;
|
||||
return next();
|
||||
}
|
||||
pushToUids(currentUids, notification, function(err) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
start = start + batchSize;
|
||||
|
||||
setTimeout(next, 1000);
|
||||
});
|
||||
},
|
||||
function(err) {
|
||||
if (err) {
|
||||
winston.error(err.stack);
|
||||
}
|
||||
}
|
||||
);
|
||||
}, 1000);
|
||||
|
||||
callback();
|
||||
};
|
||||
|
||||
function pushToUids(uids, notification, callback) {
|
||||
var unreadKeys = [];
|
||||
var readKeys = [];
|
||||
|
||||
uids.filter(function(uid) {
|
||||
return parseInt(uid, 10);
|
||||
}).forEach(function(uid) {
|
||||
uids.forEach(function(uid) {
|
||||
unreadKeys.push('uid:' + uid + ':notifications:unread');
|
||||
readKeys.push('uid:' + uid + ':notifications:read');
|
||||
});
|
||||
@@ -163,13 +204,15 @@ var async = require('async'),
|
||||
}
|
||||
|
||||
plugins.fireHook('action:notification.pushed', {notification: notification, uids: uids});
|
||||
callback();
|
||||
|
||||
var websockets = require('./socket.io');
|
||||
for(var i=0; i<uids.length; ++i) {
|
||||
websockets.in('uid_' + uids[i]).emit('event:new_notification', notification);
|
||||
}
|
||||
|
||||
callback();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
Notifications.pushGroup = function(notification, groupName, callback) {
|
||||
callback = callback || function() {};
|
||||
|
||||
@@ -161,6 +161,10 @@ module.exports = function(Topics) {
|
||||
|
||||
plugins.fireHook('action:topic.post', data.topicData);
|
||||
|
||||
if (parseInt(uid, 10)) {
|
||||
user.notifications.sendTopicNotificationToFollowers(uid, data.topicData, data.postData);
|
||||
}
|
||||
|
||||
next(null, {
|
||||
topicData: data.topicData,
|
||||
postData: data.postData
|
||||
@@ -262,9 +266,7 @@ module.exports = function(Topics) {
|
||||
postData.relativeTime = utils.toISOString(postData.timestamp);
|
||||
|
||||
if (parseInt(uid, 10)) {
|
||||
Topics.notifyFollowers(tid, postData.pid, uid);
|
||||
|
||||
user.notifications.sendPostNotificationToFollowers(uid, tid, postData.pid);
|
||||
Topics.notifyFollowers(postData.topic, postData, uid);
|
||||
}
|
||||
|
||||
next(null, postData);
|
||||
|
||||
@@ -21,8 +21,8 @@ module.exports = function(Topics) {
|
||||
db.getSetMembers('tid:' + tid + ':followers', callback);
|
||||
};
|
||||
|
||||
Topics.notifyFollowers = function(tid, pid, exceptUid) {
|
||||
Topics.getFollowers(tid, function(err, followers) {
|
||||
Topics.notifyFollowers = function(topicData, postData, exceptUid) {
|
||||
Topics.getFollowers(topicData.tid, function(err, followers) {
|
||||
if (err || !Array.isArray(followers) || !followers.length) {
|
||||
return;
|
||||
}
|
||||
@@ -36,28 +36,12 @@ module.exports = function(Topics) {
|
||||
return;
|
||||
}
|
||||
|
||||
async.parallel({
|
||||
title: async.apply(Topics.getTopicField, tid, 'title'),
|
||||
username: async.apply(user.getUserField, exceptUid, 'username'),
|
||||
postContent: function(next) {
|
||||
async.waterfall([
|
||||
async.apply(posts.getPostField, pid, 'content'),
|
||||
function(content, next) {
|
||||
postTools.parse(content, next);
|
||||
}
|
||||
], next);
|
||||
}
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
notifications.create({
|
||||
bodyShort: '[[notifications:user_posted_to, ' + results.username + ', ' + results.title + ']]',
|
||||
bodyLong: results.postContent,
|
||||
pid: pid,
|
||||
nid: 'tid:' + tid + ':pid:' + pid + ':uid:' + exceptUid,
|
||||
tid: tid,
|
||||
bodyShort: '[[notifications:user_posted_to, ' + postData.user.username + ', ' + topicData.title + ']]',
|
||||
bodyLong: postData.content,
|
||||
pid: postData.pid,
|
||||
nid: 'tid:' + topicData.tid + ':pid:' + postData.pid + ':uid:' + exceptUid,
|
||||
tid: topicData.tid,
|
||||
from: exceptUid
|
||||
}, function(err, notification) {
|
||||
if (!err && notification) {
|
||||
@@ -65,6 +49,5 @@ module.exports = function(Topics) {
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -15,6 +15,14 @@ module.exports = function(User) {
|
||||
};
|
||||
|
||||
function toggleFollow(type, uid, theiruid, callback) {
|
||||
if (!parseInt(uid, 10) || !parseInt(theiruid, 10)) {
|
||||
return callback(new Error('[[error:invalid-uid]]'));
|
||||
}
|
||||
|
||||
if (parseInt(uid, 10) === parseInt(theiruid, 10)) {
|
||||
return callback(new Error('[[error:you-cant-follow-yourself]]'));
|
||||
}
|
||||
|
||||
var command = type === 'follow' ? 'setAdd' : 'setRemove';
|
||||
db[command]('following:' + uid, theiruid, function(err) {
|
||||
if(err) {
|
||||
|
||||
@@ -247,50 +247,23 @@ var async = require('async'),
|
||||
};
|
||||
|
||||
|
||||
UserNotifications.sendPostNotificationToFollowers = function(uid, tid, pid) {
|
||||
UserNotifications.sendTopicNotificationToFollowers = function(uid, topicData, postData) {
|
||||
db.getSetMembers('followers:' + uid, function(err, followers) {
|
||||
if (err || !Array.isArray(followers) || !followers.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
async.parallel({
|
||||
username: async.apply(user.getUserField, uid, 'username'),
|
||||
topic: async.apply(topics.getTopicFields, tid, ['cid', 'title']),
|
||||
postContent: function(next) {
|
||||
async.waterfall([
|
||||
async.apply(posts.getPostField, pid, 'content'),
|
||||
function(content, next) {
|
||||
postTools.parse(content, next);
|
||||
}
|
||||
], next);
|
||||
},
|
||||
topicFollowers: function(next) {
|
||||
db.isSetMembers('tid:' + tid + ':followers', followers, next);
|
||||
}
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
return;
|
||||
}
|
||||
|
||||
followers = followers.filter(function(value, index) {
|
||||
return !results.topicFollowers[index];
|
||||
});
|
||||
|
||||
if (!followers.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
privileges.categories.filterUids('read', results.topic.cid, followers, function(err, followers) {
|
||||
privileges.categories.filterUids('read', topicData.cid, followers, function(err, followers) {
|
||||
if (err || !followers.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
notifications.create({
|
||||
bodyShort: '[[notifications:user_posted_to, ' + results.username + ', ' + results.topic.title + ']]',
|
||||
bodyLong: results.postContent,
|
||||
pid: pid,
|
||||
nid: 'tid:' + tid + ':pid:' + pid + ':uid:' + uid,
|
||||
tid: tid,
|
||||
bodyShort: '[[notifications:user_posted_topic, ' + postData.user.username + ', ' + topicData.title + ']]',
|
||||
bodyLong: postData.content,
|
||||
pid: postData.pid,
|
||||
nid: 'tid:' + postData.tid + ':pid:' + postData.pid + ':uid:' + uid,
|
||||
tid: postData.tid,
|
||||
from: uid
|
||||
}, function(err, notification) {
|
||||
if (!err && notification) {
|
||||
@@ -299,7 +272,6 @@ var async = require('async'),
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
UserNotifications.sendWelcomeNotification = function(uid) {
|
||||
|
||||
Reference in New Issue
Block a user