diff --git a/src/controllers/topics.js b/src/controllers/topics.js index 15452aaf80..879bd65cd3 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -20,17 +20,17 @@ topicsController.get = function(req, res, next) { async.waterfall([ function(next) { - threadTools.privileges(tid, ((req.user) ? req.user.uid || 0 : 0), function(err, userPrivileges) { - if (!err) { - if (!userPrivileges.read) { - next(new Error('not-enough-privileges')); - } else { - privileges = userPrivileges; - next(); - } - } else { - next(err); + threadTools.privileges(tid, uid, function(err, userPrivileges) { + if (err) { + return next(err); } + + if (!userPrivileges.read) { + return next(new Error('not-enough-privileges')); + } + + privileges = userPrivileges; + next(); }); }, function (next) { @@ -45,7 +45,7 @@ topicsController.get = function(req, res, next) { topics.getTopicWithPosts(tid, uid, start, end, function (err, topicData) { if (topicData) { if (parseInt(topicData.deleted, 10) === 1 && parseInt(topicData.expose_tools, 10) === 0) { - return next(new Error('Topic deleted'), null); + return next(new Error('Topic deleted')); } topicData.currentPage = page; } @@ -55,19 +55,18 @@ topicsController.get = function(req, res, next) { }, function (topicData, next) { var lastMod = topicData.timestamp, - description = (function() { - var content = ''; - if(topicData.posts.length) { - content = S(topicData.posts[0].content).stripTags().s; - } + timestamp, + description = ''; - if (content.length > 255) { - content = content.substr(0, 255) + '...'; - } + if(topicData.posts.length) { + description = S(topicData.posts[0].content).stripTags().s; + } + + if (description.length > 255) { + description = description.substr(0, 255) + '...'; + } - return validator.escape(content); - })(), - timestamp; + description = validator.escape(description); for (var x = 0, numPosts = topicData.posts.length; x < numPosts; x++) { timestamp = parseInt(topicData.posts[x].timestamp, 10); diff --git a/src/topics.js b/src/topics.js index 58399d7344..c665a77dfe 100644 --- a/src/topics.js +++ b/src/topics.js @@ -26,6 +26,8 @@ var async = require('async'), (function(Topics) { + require('./topics/unread')(Topics); + Topics.create = function(data, callback) { var uid = data.uid, title = data.title, @@ -559,134 +561,6 @@ var async = require('async'), }); }; - Topics.getTotalUnread = function(uid, callback) { - Topics.getUnreadTids(uid, 0, 20, function(err, tids) { - callback(err, tids ? tids.length : 0); - }); - }; - - Topics.getUnreadTids = function(uid, start, stop, callback) { - var unreadTids = [], - done = false; - - uid = parseInt(uid, 10); - if(uid === 0) { - return callback(null, unreadTids); - } - - async.whilst(function() { - return unreadTids.length < 21 && !done; - }, function(callback) { - Topics.getLatestTids(start, stop, 'month', function(err, tids) { - if (err) { - return callback(err); - } - - if (tids && !tids.length) { - done = true; - return callback(); - } - - Topics.hasReadTopics(tids, uid, function(err, read) { - if(err) { - return callback(err); - } - var newtids = tids.filter(function(tid, index, self) { - return parseInt(read[index], 10) === 0; - }); - - async.filter(newtids, function(tid, next) { - threadTools.privileges(tid, uid, function(err, privileges) { - next(!err && privileges.read); - }); - }, function(newtids) { - unreadTids.push.apply(unreadTids, newtids); - - start = stop + 1; - stop = start + 19; - - callback(); - }); - }); - }); - }, function(err) { - callback(err, unreadTids); - }); - }; - - Topics.getUnreadTopics = function(uid, start, stop, callback) { - - var unreadTopics = { - no_topics_message: '', - show_markallread_button: 'hidden', - nextStart : 0, - topics: [] - }; - - function sendUnreadTopics(topicIds) { - - Topics.getTopicsByTids(topicIds, uid, function(err, topicData) { - if(err) { - return callback(err); - } - - db.sortedSetRevRank('topics:recent', topicData[topicData.length - 1].tid, function(err, rank) { - if(err) { - return callback(err); - } - - unreadTopics.topics = topicData; - unreadTopics.nextStart = parseInt(rank, 10) + 1; - unreadTopics.no_topics_message = (!topicData || topicData.length === 0) ? '' : 'hidden'; - unreadTopics.show_markallread_button = topicData.length === 0 ? 'hidden' : ''; - - callback(null, unreadTopics); - }); - }); - } - - Topics.getUnreadTids(uid, start, stop, function(err, unreadTids) { - if (err) { - return callback(err); - } - - if (unreadTids.length) { - sendUnreadTopics(unreadTids); - } else { - callback(null, unreadTopics); - } - }); - }; - - Topics.pushUnreadCount = function(uids, callback) { - var websockets = require('./socket.io'); - - if (!uids) { - uids = websockets.getConnectedClients(); - } else if (!Array.isArray(uids)) { - uids = [uids]; - } - - uids = uids.filter(function(value) { - return parseInt(value, 10) !== 0; - }); - - async.each(uids, function(uid, next) { - Topics.getTotalUnread(uid, function(err, count) { - websockets.in('uid_' + uid).emit('event:unread.updateCount', null, count); - next(); - }); - }, function(err) { - if (err) { - winston.error(err.message); - } - - if (callback) { - callback(); - } - }); - }; - Topics.getTopicsByTids = function(tids, uid, callback) { if (!Array.isArray(tids) || tids.length === 0) { return callback(null, []); @@ -854,77 +728,6 @@ var async = require('async'), }); }; - Topics.markAsUnreadForAll = function(tid, callback) { - db.delete('tid:' + tid + ':read_by_uid', function(err) { - if(err) { - return callback(err); - } - Topics.markCategoryUnreadForAll(tid, callback); - }); - }; - - Topics.markAllRead = function(uid, tids, callback) { - if(!tids || !tids.length) { - return callback(); - } - - async.each(tids, function (tid, next) { - Topics.markAsRead(tid, uid, next); - }, callback); - }; - - Topics.markAsRead = function(tid, uid, callback) { - - db.setAdd('tid:' + tid + ':read_by_uid', uid, function(err) { - if(callback) { - callback(err); - } - }); - - Topics.getTopicField(tid, 'cid', function(err, cid) { - categories.markAsRead(cid, uid); - }); - - user.notifications.getUnreadByUniqueId(uid, 'topic:' + tid, function(err, nids) { - notifications.mark_read_multiple(nids, uid, function() { - user.notifications.pushCount(uid); - }); - }); - }; - - Topics.markCategoryUnreadForAll = function(tid, callback) { - Topics.getTopicField(tid, 'cid', function(err, cid) { - if(err) { - return callback(err); - } - - categories.markAsUnreadForAll(cid, callback); - }); - }; - - Topics.hasReadTopics = function(tids, uid, callback) { - if(!parseInt(uid, 10)) { - return callback(null, tids.map(function() { - return false; - })); - } - - var sets = []; - - for (var i = 0, ii = tids.length; i < ii; i++) { - sets.push('tid:' + tids[i] + ':read_by_uid'); - } - - db.isMemberOfSets(sets, uid, callback); - }; - - Topics.hasReadTopic = function(tid, uid, callback) { - if(!parseInt(uid, 10)) { - return callback(null, false); - } - - db.isSetMember('tid:' + tid + ':read_by_uid', uid, callback); - }; Topics.getTeasers = function(tids, callback) { diff --git a/src/topics/unread.js b/src/topics/unread.js new file mode 100644 index 0000000000..58f8168040 --- /dev/null +++ b/src/topics/unread.js @@ -0,0 +1,216 @@ + +'use strict'; + +var async = require('async'), + winston = require('winston'), + + db = require('./../database'), + user = require('./../user'), + notifications = require('./../notifications'), + categories = require('./../categories'), + threadTools = require('./../threadTools'); + +module.exports = function(Topics) { + + Topics.getTotalUnread = function(uid, callback) { + Topics.getUnreadTids(uid, 0, 20, function(err, tids) { + callback(err, tids ? tids.length : 0); + }); + }; + + Topics.getUnreadTids = function(uid, start, stop, callback) { + var unreadTids = [], + done = false; + + uid = parseInt(uid, 10); + if(uid === 0) { + return callback(null, unreadTids); + } + + async.whilst(function() { + return unreadTids.length < 21 && !done; + }, function(callback) { + Topics.getLatestTids(start, stop, 'month', function(err, tids) { + if (err) { + return callback(err); + } + + if (tids && !tids.length) { + done = true; + return callback(); + } + + Topics.hasReadTopics(tids, uid, function(err, read) { + if(err) { + return callback(err); + } + var newtids = tids.filter(function(tid, index, self) { + return parseInt(read[index], 10) === 0; + }); + + async.filter(newtids, function(tid, next) { + threadTools.privileges(tid, uid, function(err, privileges) { + next(!err && privileges.read); + }); + }, function(newtids) { + unreadTids.push.apply(unreadTids, newtids); + + start = stop + 1; + stop = start + 19; + + callback(); + }); + }); + }); + }, function(err) { + callback(err, unreadTids); + }); + }; + + Topics.getUnreadTopics = function(uid, start, stop, callback) { + + var unreadTopics = { + no_topics_message: '', + show_markallread_button: 'hidden', + nextStart : 0, + topics: [] + }; + + function sendUnreadTopics(topicIds) { + + Topics.getTopicsByTids(topicIds, uid, function(err, topicData) { + if(err) { + return callback(err); + } + + db.sortedSetRevRank('topics:recent', topicData[topicData.length - 1].tid, function(err, rank) { + if(err) { + return callback(err); + } + + unreadTopics.topics = topicData; + unreadTopics.nextStart = parseInt(rank, 10) + 1; + unreadTopics.no_topics_message = (!topicData || topicData.length === 0) ? '' : 'hidden'; + unreadTopics.show_markallread_button = topicData.length === 0 ? 'hidden' : ''; + + callback(null, unreadTopics); + }); + }); + } + + Topics.getUnreadTids(uid, start, stop, function(err, unreadTids) { + if (err) { + return callback(err); + } + + if (unreadTids.length) { + sendUnreadTopics(unreadTids); + } else { + callback(null, unreadTopics); + } + }); + }; + + Topics.pushUnreadCount = function(uids, callback) { + var websockets = require('./../socket.io'); + + if (!uids) { + uids = websockets.getConnectedClients(); + } else if (!Array.isArray(uids)) { + uids = [uids]; + } + + uids = uids.filter(function(value) { + return parseInt(value, 10) !== 0; + }); + + async.each(uids, function(uid, next) { + Topics.getTotalUnread(uid, function(err, count) { + websockets.in('uid_' + uid).emit('event:unread.updateCount', null, count); + next(); + }); + }, function(err) { + if (err) { + winston.error(err.message); + } + + if (callback) { + callback(); + } + }); + }; + + Topics.markAsUnreadForAll = function(tid, callback) { + db.delete('tid:' + tid + ':read_by_uid', function(err) { + if(err) { + return callback(err); + } + Topics.markCategoryUnreadForAll(tid, callback); + }); + }; + + Topics.markAllRead = function(uid, tids, callback) { + if(!tids || !tids.length) { + return callback(); + } + + async.each(tids, function (tid, next) { + Topics.markAsRead(tid, uid, next); + }, callback); + }; + + Topics.markAsRead = function(tid, uid, callback) { + + db.setAdd('tid:' + tid + ':read_by_uid', uid, function(err) { + if(callback) { + callback(err); + } + }); + + Topics.getTopicField(tid, 'cid', function(err, cid) { + categories.markAsRead(cid, uid); + }); + + user.notifications.getUnreadByUniqueId(uid, 'topic:' + tid, function(err, nids) { + notifications.mark_read_multiple(nids, uid, function() { + user.notifications.pushCount(uid); + }); + }); + }; + + Topics.markCategoryUnreadForAll = function(tid, callback) { + Topics.getTopicField(tid, 'cid', function(err, cid) { + if(err) { + return callback(err); + } + + categories.markAsUnreadForAll(cid, callback); + }); + }; + + Topics.hasReadTopics = function(tids, uid, callback) { + if(!parseInt(uid, 10)) { + return callback(null, tids.map(function() { + return false; + })); + } + + var sets = []; + + for (var i = 0, ii = tids.length; i < ii; i++) { + sets.push('tid:' + tids[i] + ':read_by_uid'); + } + + db.isMemberOfSets(sets, uid, callback); + }; + + Topics.hasReadTopic = function(tid, uid, callback) { + if(!parseInt(uid, 10)) { + return callback(null, false); + } + + db.isSetMember('tid:' + tid + ':read_by_uid', uid, callback); + }; + + +}; \ No newline at end of file