diff --git a/app/assets/javascripts/discourse/app/models/topic-tracking-state.js b/app/assets/javascripts/discourse/app/models/topic-tracking-state.js index be49ad4b39e..65d1c21269f 100644 --- a/app/assets/javascripts/discourse/app/models/topic-tracking-state.js +++ b/app/assets/javascripts/discourse/app/models/topic-tracking-state.js @@ -404,10 +404,10 @@ const TopicTrackingState = EmberObject.extend({ return new Set(result); }, - countNew(categoryId) { + countCategoryByState(fn, categoryId) { const subcategoryIds = this.getSubCategoryIds(categoryId); return _.chain(this.states) - .filter(isNew) + .filter(fn) .filter( topic => topic.archetype !== "private_message" && @@ -417,17 +417,45 @@ const TopicTrackingState = EmberObject.extend({ .value().length; }, + countNew(categoryId) { + return this.countCategoryByState(isNew, categoryId); + }, + countUnread(categoryId) { - const subcategoryIds = this.getSubCategoryIds(categoryId); - return _.chain(this.states) - .filter(isUnread) - .filter( - topic => - topic.archetype !== "private_message" && - !topic.deleted && - (!categoryId || subcategoryIds.has(topic.category_id)) - ) - .value().length; + return this.countCategoryByState(isUnread, categoryId); + }, + + countTags(tags) { + let counts = {}; + + tags.forEach(tag => { + counts[tag] = { unreadCount: 0, newCount: 0 }; + }); + + Object.values(this.states).forEach(topic => { + if ( + topic.archetype !== "private_message" && + !topic.deleted && + topic.tags + ) { + let newTopic = isNew(topic); + let unreadTopic = isUnread(topic); + if (isUnread || isNew) { + tags.forEach(tag => { + if (topic.tags.indexOf(tag) > -1) { + if (unreadTopic) { + counts[tag].unreadCount++; + } + if (newTopic) { + counts[tag].newCount++; + } + } + }); + } + } + }); + + return counts; }, countCategory(category_id) { diff --git a/test/javascripts/models/topic-tracking-state-test.js b/test/javascripts/models/topic-tracking-state-test.js index 709928c9329..ee6c0c0e4e5 100644 --- a/test/javascripts/models/topic-tracking-state-test.js +++ b/test/javascripts/models/topic-tracking-state-test.js @@ -14,6 +14,56 @@ QUnit.module("model:topic-tracking-state", { } }); +QUnit.test("tag counts", function(assert) { + const state = TopicTrackingState.create(); + + state.loadStates([ + { + topic_id: 1, + last_read_post_number: null, + tags: ["foo", "new"] + }, + { + topic_id: 2, + last_read_post_number: null, + tags: ["new"] + }, + { + topic_id: 3, + last_read_post_number: null, + tags: ["random"] + }, + { + topic_id: 4, + last_read_post_number: 1, + highest_post_number: 7, + tags: ["unread"], + notification_level: NotificationLevels.TRACKING + }, + { + topic_id: 5, + last_read_post_number: 1, + highest_post_number: 7, + tags: ["bar", "unread"], + notification_level: NotificationLevels.TRACKING + }, + { + topic_id: 6, + last_read_post_number: 1, + highest_post_number: 7, + tags: null, + notification_level: NotificationLevels.TRACKING + } + ]); + + const states = state.countTags(["new", "unread"]); + + assert.equal(states["new"].newCount, 2, "new counts"); + assert.equal(states["new"].unreadCount, 0, "new counts"); + assert.equal(states["unread"].unreadCount, 2, "unread counts"); + assert.equal(states["unread"].newCount, 0, "unread counts"); +}); + QUnit.test("sync", function(assert) { const state = TopicTrackingState.create(); state.states["t111"] = { last_read_post_number: null };