diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6 index 82efda4dc14..682d202030b 100644 --- a/app/assets/javascripts/discourse/controllers/topic.js.es6 +++ b/app/assets/javascripts/discourse/controllers/topic.js.es6 @@ -849,14 +849,25 @@ export default Ember.Controller.extend(SelectedPostsCount, BufferedContent, { if (topic.get('id') === topicId) { + let highestReadPostId = 0; + // TODO identity map for postNumber postStream.get('posts').forEach(post => { if (!post.read && postNumbers.indexOf(post.post_number) !== -1) { + const id = post.get('id'); + if (id > highestReadPostId) { + highestReadPostId = id; + } + post.set('read', true); - this.appEvents.trigger('post-stream:refresh', { id: post.id }); + this.appEvents.trigger('post-stream:refresh', { id }); } }); + if (highestReadPostId > 0) { + topic.set('last_read_post_id', highestReadPostId); + } + const max = _.max(postNumbers); if (max > topic.get("last_read_post_number")) { topic.set("last_read_post_number", max); diff --git a/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 b/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 index a3e97c9b0a2..378970893d7 100644 --- a/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 +++ b/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 @@ -320,11 +320,6 @@ const TopicTrackingState = Discourse.Model.extend({ .length; }, - lastReadPostNumber(topicId) { - const state = this.states[`t${topicId}`]; - return state ? state.last_read_post_number : null; - }, - countCategory(category_id) { let sum = 0; _.each(this.states, function(topic){ diff --git a/app/assets/javascripts/discourse/widgets/topic-timeline.js.es6 b/app/assets/javascripts/discourse/widgets/topic-timeline.js.es6 index 1f4867f3086..8dd16590956 100644 --- a/app/assets/javascripts/discourse/widgets/topic-timeline.js.es6 +++ b/app/assets/javascripts/discourse/widgets/topic-timeline.js.es6 @@ -20,7 +20,7 @@ createWidget('timeline-last-read', { this.attach('button', { className: 'btn btn-primary btn-small', icon: 'arrow-left', - label: 'go_back', + label: 'topic.timeline.back', action: 'goBack' }) ]; @@ -92,7 +92,8 @@ createWidget('timeline-scrollarea', { position() { const { attrs } = this; const percentage = this.state.percentage; - const postStream = attrs.topic.get('postStream'); + const topic = attrs.topic; + const postStream = topic.get('postStream'); const total = postStream.get('filteredPostsCount'); let current = Math.round(total * percentage); @@ -111,12 +112,13 @@ createWidget('timeline-scrollarea', { lastReadPercentage: null }; - if (attrs.topicTrackingState) { - const lastRead = attrs.topicTrackingState.lastReadPostNumber(attrs.topic.id); - if (lastRead) { - result.lastRead = lastRead; - result.lastReadPercentage = lastRead === 1 ? 0.0 : parseFloat(lastRead) / total; - } + const lastReadId = topic.last_read_post_id; + const lastReadNumber = topic.last_read_post_number; + + if (lastReadId && lastReadNumber) { + const idx = postStream.get('stream').indexOf(lastReadId) + 1; + result.lastRead = lastReadNumber; + result.lastReadPercentage = this._percentFor(topic, idx); } return result; @@ -173,7 +175,6 @@ createWidget('timeline-scrollarea', { _percentFor(topic, postNumber) { const total = topic.get('postStream.filteredPostsCount'); - console.log(postNumber, total); let result = (postNumber === 1) ? 0.0 : parseFloat(postNumber) / total; if (result < 0) { return 0.0; } diff --git a/app/serializers/topic_view_serializer.rb b/app/serializers/topic_view_serializer.rb index c44d44cacc0..e9e308b5dfc 100644 --- a/app/serializers/topic_view_serializer.rb +++ b/app/serializers/topic_view_serializer.rb @@ -47,6 +47,7 @@ class TopicViewSerializer < ApplicationSerializer :details, :highest_post_number, :last_read_post_number, + :last_read_post_id, :deleted_by, :has_deleted, :actions_summary, @@ -164,8 +165,16 @@ class TopicViewSerializer < ApplicationSerializer object.highest_post_number end + def last_read_post_id + return nil unless object.filtered_post_stream && last_read_post_number + object.filtered_post_stream.each do |ps| + return ps[0] if ps[1] === last_read_post_number + end + end + alias_method :include_last_read_post_id?, :has_topic_user? + def last_read_post_number - object.topic_user.last_read_post_number + @last_read_post_number ||= object.topic_user.last_read_post_number end alias_method :include_last_read_post_number?, :has_topic_user? diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 4b86c676a2e..5d347aaa90b 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1294,6 +1294,7 @@ en: auto_close_immediate: "The last post in the topic is already %{hours} hours old, so the topic will be closed immediately." timeline: + back: "Back" replies: "%{current} / %{total} replies" replies_short: "%{current} / %{total}"