diff --git a/app/assets/javascripts/discourse/components/screen_track.js b/app/assets/javascripts/discourse/components/screen_track.js index 5601eb17a..8a2679577 100644 --- a/app/assets/javascripts/discourse/components/screen_track.js +++ b/app/assets/javascripts/discourse/components/screen_track.js @@ -28,12 +28,6 @@ Discourse.ScreenTrack = Ember.Object.extend({ }; }, - guessedSeen: function(postNumber) { - if (postNumber > (this.highestSeen || 0)) { - this.highestSeen = postNumber; - } - }, - // Reset our timers reset: function() { this.lastTick = new Date().getTime(); @@ -93,16 +87,21 @@ Discourse.ScreenTrack = Ember.Object.extend({ timing.time = 0; }); topicId = this.get('topic_id'); + + var highestSeen = 0; + $.each(newTimings, function(postNumber){ + highestSeen = Math.max(highestSeen, parseInt(postNumber, 10)); + }); + highestSeenByTopic = Discourse.get('highestSeenByTopic'); - if ((highestSeenByTopic[topicId] || 0) < this.highestSeen) { - highestSeenByTopic[topicId] = this.highestSeen; + if ((highestSeenByTopic[topicId] || 0) < highestSeen) { + highestSeenByTopic[topicId] = highestSeen; } if (!Object.isEmpty(newTimings)) { Discourse.ajax(Discourse.getURL('/topics/timings'), { data: { timings: newTimings, topic_time: this.topicTime, - highest_seen: this.highestSeen, topic_id: topicId }, cache: false, diff --git a/app/assets/javascripts/discourse/views/topic_view.js b/app/assets/javascripts/discourse/views/topic_view.js index 95bd306f1..1c88898c9 100644 --- a/app/assets/javascripts/discourse/views/topic_view.js +++ b/app/assets/javascripts/discourse/views/topic_view.js @@ -181,8 +181,6 @@ Discourse.TopicView = Discourse.View.extend(Discourse.Scrolling, { } if (!post.get('read')) { post.set('read', true); - screenTrack = this.get('screenTrack'); - if (screenTrack) { screenTrack.guessedSeen(postNumber); } } return post.get('post_number'); } diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index 71a5b45c4..01bd068da 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -151,7 +151,6 @@ class TopicsController < ApplicationController PostTiming.process_timings( current_user, params[:topic_id].to_i, - params[:highest_seen].to_i, params[:topic_time].to_i, (params[:timings] || []).map{|post_number, t| [post_number.to_i, t.to_i]} ) diff --git a/app/models/post_timing.rb b/app/models/post_timing.rb index 1caeaf307..acf6147af 100644 --- a/app/models/post_timing.rb +++ b/app/models/post_timing.rb @@ -37,15 +37,19 @@ class PostTiming < ActiveRecord::Base end - def self.process_timings(current_user, topic_id, highest_seen, topic_time, timings) + def self.process_timings(current_user, topic_id, topic_time, timings) current_user.update_time_read! + highest_seen = 1 timings.each do |post_number, time| if post_number >= 0 PostTiming.record_timing(topic_id: topic_id, post_number: post_number, user_id: current_user.id, msecs: time) + + highest_seen = post_number.to_i > highest_seen ? + post_number.to_i : highest_seen end end diff --git a/app/models/topic_user.rb b/app/models/topic_user.rb index 5052999b7..975c79114 100644 --- a/app/models/topic_user.rb +++ b/app/models/topic_user.rb @@ -117,6 +117,10 @@ class TopicUser < ActiveRecord::Base threshold: SiteSetting.auto_track_topics_after } + # In case anyone seens "seen_post_count" and gets confused, like I do. + # seen_post_count represents the highest_post_number of the topic when + # the user visited it. It may be out of alignement with last_read, meaning + # ... user visited the topic but did not read the posts rows = exec_sql("UPDATE topic_users SET last_read_post_number = greatest(:post_number, tu.last_read_post_number), @@ -176,17 +180,16 @@ class TopicUser < ActiveRecord::Base UPDATE topic_users t SET last_read_post_number = last_read, - seen_post_count = post_count + seen_post_count = GREATEST(t.seen_post_count, last_read) FROM ( - SELECT topic_id, user_id, COUNT(*) post_count, MAX(post_number) last_read + SELECT topic_id, user_id, MAX(post_number) last_read FROM post_timings GROUP BY topic_id, user_id ) as X WHERE X.topic_id = t.topic_id AND X.user_id = t.user_id AND ( - last_read_post_number <> last_read OR - seen_post_count <> post_count + last_read_post_number <> last_read ) SQL end diff --git a/spec/models/post_timing_spec.rb b/spec/models/post_timing_spec.rb index fec311d79..fb1c592d1 100644 --- a/spec/models/post_timing_spec.rb +++ b/spec/models/post_timing_spec.rb @@ -21,7 +21,7 @@ describe PostTiming do post.user.unread_notifications_by_type.should == { Notification.types[:liked] => 1 } - PostTiming.process_timings(post.user, post.topic_id, 1, 100, [[post.post_number, 100]]) + PostTiming.process_timings(post.user, post.topic_id, 1, [[post.post_number, 100]]) post.user.reload post.user.unread_notifications_by_type.should == {}