From ec33a57f7773b60d8913c4ebe33306c2a52164fa Mon Sep 17 00:00:00 2001 From: barisusakli Date: Mon, 18 Apr 2016 15:44:07 +0300 Subject: [PATCH] closes #3128 --- public/language/en_GB/unread.json | 5 +- src/controllers/unread.js | 21 +++++- src/topics/unread.js | 117 ++++++++++++++++++------------ 3 files changed, 94 insertions(+), 49 deletions(-) diff --git a/public/language/en_GB/unread.json b/public/language/en_GB/unread.json index 0af9a2cdf648..4a449a53f5ab 100644 --- a/public/language/en_GB/unread.json +++ b/public/language/en_GB/unread.json @@ -6,5 +6,8 @@ "selected": "Selected", "all": "All", "all_categories": "All categories", - "topics_marked_as_read.success": "Topics marked as read!" + "topics_marked_as_read.success": "Topics marked as read!", + "all-topics": "All Topics", + "new-topics": "New Topics", + "watched-topics": "Watched Topics" } \ No newline at end of file diff --git a/src/controllers/unread.js b/src/controllers/unread.js index e7aacb2465c8..d3655fd050e6 100644 --- a/src/controllers/unread.js +++ b/src/controllers/unread.js @@ -5,14 +5,14 @@ var async = require('async'); var meta = require('../meta'); var categories = require('../categories'); var privileges = require('../privileges'); -var user = require('../user') +var user = require('../user'); var topics = require('../topics'); var helpers = require('./helpers'); var plugins = require('../plugins'); var unreadController = {}; -var validFilter = {'': true, 'new': true}; +var validFilter = {'': true, 'new': true, 'watched': true}; unreadController.get = function(req, res, next) { var stop = (parseInt(meta.config.topicsPerList, 10) || 20) - 1; @@ -57,6 +57,23 @@ unreadController.get = function(req, res, next) { results.unreadTopics.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[unread:title]]'}]); results.unreadTopics.title = '[[pages:unread]]'; + results.unreadTopics.filters = [{ + name: '[[unread:all-topics]]', + url: 'unread', + selected: filter === '' + }, { + name: '[[unread:new-topics]]', + url: 'unread/new', + selected: filter === 'new' + }, { + name: '[[unread:watched-topics]]', + url: 'unread/watched', + selected: filter === 'watched' + }]; + + results.unreadTopics.selectedFilter = results.unreadTopics.filters.filter(function(filter) { + return filter && filter.selected; + })[0]; plugins.fireHook('filter:unread.build', {req: req, res: res, templateData: results.unreadTopics}, next); } diff --git a/src/topics/unread.js b/src/topics/unread.js index 63941cd01a22..ac2e6d63a38a 100644 --- a/src/topics/unread.js +++ b/src/topics/unread.js @@ -31,7 +31,6 @@ module.exports = function(Topics) { filter = ''; } - var unreadTopics = { showSelect: true, nextStart : 0, @@ -77,57 +76,71 @@ module.exports = function(Topics) { var cutoff = Topics.unreadCutoff(); - async.parallel({ - ignoredCids: function(next) { - user.getIgnoredCategories(uid, next); - }, - recentTids: function(next) { - db.getSortedSetRevRangeByScoreWithScores('topics:recent', 0, -1, '+inf', cutoff, next); - }, - userScores: function(next) { - db.getSortedSetRevRangeByScoreWithScores('uid:' + uid + ':tids_read', 0, -1, '+inf', cutoff, next); + var ignoredCids; + + async.waterfall([ + function (next) { + async.parallel({ + ignoredCids: function(next) { + if (filter === 'watched') { + return next(null, []); + } + user.getIgnoredCategories(uid, next); + }, + recentTids: function(next) { + db.getSortedSetRevRangeByScoreWithScores('topics:recent', 0, -1, '+inf', cutoff, next); + }, + userScores: function(next) { + db.getSortedSetRevRangeByScoreWithScores('uid:' + uid + ':tids_read', 0, -1, '+inf', cutoff, next); + }, + tids_unread: function(next) { + db.getSortedSetRevRangeWithScores('uid:' + uid + ':tids_unread', 0, -1, next); + } + }, next); }, - tids_unread: function(next) { - db.getSortedSetRevRangeWithScores('uid:' + uid + ':tids_unread', 0, -1, next); - } - }, function(err, results) { - if (err) { - return callback(err); - } + function (results, next) { + if (results.recentTids && !results.recentTids.length && !results.tids_unread.length) { + return callback(null, []); + } - if (results.recentTids && !results.recentTids.length && !results.tids_unread.length) { - return callback(null, []); - } + ignoredCids = results.ignoredCids; - var userRead = {}; - results.userScores.forEach(function(userItem) { - userRead[userItem.value] = userItem.score; - }); + var userRead = {}; + results.userScores.forEach(function(userItem) { + userRead[userItem.value] = userItem.score; + }); - results.recentTids = results.recentTids.concat(results.tids_unread); - results.recentTids.sort(function(a, b) { - return b.score - a.score; - }); + results.recentTids = results.recentTids.concat(results.tids_unread); + results.recentTids.sort(function(a, b) { + return b.score - a.score; + }); + + var tids = results.recentTids.filter(function(recentTopic) { + switch (filter) { + case 'new': + return !userRead[recentTopic.value]; + default: + return !userRead[recentTopic.value] || recentTopic.score > userRead[recentTopic.value]; + } + }).map(function(topic) { + return topic.value; + }).filter(function(tid, index, array) { + return array.indexOf(tid) === index; + }); - var tids = results.recentTids.filter(function(recentTopic) { - switch (filter) { - default: - return !userRead[recentTopic.value] || recentTopic.score > userRead[recentTopic.value]; - case 'new': - return !userRead[recentTopic.value]; + if (filter === 'watched') { + filterWatchedTids(uid, tids, next); + } else { + next(null, tids); } - }).map(function(topic) { - return topic.value; - }).filter(function(tid, index, array) { - return array.indexOf(tid) === index; - }); + }, + function (tids, next) { - tids = tids.slice(0, 100); + tids = tids.slice(0, 100); - filterTopics(uid, tids, cid, results.ignoredCids, function(err, tids) { - if (err) { - return callback(err); - } + filterTopics(uid, tids, cid, ignoredCids, next); + }, + function (tids, next) { if (stop === -1) { tids = tids.slice(start); @@ -135,10 +148,22 @@ module.exports = function(Topics) { tids = tids.slice(start, stop + 1); } - callback(null, tids); + next(null, tids); + } + ], callback); + }; + + function filterWatchedTids(uid, tids, callback) { + db.sortedSetScores('uid:' + uid + ':followed_tids', tids, function(err, scores) { + if (err) { + return callback(err); + } + tids = tids.filter(function(tid, index) { + return tid && !!scores[index]; }); + callback(null, tids); }); - }; + } function filterTopics(uid, tids, cid, ignoredCids, callback) { if (!Array.isArray(ignoredCids) || !tids.length) {