BUGFIX: improve quality of unread / new counters

This commit is contained in:
Sam 2014-02-11 15:28:05 +11:00
parent 4a35d055bc
commit 11e962c848
4 changed files with 51 additions and 4 deletions

View File

@ -37,6 +37,11 @@ Discourse.ScreenTrack = Ember.Object.extend({
},
stop: function() {
if(!this.get('topicId')) {
// already stopped no need to "extra stop"
return;
}
this.tick();
this.flush();
this.reset();
@ -105,9 +110,10 @@ Discourse.ScreenTrack = Ember.Object.extend({
var highestSeenByTopic = Discourse.Session.currentProp('highestSeenByTopic');
if ((highestSeenByTopic[topicId] || 0) < highestSeen) {
highestSeenByTopic[topicId] = highestSeen;
Discourse.TopicTrackingState.current().updateSeen(topicId, highestSeen);
}
Discourse.TopicTrackingState.current().updateSeen(topicId, highestSeen);
if (!$.isEmptyObject(newTimings)) {
Discourse.ajax('/topics/timings', {
data: {

View File

@ -39,8 +39,9 @@ Discourse.TopicTrackingState = Discourse.Model.extend({
},
updateSeen: function(topicId, highestSeen) {
if(!topicId || !highestSeen) { return; }
var state = this.states["t" + topicId];
if(state && state.last_read_post_number < highestSeen) {
if(state && (!state.last_read_post_number || state.last_read_post_number < highestSeen)) {
state.last_read_post_number = highestSeen;
this.incrementMessageCount();
}
@ -84,9 +85,24 @@ Discourse.TopicTrackingState = Discourse.Model.extend({
sync: function(list, filter){
var tracker = this;
var states = this.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--){
var state = states["t"+ list.topics[i].id];
if(state && state.last_read_post_number > 0){
if(filter === "new"){
list.topics.splice(i, 1);
} else {
list.topics[i].unseen = false;
list.topics[i].dont_sync = true;
}
}
}
if(filter === "new" && !list.more_topics_url){
// scrub all new rows and reload from list
_.each(this.states, function(state){
@ -112,10 +128,11 @@ Discourse.TopicTrackingState = Discourse.Model.extend({
if(topic.unseen) {
row.last_read_post_number = null;
} else if (topic.unread || topic.new_posts){
// subtle issue here
row.last_read_post_number = topic.highest_post_number - ((topic.unread||0) + (topic.new_posts||0));
} else {
delete tracker.states["t" + topic.id];
if(!topic.dont_sync) {
delete tracker.states["t" + topic.id];
}
return;
}

View File

@ -11,6 +11,9 @@ function buildTopicRoute(filter) {
},
model: function() {
// attempt to stop early cause we need this to be called before .sync
Discourse.ScreenTrack.current().stop();
return Discourse.TopicList.list(filter).then(function(list) {
var tracking = Discourse.TopicTrackingState.current();
if (tracking) {

View File

@ -0,0 +1,21 @@
module("Discourse.TopicTrackingState");
test("sync", function () {
var state = Discourse.TopicTrackingState.create();
// fake track it
state.states["t111"] = {last_read_post_number: null};
state.updateSeen(111, 7);
var list = {topics: [{
highest_post_number: null,
id: 111,
unread: 10,
new_posts: 10
}]};
state.sync(list, "new");
equal(list.topics.length, 0, "expect new topic to be removed as it was seen");
});