diff --git a/public/css/style.less b/public/css/style.less index 484ea34e1c..c857495090 100644 --- a/public/css/style.less +++ b/public/css/style.less @@ -751,6 +751,10 @@ body .navbar .nodebb-inline-block { } } +#mark-allread-btn { + margin-bottom:15px; +} + @-webkit-keyframes scroll-2 /* Safari and Chrome */ { 0% {top: 0px;} diff --git a/public/src/forum/recent.js b/public/src/forum/recent.js index 9cc0c31208..067b595fc8 100644 --- a/public/src/forum/recent.js +++ b/public/src/forum/recent.js @@ -44,7 +44,13 @@ socket.on('event:new_post', function(data) { ++newPostCount; updateAlertText(); - + }); + + $('#mark-allread-btn').on('click', function() { + socket.emit('api:topics.markAllRead'); + $(this).remove(); + $('#topics-container').empty(); + $('#category-no-topics').removeClass('hidden'); }); })(); \ No newline at end of file diff --git a/public/templates/config.json b/public/templates/config.json index 5f00752c23..e88444223a 100644 --- a/public/templates/config.json +++ b/public/templates/config.json @@ -27,6 +27,7 @@ "users/[^]*": "account", "recent": "recent", + "unread": "unread", "popular": "category", "active": "category" }, diff --git a/public/templates/header.tpl b/public/templates/header.tpl index 0c7ae37264..8df622c03f 100644 --- a/public/templates/header.tpl +++ b/public/templates/header.tpl @@ -49,10 +49,10 @@
  • Recent
  • -
  • diff --git a/public/templates/recent.tpl b/public/templates/recent.tpl index b838f0f33f..d9c9dca1ba 100644 --- a/public/templates/recent.tpl +++ b/public/templates/recent.tpl @@ -15,8 +15,6 @@ There are no recent topics. -

    -
      diff --git a/public/templates/unread.tpl b/public/templates/unread.tpl new file mode 100644 index 0000000000..a44d30aa1b --- /dev/null +++ b/public/templates/unread.tpl @@ -0,0 +1,54 @@ +
      + +
      + + + +
      +
      + +
      + There are no unread topics. +
      + +
      + +
      + + + + \ No newline at end of file diff --git a/src/posts.js b/src/posts.js index c0f22cba9d..0b2f29a917 100644 --- a/src/posts.js +++ b/src/posts.js @@ -307,7 +307,7 @@ var RDB = require('./redis.js'), feed.updateTopic(tid, cid); - RDB.zadd('categories:recent_posts:cid:' + cid, Date.now(), pid); + RDB.zadd('categories:recent_posts:cid:' + cid, timestamp, pid); // this is a bit of a naive implementation, defn something to look at post-MVP RDB.scard('cid:' + cid + ':active_users', function(amount) { @@ -319,7 +319,7 @@ var RDB = require('./redis.js'), }); }); - user.onNewPostMade(uid, tid, pid, timestamp); + user.onNewPostMade(uid, tid, pid, timestamp); var imgur = require('./imgur'); // move clientID to config diff --git a/src/schema.js b/src/schema.js index 1672b7b71f..7d5c7fc8b0 100644 --- a/src/schema.js +++ b/src/schema.js @@ -14,7 +14,6 @@ return { /* sets */ - tid: 'topics:tid', read_by_uid: 'tid:' + tid + ':read_by_uid', /* sorted sets */ diff --git a/src/topics.js b/src/topics.js index ee737f9452..00bcf792af 100644 --- a/src/topics.js +++ b/src/topics.js @@ -94,8 +94,6 @@ marked.setOptions({ var timestamp = Date.now(); - RDB.zremrangebyscore('topics:recent', '-inf', timestamp - 86400000); - RDB.zrevrangebyscore([ 'topics:recent', '+inf', timestamp - 86400000], function(err, tids) { var latestTopics = { @@ -120,11 +118,60 @@ marked.setOptions({ }); }); } + + Topics.getUnreadTopics = function(uid, start, stop, callback) { + + var unreadTopics = { + 'category_name' : 'Unread', + 'show_sidebar' : 'hidden', + 'show_topic_button' : 'hidden', + 'show_markallread_button': 'show', + 'no_topics_message' : 'hidden', + 'topic_row_size': 'span12', + 'topics' : [] + }; + + RDB.zrevrange('topics:recent', start, stop, function (err, tids) { + + function noUnreadTopics() { + unreadTopics.no_topics_message = 'show'; + unreadTopics.show_markallread_button = 'hidden'; + callback(unreadTopics); + } + + if (!tids || !tids.length) { + noUnreadTopics(); + return; + } + + Topics.hasReadTopics(tids, uid, function(read) { + + var unreadTids = tids.filter(function(tid, index, self) { + return read[index] === 0; + }); + + if (!unreadTids || !unreadTids.length) { + noUnreadTopics(); + return; + } + + Topics.getTopicsByTids(unreadTids, uid, function(topicData) { + unreadTopics.topics = topicData; + callback(unreadTopics); + }); + }); + }); + } Topics.getTopicsByTids = function(tids, current_user, callback, category_id) { var retrieved_topics = []; + if(!Array.isArray(tids) || tids.length === 0) { + callback(retrieved_topics); + return; + } + function getTopicInfo(topicData, callback) { function getUserName(next) { @@ -134,20 +181,20 @@ marked.setOptions({ } function hasReadTopic(next) { - topics.hasReadTopic(topicData.tid, current_user, function(hasRead) { + Topics.hasReadTopic(topicData.tid, current_user, function(hasRead) { next(null, hasRead); }); } function getTeaserInfo(next) { - topics.getTeaser(topicData.tid, function(err, teaser) { + Topics.getTeaser(topicData.tid, function(err, teaser) { next(null, teaser || {}); }); } // temporary. I don't think this call should belong here function getPrivileges(next) { - Categories.privileges(category_id, current_user, function(user_privs) { + categories.privileges(category_id, current_user, function(user_privs) { next(null, user_privs); }); } @@ -173,7 +220,7 @@ marked.setOptions({ } function loadTopic(tid, callback) { - topics.getTopicData(tid, function(topicData) { + Topics.getTopicData(tid, function(topicData) { if(!topicData) { return callback(null); } @@ -354,10 +401,11 @@ marked.setOptions({ }); } - Topics.markAllRead = function(uid) { + Topics.markAllRead = function(uid, callback) { RDB.smembers('topics:tid', function(err, tids) { if(err) { console.log(err); + callback(err, null); return; } @@ -366,6 +414,8 @@ marked.setOptions({ Topics.markAsRead(tids[i], uid); } } + + callback(null, true); }); } @@ -513,7 +563,7 @@ marked.setOptions({ // Global Topics if (uid == null) uid = 0; if (uid !== null) { - RDB.sadd(schema.topics().tid, tid); + RDB.sadd('topics:tid', tid); } else { // need to add some unique key sent by client so we can update this with the real uid later RDB.lpush(schema.topics().queued_tids, tid); diff --git a/src/webserver.js b/src/webserver.js index 5498b4c78b..dd8f3c0b90 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -150,7 +150,7 @@ var express = require('express'), // Basic Routes (entirely client-side parsed, goal is to move the rest of the crap in this file into this one section) (function() { - var routes = ['login', 'register', 'account', 'recent', 'popular', 'active', '403', '404']; + var routes = ['login', 'register', 'account', 'recent', 'unread', 'popular', 'active', '403', '404']; for (var i=0, ii=routes.length; i