From c2c256cdd9a46fcb8eefc4cfdda5f6d3674357ef Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Thu, 14 Aug 2014 18:30:38 -0400 Subject: [PATCH] FIX: Bug with cached topics not being marked as read in your topics list. --- .../discourse/models/topic_list.js | 16 ++++- .../discourse/models/topic_tracking_state.js | 59 ++++++++++++++----- .../routes/build-category-route.js.es6 | 6 -- .../discourse/routes/build-topic-route.js.es6 | 9 +-- .../templates/discovery/topics.js.handlebars | 21 +++---- 5 files changed, 68 insertions(+), 43 deletions(-) diff --git a/app/assets/javascripts/discourse/models/topic_list.js b/app/assets/javascripts/discourse/models/topic_list.js index 4fa07d97795..1e4357be0f6 100644 --- a/app/assets/javascripts/discourse/models/topic_list.js +++ b/app/assets/javascripts/discourse/models/topic_list.js @@ -196,10 +196,16 @@ Discourse.TopicList.reopenClass({ **/ list: function(filter, params) { var session = Discourse.Session.current(), - list = session.get('topicList'); + list = session.get('topicList'), + tracking = Discourse.TopicTrackingState.current(); if (list && (list.get('filter') === filter)) { list.set('loaded', true); + + if (tracking) { + tracking.updateTopics(list.get('topics')); + } + return Ember.RSVP.resolve(list); } session.setProperties({topicList: null, topicListScrollPosition: null}); @@ -223,7 +229,13 @@ Discourse.TopicList.reopenClass({ } }); - return Discourse.TopicList.find(filter, _.extend(findParams, params || {})); + return Discourse.TopicList.find(filter, _.extend(findParams, params || {})).then(function (list) { + if (tracking) { + tracking.sync(list, list.filter); + tracking.trackIncoming(list.filter); + } + return list; + }); }, find: function(filter, params) { diff --git a/app/assets/javascripts/discourse/models/topic_tracking_state.js b/app/assets/javascripts/discourse/models/topic_tracking_state.js index e77476a7b4d..0299f923844 100644 --- a/app/assets/javascripts/discourse/models/topic_tracking_state.js +++ b/app/assets/javascripts/discourse/models/topic_tracking_state.js @@ -1,12 +1,11 @@ Discourse.TopicTrackingState = Discourse.Model.extend({ messageCount: 0, - init: function(){ - this._super(); + _setup: function() { this.unreadSequence = []; this.newSequence = []; this.states = {}; - }, + }.on('init'), establishChannels: function() { var tracker = this; @@ -104,18 +103,48 @@ Discourse.TopicTrackingState = Discourse.Model.extend({ delete this.states["t" + topic_id]; }, - sync: function(list, filter){ - var tracker = this; - var states = this.states; + // If we have a cached topic list, we can update it from our tracking + // information. + updateTopics: function(topics) { + if (Em.isEmpty(topics)) { return; } - if(!list || !list.topics) { return; } + var states = this.states; + topics.forEach(function(t) { + var state = states['t' + t.get('id')]; + + if (state) { + var lastRead = t.get('last_read_post_number'); + if (lastRead !== state.last_read_post_number) { + var postsCount = t.get('posts_count'), + newPosts = postsCount - state.highest_post_number, + unread = postsCount - state.last_read_post_number; + + if (newPosts < 0) { newPosts = 0; } + if (unread < 0) { unread = 0; } + + t.setProperties({ + highest_post_number: state.highest_post_number, + last_read_post_number: state.last_read_post_number, + new_posts: newPosts, + unread: unread + }); + } + } + }); + }, + + sync: function(list, filter) { + var tracker = this, + states = tracker.states; + + if (!list || !list.topics) { return; } // compensate for delayed "new" topics // client side we know they are not new, server side we think they are - for(var i=list.topics.length-1; i>=0; i--){ + for (var i=list.topics.length-1; i>=0; i--) { var state = states["t"+ list.topics[i].id]; - if(state && state.last_read_post_number > 0){ - if(filter === "new"){ + if (state && state.last_read_post_number > 0) { + if (filter === "new") { list.topics.splice(i, 1); } else { list.topics[i].unseen = false; @@ -124,16 +153,16 @@ Discourse.TopicTrackingState = Discourse.Model.extend({ } } - _.each(list.topics, function(topic){ + list.topics.forEach(function(topic){ var row = tracker.states["t" + topic.id] || {}; - row.topic_id = topic.id; - if(topic.unseen) { + + if (topic.unseen) { row.last_read_post_number = null; - } else if (topic.unread || topic.new_posts){ + } else if (topic.unread || topic.new_posts) { row.last_read_post_number = topic.highest_post_number - ((topic.unread||0) + (topic.new_posts||0)); } else { - if(!topic.dont_sync) { + if (!topic.dont_sync) { delete tracker.states["t" + topic.id]; } return; diff --git a/app/assets/javascripts/discourse/routes/build-category-route.js.es6 b/app/assets/javascripts/discourse/routes/build-category-route.js.es6 index e1b89f6f4d7..1f4faa35047 100644 --- a/app/assets/javascripts/discourse/routes/build-category-route.js.es6 +++ b/app/assets/javascripts/discourse/routes/build-category-route.js.es6 @@ -53,12 +53,6 @@ export default function(filter, params) { var findOpts = filterQueryParams(transaction.queryParams, params); return Discourse.TopicList.list(listFilter, findOpts).then(function(list) { - var tracking = Discourse.TopicTrackingState.current(); - if (tracking) { - tracking.sync(list, listFilter); - tracking.trackIncoming(listFilter); - } - // If all the categories are the same, we can hide them var hideCategory = !list.get('topics').find(function (t) { return t.get('category') !== model; }); list.set('hideCategory', hideCategory); diff --git a/app/assets/javascripts/discourse/routes/build-topic-route.js.es6 b/app/assets/javascripts/discourse/routes/build-topic-route.js.es6 index 14b6a0017bd..8a5d419e461 100644 --- a/app/assets/javascripts/discourse/routes/build-topic-route.js.es6 +++ b/app/assets/javascripts/discourse/routes/build-topic-route.js.es6 @@ -26,14 +26,7 @@ export default function(filter) { Discourse.ScreenTrack.current().stop(); var findOpts = filterQueryParams(transaction.queryParams); - return Discourse.TopicList.list(filter, findOpts).then(function(list) { - var tracking = Discourse.TopicTrackingState.current(); - if (tracking) { - tracking.sync(list, filter); - tracking.trackIncoming(filter); - } - return list; - }); + return Discourse.TopicList.list(filter, findOpts); }, setupController: function(controller, model, trans) { diff --git a/app/assets/javascripts/discourse/templates/discovery/topics.js.handlebars b/app/assets/javascripts/discourse/templates/discovery/topics.js.handlebars index 91d87043273..e7f620ed4a0 100644 --- a/app/assets/javascripts/discourse/templates/discovery/topics.js.handlebars +++ b/app/assets/javascripts/discourse/templates/discovery/topics.js.handlebars @@ -1,14 +1,13 @@ - {{#if showDismissAtTop}} -
-{{#if showDismissRead}} - - -{{/if}} -{{#if showResetNew}} - -{{/if}} -
+
+ {{#if showDismissRead}} + + + {{/if}} + {{#if showResetNew}} + + {{/if}} +
{{/if}} {{#if selected}} @@ -37,8 +36,6 @@ {{/if}} {{#sortable-heading sortBy="default" action="changeSort" order=order ascending=ascending}} {{i18n topic.title}} - - {{/sortable-heading}} {{#unless controller.hideCategory}} {{#sortable-heading sortBy="category" action="changeSort" order=order ascending=ascending}}