diff --git a/app/assets/javascripts/discourse/components/scrolling-post-stream.js.es6 b/app/assets/javascripts/discourse/components/scrolling-post-stream.js.es6 index 4121a8b0b33..89a48126f30 100644 --- a/app/assets/javascripts/discourse/components/scrolling-post-stream.js.es6 +++ b/app/assets/javascripts/discourse/components/scrolling-post-stream.js.es6 @@ -40,7 +40,8 @@ export default MountWidget.extend({ "gaps", "selectedQuery", "selectedPostsCount", - "searchService" + "searchService", + "showReadIndicator" ); }, @@ -291,6 +292,12 @@ export default MountWidget.extend({ onRefresh: "refreshLikes" }); } + + if (args.refreshReaders) { + this.dirtyKeys.keyDirty(`post-menu-${args.id}`, { + onRefresh: "refreshReaders" + }); + } } else if (args.force) { this.dirtyKeys.forceAll(); } 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 564938e0566..e7ed6186b34 100644 --- a/app/assets/javascripts/discourse/components/topic-list-item.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-list-item.js.es6 @@ -35,6 +35,47 @@ export const ListItemDefaults = { attributeBindings: ["data-topic-id"], "data-topic-id": Ember.computed.alias("topic.id"), + didInsertElement() { + this._super(...arguments); + + if (this.includeReadIndicator) { + this.messageBus.subscribe(this.readIndicatorChannel, data => { + const nodeClassList = document.querySelector( + `.indicator-topic-${data.topic_id}` + ).classList; + + if (data.show_indicator) { + nodeClassList.remove("unread"); + } else { + nodeClassList.add("unread"); + } + }); + } + }, + + willDestroyElement() { + this._super(...arguments); + + if (this.includeReadIndicator) { + this.messageBus.unsubscribe(this.readIndicatorChannel); + } + }, + + @computed("topic.id") + readIndicatorChannel(topicId) { + return `/private-messages/read-indicator/${topicId}`; + }, + + @computed("topic.read_by_group_member") + unreadClass(readByGroupMember) { + return readByGroupMember ? "" : "unread"; + }, + + @computed("topic.read_by_group_member") + includeReadIndicator(readByGroupMember) { + return typeof readByGroupMember !== "undefined"; + }, + @computed newDotText() { return this.currentUser && this.currentUser.trust_level > 0 diff --git a/app/assets/javascripts/discourse/controllers/topic.js.es6 b/app/assets/javascripts/discourse/controllers/topic.js.es6 index c1983bc4c16..25a635b48bf 100644 --- a/app/assets/javascripts/discourse/controllers/topic.js.es6 +++ b/app/assets/javascripts/discourse/controllers/topic.js.es6 @@ -1348,6 +1348,17 @@ export default Ember.Controller.extend(bufferedProperty("model"), { }) .then(() => refresh({ id: data.id, refreshLikes: true })); break; + case "read": + postStream + .triggerChangedPost(data.id, data.updated_at, { + preserveCooked: true + }) + .then(() => + refresh({ + id: data.id, + refreshReaders: topic.show_read_indicator + }) + ); case "revised": case "rebaked": { postStream diff --git a/app/assets/javascripts/discourse/lib/transform-post.js.es6 b/app/assets/javascripts/discourse/lib/transform-post.js.es6 index 7a1872b4fe5..5f882d8a933 100644 --- a/app/assets/javascripts/discourse/lib/transform-post.js.es6 +++ b/app/assets/javascripts/discourse/lib/transform-post.js.es6 @@ -71,7 +71,8 @@ export function transformBasicPost(post) { expandablePost: false, replyCount: post.reply_count, locked: post.locked, - userCustomFields: post.user_custom_fields + userCustomFields: post.user_custom_fields, + readCount: post.readers_count }; _additionalAttributes.forEach(a => (postAtts[a] = post[a])); diff --git a/app/assets/javascripts/discourse/models/group.js.es6 b/app/assets/javascripts/discourse/models/group.js.es6 index 5ea8f11616f..04898356354 100644 --- a/app/assets/javascripts/discourse/models/group.js.es6 +++ b/app/assets/javascripts/discourse/models/group.js.es6 @@ -178,7 +178,8 @@ const Group = RestModel.extend({ allow_membership_requests: this.allow_membership_requests, full_name: this.full_name, default_notification_level: this.default_notification_level, - membership_request_template: this.membership_request_template + membership_request_template: this.membership_request_template, + publish_read_state: this.publish_read_state }; if (!this.id) { diff --git a/app/assets/javascripts/discourse/templates/components/groups-form-interaction-fields.hbs b/app/assets/javascripts/discourse/templates/components/groups-form-interaction-fields.hbs index b2f254ca328..959e2e12d13 100644 --- a/app/assets/javascripts/discourse/templates/components/groups-form-interaction-fields.hbs +++ b/app/assets/javascripts/discourse/templates/components/groups-form-interaction-fields.hbs @@ -52,6 +52,16 @@ class="groups-form-messageable-level"}} +
+ +
+ {{#if showEmailSettings}}
diff --git a/app/assets/javascripts/discourse/templates/list/topic-list-item.raw.hbs b/app/assets/javascripts/discourse/templates/list/topic-list-item.raw.hbs index 6b6b7b2af14..f6d2ddfc382 100644 --- a/app/assets/javascripts/discourse/templates/list/topic-list-item.raw.hbs +++ b/app/assets/javascripts/discourse/templates/list/topic-list-item.raw.hbs @@ -23,6 +23,11 @@ {{~#if showTopicPostBadges}} {{~raw "topic-post-badges" unread=topic.unread newPosts=topic.displayNewPosts unseen=topic.unseen url=topic.lastUnreadUrl newDotText=newDotText}} {{~/if}} + {{~#if includeReadIndicator}} + + {{~d-icon "book-reader"}} + + {{~/if}}