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 cf5f8903751..87c256e202e 100644 --- a/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 +++ b/app/assets/javascripts/discourse/models/topic-tracking-state.js.es6 @@ -1,4 +1,6 @@ import NotificationLevels from 'discourse/lib/notification-levels'; +import computed from "ember-addons/ember-computed-decorators"; +import { on } from "ember-addons/ember-computed-decorators"; function isNew(topic) { return topic.last_read_post_number === null && @@ -15,24 +17,25 @@ function isUnread(topic) { const TopicTrackingState = Discourse.Model.extend({ messageCount: 0, - _setup: function() { + @on("init") + _setup() { this.unreadSequence = []; this.newSequence = []; this.states = {}; - }.on('init'), + }, establishChannels() { const tracker = this; - const process = function(data){ + const process = data => { if (data.message_type === "delete") { tracker.removeTopic(data.topic_id); tracker.incrementMessageCount(); } if (data.message_type === "new_topic" || data.message_type === "latest") { - const ignored_categories = Discourse.User.currentProp("muted_category_ids"); - if(_.include(ignored_categories, data.payload.category_id)){ + const muted_category_ids = Discourse.User.currentProp("muted_category_ids"); + if (_.include(muted_category_ids, data.payload.category_id)) { return; } } @@ -45,7 +48,7 @@ const TopicTrackingState = Discourse.Model.extend({ tracker.notify(data); const old = tracker.states["t" + data.topic_id]; - if(!_.isEqual(old, data.payload)){ + if (!_.isEqual(old, data.payload)) { tracker.states["t" + data.topic_id] = data.payload; tracker.incrementMessageCount(); } @@ -60,20 +63,27 @@ const TopicTrackingState = Discourse.Model.extend({ }, updateSeen(topicId, highestSeen) { - if(!topicId || !highestSeen) { return; } + if (!topicId || !highestSeen) { return; } const state = this.states["t" + topicId]; - if(state && (!state.last_read_post_number || 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(); } }, - notify(data){ + notify(data) { if (!this.newIncoming) { return; } const filter = this.get("filter"); - if ((filter === "all" || filter === "latest" || filter === "new") && data.message_type === "new_topic" ) { + if (filter === Discourse.Utilities.defaultHomepage()) { + const suppressed_from_homepage_category_ids = Discourse.Site.currentProp("suppressed_from_homepage_category_ids"); + if (_.include(suppressed_from_homepage_category_ids, data.payload.category_id)) { + return; + } + } + + if ((filter === "all" || filter === "latest" || filter === "new") && data.message_type === "new_topic") { this.addIncoming(data.topic_id); } @@ -84,7 +94,7 @@ const TopicTrackingState = Discourse.Model.extend({ } } - if(filter === "latest" && data.message_type === "latest") { + if (filter === "latest" && data.message_type === "latest") { this.addIncoming(data.topic_id); } @@ -92,12 +102,12 @@ const TopicTrackingState = Discourse.Model.extend({ }, addIncoming(topicId) { - if(this.newIncoming.indexOf(topicId) === -1){ + if (this.newIncoming.indexOf(topicId) === -1) { this.newIncoming.push(topicId); } }, - resetTracking(){ + resetTracking() { this.newIncoming = []; this.set("incomingCount", 0); }, @@ -109,10 +119,10 @@ const TopicTrackingState = Discourse.Model.extend({ this.set("incomingCount", 0); }, - hasIncoming: function(){ - const count = this.get('incomingCount'); - return count && count > 0; - }.property('incomingCount'), + @computed("incomingCount") + hasIncoming(incomingCount) { + return incomingCount && incomingCount > 0; + }, removeTopic(topic_id) { delete this.states["t" + topic_id]; @@ -124,7 +134,7 @@ const TopicTrackingState = Discourse.Model.extend({ if (Em.isEmpty(topics)) { return; } const states = this.states; - topics.forEach(function(t) { + topics.forEach(t => { const state = states['t' + t.get('id')]; if (state) { @@ -135,9 +145,7 @@ const TopicTrackingState = Discourse.Model.extend({ unread = postsCount - state.last_read_post_number; if (newPosts < 0) { newPosts = 0; } - if (!state.last_read_post_number) { - unread = 0; - } + if (!state.last_read_post_number) { unread = 0; } if (unread < 0) { unread = 0; } t.setProperties({ @@ -154,7 +162,7 @@ const TopicTrackingState = Discourse.Model.extend({ sync(list, filter) { const tracker = this, - states = tracker.states; + states = tracker.states; if (!list || !list.topics) { return; } @@ -198,14 +206,12 @@ const TopicTrackingState = Discourse.Model.extend({ }); // Correct missing states, safeguard in case message bus is corrupt - if((filter === "new" || filter === "unread") && !list.more_topics_url){ + if ((filter === "new" || filter === "unread") && !list.more_topics_url) { const ids = {}; - list.topics.forEach(function(r){ - ids["t" + r.id] = true; - }); + list.topics.forEach(r => ids["t" + r.id] = true); - _.each(tracker.states, function(v, k){ + _.each(tracker.states, (v, k) => { // we are good if we are on the list if (ids[k]) { return; } @@ -229,12 +235,12 @@ const TopicTrackingState = Discourse.Model.extend({ this.set("messageCount", this.get("messageCount") + 1); }, - countNew(category_id){ + countNew(category_id) { return _.chain(this.states) - .where(isNew) - .where(function(topic){ return topic.category_id === category_id || !category_id;}) - .value() - .length; + .where(isNew) + .where(topic => topic.category_id === category_id || !category_id) + .value() + .length; }, tooManyTracked() { @@ -242,20 +248,19 @@ const TopicTrackingState = Discourse.Model.extend({ }, resetNew() { - const self = this; - Object.keys(this.states).forEach(function (id) { - if (self.states[id].last_read_post_number === null) { - delete self.states[id]; + Object.keys(this.states).forEach(id => { + if (this.states[id].last_read_post_number === null) { + delete this.states[id]; } }); }, - countUnread(category_id){ + countUnread(category_id) { return _.chain(this.states) - .where(isUnread) - .where(function(topic){ return topic.category_id === category_id || !category_id;}) - .value() - .length; + .where(isUnread) + .where(topic => topic.category_id === category_id || !category_id) + .value() + .length; }, countCategory(category_id) { @@ -269,42 +274,37 @@ const TopicTrackingState = Discourse.Model.extend({ return sum; }, - lookupCount(name, category){ - + lookupCount(name, category) { if (name === "latest") { return this.lookupCount("new", category) + this.lookupCount("unread", category); } let categoryName = category ? Em.get(category, "name") : null; - if(name === "new") { + if (name === "new") { return this.countNew(categoryName); - } else if(name === "unread") { + } else if (name === "unread") { return this.countUnread(categoryName); } else { categoryName = name.split("/")[1]; - if(categoryName) { + if (categoryName) { return this.countCategory(categoryName); } } }, loadStates(data) { - // not exposed const states = this.states; - - if(data) { - _.each(data,function(topic){ - states["t" + topic.topic_id] = topic; - }); + if (data) { + _.each(data,topic => states["t" + topic.topic_id] = topic); } } }); TopicTrackingState.reopenClass({ - createFromStates(data) { + createFromStates(data) { // TODO: This should be a model that does injection automatically const container = Discourse.__container__, messageBus = container.lookup('message-bus:main'), @@ -316,7 +316,8 @@ TopicTrackingState.reopenClass({ instance.establishChannels(); return instance; }, - current(){ + + current() { if (!this.tracker) { const data = PreloadStore.get('topicTrackingStates'); this.tracker = this.createFromStates(data); diff --git a/app/models/site.rb b/app/models/site.rb index c2fcfeb4a45..c6a3313f172 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -71,6 +71,10 @@ class Site end end + def suppressed_from_homepage_category_ids + categories.select { |c| c.suppress_from_homepage == true }.map(&:id) + end + def archetypes Archetype.list.reject { |t| t.id == Archetype.private_message } end diff --git a/app/serializers/site_serializer.rb b/app/serializers/site_serializer.rb index 38c30737b2b..dec52ed2f2d 100644 --- a/app/serializers/site_serializer.rb +++ b/app/serializers/site_serializer.rb @@ -11,7 +11,8 @@ class SiteSerializer < ApplicationSerializer :uncategorized_category_id, # this is hidden so putting it here :is_readonly, :disabled_plugins, - :user_field_max_length + :user_field_max_length, + :suppressed_from_homepage_category_ids has_many :categories, serializer: BasicCategorySerializer, embed: :objects has_many :post_action_types, embed: :objects