FIX: don't show new topic notifications in homepag for suppressed categories

This commit is contained in:
Régis Hanol 2015-09-03 19:18:46 +02:00
parent 7516643f11
commit 80041b874c
3 changed files with 61 additions and 55 deletions

View File

@ -1,4 +1,6 @@
import NotificationLevels from 'discourse/lib/notification-levels'; 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) { function isNew(topic) {
return topic.last_read_post_number === null && return topic.last_read_post_number === null &&
@ -15,24 +17,25 @@ function isUnread(topic) {
const TopicTrackingState = Discourse.Model.extend({ const TopicTrackingState = Discourse.Model.extend({
messageCount: 0, messageCount: 0,
_setup: function() { @on("init")
_setup() {
this.unreadSequence = []; this.unreadSequence = [];
this.newSequence = []; this.newSequence = [];
this.states = {}; this.states = {};
}.on('init'), },
establishChannels() { establishChannels() {
const tracker = this; const tracker = this;
const process = function(data){ const process = data => {
if (data.message_type === "delete") { if (data.message_type === "delete") {
tracker.removeTopic(data.topic_id); tracker.removeTopic(data.topic_id);
tracker.incrementMessageCount(); tracker.incrementMessageCount();
} }
if (data.message_type === "new_topic" || data.message_type === "latest") { if (data.message_type === "new_topic" || data.message_type === "latest") {
const ignored_categories = Discourse.User.currentProp("muted_category_ids"); const muted_category_ids = Discourse.User.currentProp("muted_category_ids");
if(_.include(ignored_categories, data.payload.category_id)){ if (_.include(muted_category_ids, data.payload.category_id)) {
return; return;
} }
} }
@ -45,7 +48,7 @@ const TopicTrackingState = Discourse.Model.extend({
tracker.notify(data); tracker.notify(data);
const old = tracker.states["t" + data.topic_id]; 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.states["t" + data.topic_id] = data.payload;
tracker.incrementMessageCount(); tracker.incrementMessageCount();
} }
@ -60,20 +63,27 @@ const TopicTrackingState = Discourse.Model.extend({
}, },
updateSeen(topicId, highestSeen) { updateSeen(topicId, highestSeen) {
if(!topicId || !highestSeen) { return; } if (!topicId || !highestSeen) { return; }
const state = this.states["t" + topicId]; 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; state.last_read_post_number = highestSeen;
this.incrementMessageCount(); this.incrementMessageCount();
} }
}, },
notify(data){ notify(data) {
if (!this.newIncoming) { return; } if (!this.newIncoming) { return; }
const filter = this.get("filter"); 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); 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); this.addIncoming(data.topic_id);
} }
@ -92,12 +102,12 @@ const TopicTrackingState = Discourse.Model.extend({
}, },
addIncoming(topicId) { addIncoming(topicId) {
if(this.newIncoming.indexOf(topicId) === -1){ if (this.newIncoming.indexOf(topicId) === -1) {
this.newIncoming.push(topicId); this.newIncoming.push(topicId);
} }
}, },
resetTracking(){ resetTracking() {
this.newIncoming = []; this.newIncoming = [];
this.set("incomingCount", 0); this.set("incomingCount", 0);
}, },
@ -109,10 +119,10 @@ const TopicTrackingState = Discourse.Model.extend({
this.set("incomingCount", 0); this.set("incomingCount", 0);
}, },
hasIncoming: function(){ @computed("incomingCount")
const count = this.get('incomingCount'); hasIncoming(incomingCount) {
return count && count > 0; return incomingCount && incomingCount > 0;
}.property('incomingCount'), },
removeTopic(topic_id) { removeTopic(topic_id) {
delete this.states["t" + topic_id]; delete this.states["t" + topic_id];
@ -124,7 +134,7 @@ const TopicTrackingState = Discourse.Model.extend({
if (Em.isEmpty(topics)) { return; } if (Em.isEmpty(topics)) { return; }
const states = this.states; const states = this.states;
topics.forEach(function(t) { topics.forEach(t => {
const state = states['t' + t.get('id')]; const state = states['t' + t.get('id')];
if (state) { if (state) {
@ -135,9 +145,7 @@ const TopicTrackingState = Discourse.Model.extend({
unread = postsCount - state.last_read_post_number; unread = postsCount - state.last_read_post_number;
if (newPosts < 0) { newPosts = 0; } if (newPosts < 0) { newPosts = 0; }
if (!state.last_read_post_number) { if (!state.last_read_post_number) { unread = 0; }
unread = 0;
}
if (unread < 0) { unread = 0; } if (unread < 0) { unread = 0; }
t.setProperties({ t.setProperties({
@ -198,14 +206,12 @@ const TopicTrackingState = Discourse.Model.extend({
}); });
// Correct missing states, safeguard in case message bus is corrupt // 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 = {}; const ids = {};
list.topics.forEach(function(r){ list.topics.forEach(r => ids["t" + r.id] = true);
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 // we are good if we are on the list
if (ids[k]) { return; } if (ids[k]) { return; }
@ -229,10 +235,10 @@ const TopicTrackingState = Discourse.Model.extend({
this.set("messageCount", this.get("messageCount") + 1); this.set("messageCount", this.get("messageCount") + 1);
}, },
countNew(category_id){ countNew(category_id) {
return _.chain(this.states) return _.chain(this.states)
.where(isNew) .where(isNew)
.where(function(topic){ return topic.category_id === category_id || !category_id;}) .where(topic => topic.category_id === category_id || !category_id)
.value() .value()
.length; .length;
}, },
@ -242,18 +248,17 @@ const TopicTrackingState = Discourse.Model.extend({
}, },
resetNew() { resetNew() {
const self = this; Object.keys(this.states).forEach(id => {
Object.keys(this.states).forEach(function (id) { if (this.states[id].last_read_post_number === null) {
if (self.states[id].last_read_post_number === null) { delete this.states[id];
delete self.states[id];
} }
}); });
}, },
countUnread(category_id){ countUnread(category_id) {
return _.chain(this.states) return _.chain(this.states)
.where(isUnread) .where(isUnread)
.where(function(topic){ return topic.category_id === category_id || !category_id;}) .where(topic => topic.category_id === category_id || !category_id)
.value() .value()
.length; .length;
}, },
@ -269,42 +274,37 @@ const TopicTrackingState = Discourse.Model.extend({
return sum; return sum;
}, },
lookupCount(name, category){ lookupCount(name, category) {
if (name === "latest") { if (name === "latest") {
return this.lookupCount("new", category) + return this.lookupCount("new", category) +
this.lookupCount("unread", category); this.lookupCount("unread", category);
} }
let categoryName = category ? Em.get(category, "name") : null; let categoryName = category ? Em.get(category, "name") : null;
if(name === "new") { if (name === "new") {
return this.countNew(categoryName); return this.countNew(categoryName);
} else if(name === "unread") { } else if (name === "unread") {
return this.countUnread(categoryName); return this.countUnread(categoryName);
} else { } else {
categoryName = name.split("/")[1]; categoryName = name.split("/")[1];
if(categoryName) { if (categoryName) {
return this.countCategory(categoryName); return this.countCategory(categoryName);
} }
} }
}, },
loadStates(data) { loadStates(data) {
// not exposed
const states = this.states; const states = this.states;
if (data) {
if(data) { _.each(data,topic => states["t" + topic.topic_id] = topic);
_.each(data,function(topic){
states["t" + topic.topic_id] = topic;
});
} }
} }
}); });
TopicTrackingState.reopenClass({ TopicTrackingState.reopenClass({
createFromStates(data) {
createFromStates(data) {
// TODO: This should be a model that does injection automatically // TODO: This should be a model that does injection automatically
const container = Discourse.__container__, const container = Discourse.__container__,
messageBus = container.lookup('message-bus:main'), messageBus = container.lookup('message-bus:main'),
@ -316,7 +316,8 @@ TopicTrackingState.reopenClass({
instance.establishChannels(); instance.establishChannels();
return instance; return instance;
}, },
current(){
current() {
if (!this.tracker) { if (!this.tracker) {
const data = PreloadStore.get('topicTrackingStates'); const data = PreloadStore.get('topicTrackingStates');
this.tracker = this.createFromStates(data); this.tracker = this.createFromStates(data);

View File

@ -71,6 +71,10 @@ class Site
end end
end end
def suppressed_from_homepage_category_ids
categories.select { |c| c.suppress_from_homepage == true }.map(&:id)
end
def archetypes def archetypes
Archetype.list.reject { |t| t.id == Archetype.private_message } Archetype.list.reject { |t| t.id == Archetype.private_message }
end end

View File

@ -11,7 +11,8 @@ class SiteSerializer < ApplicationSerializer
:uncategorized_category_id, # this is hidden so putting it here :uncategorized_category_id, # this is hidden so putting it here
:is_readonly, :is_readonly,
:disabled_plugins, :disabled_plugins,
:user_field_max_length :user_field_max_length,
:suppressed_from_homepage_category_ids
has_many :categories, serializer: BasicCategorySerializer, embed: :objects has_many :categories, serializer: BasicCategorySerializer, embed: :objects
has_many :post_action_types, embed: :objects has_many :post_action_types, embed: :objects