diff --git a/app/assets/javascripts/discourse/components/topic-list-item.js.es6 b/app/assets/javascripts/discourse/components/topic-list-item.js.es6 index 4d2facadf1e..b555383ffb3 100644 --- a/app/assets/javascripts/discourse/components/topic-list-item.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-list-item.js.es6 @@ -47,6 +47,10 @@ export default Ember.Component.extend(StringBuffer, { } }); + if (topic === this.get('lastVisitedTopic')) { + classes.push('last-visit'); + } + return classes.join(' '); }.property(), diff --git a/app/assets/javascripts/discourse/components/topic-list.js.es6 b/app/assets/javascripts/discourse/components/topic-list.js.es6 index cf0f7eb34f3..a7c10fb4d45 100644 --- a/app/assets/javascripts/discourse/components/topic-list.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-list.js.es6 @@ -1,10 +1,11 @@ +import computed from 'ember-addons/ember-computed-decorators'; export default Ember.Component.extend({ tagName: 'table', classNames: ['topic-list'], showTopicPostBadges: true, - _observeHideCategory: function(){ + _init: function(){ this.addObserver('hideCategory', this.rerender); this.addObserver('order', this.rerender); this.addObserver('ascending', this.rerender); @@ -30,6 +31,36 @@ export default Ember.Component.extend({ return this.get('order') === "op_likes"; }.property('order'), + @computed('topics.@each') + lastVisitedTopic() { + let user = Discourse.User.current(); + if (!user || !user.previous_visit_at) { + return; + } + + let prevVisit = user.get('previousVisitAt'); + let prevTopic, topic; + let skipPinned = true; + + this.get('topics').any(t => { + if (skipPinned && t.get('pinned')) { + return false; + } + skipPinned = false; + + prevTopic = topic; + topic = t; + return t.get('bumpedAt') < prevVisit; + }); + + + if (!prevTopic || !topic) { + return; + } + + return prevTopic; + }, + click(e) { var self = this; var on = function(sel, callback){ diff --git a/app/assets/javascripts/discourse/models/user.js.es6 b/app/assets/javascripts/discourse/models/user.js.es6 index ff0ae124de1..a8ba8682fae 100644 --- a/app/assets/javascripts/discourse/models/user.js.es6 +++ b/app/assets/javascripts/discourse/models/user.js.es6 @@ -156,6 +156,11 @@ const User = RestModel.extend({ isSuspended: Em.computed.equal('suspended', true), + @computed("previous_visit_at") + previousVisitAt(previous_visit_at) { + return new Date(previous_visit_at); + }, + @computed("suspended_till") suspended(suspendedTill) { return suspendedTill && moment(suspendedTill).isAfter(); diff --git a/app/assets/javascripts/discourse/templates/components/topic-list.hbs b/app/assets/javascripts/discourse/templates/components/topic-list.hbs index ebc2e1bf5a6..d4be464b799 100644 --- a/app/assets/javascripts/discourse/templates/components/topic-list.hbs +++ b/app/assets/javascripts/discourse/templates/components/topic-list.hbs @@ -26,6 +26,7 @@ showOpLikes=showOpLikes expandGloballyPinned=expandGloballyPinned expandAllPinned=expandAllPinned + lastVisitedTopic=lastVisitedTopic selected=selected}} {{/each}} diff --git a/app/assets/stylesheets/common/base/_topic-list.scss b/app/assets/stylesheets/common/base/_topic-list.scss index ca65f1d1fa2..ca918e97086 100644 --- a/app/assets/stylesheets/common/base/_topic-list.scss +++ b/app/assets/stylesheets/common/base/_topic-list.scss @@ -31,6 +31,10 @@ html.anon .topic-list a.title:visited:not(.badge-notification) {color: dark-ligh margin-top: 2px; } border-bottom: 1px solid dark-light-diff($primary, $secondary, 90%, -75%); + + &.last-visit { + border-bottom: 1px solid scale-color($danger, $lightness: 60%); + } } > tbody > tr:first-of-type { diff --git a/app/serializers/current_user_serializer.rb b/app/serializers/current_user_serializer.rb index 4327abe79ac..e60da521bc6 100644 --- a/app/serializers/current_user_serializer.rb +++ b/app/serializers/current_user_serializer.rb @@ -33,7 +33,8 @@ class CurrentUserSerializer < BasicUserSerializer :show_queued_posts, :read_faq, :automatically_unpin_topics, - :mailing_list_mode + :mailing_list_mode, + :previous_visit_at def include_site_flagged_posts_count? object.staff?