DEV: add countTags to topic tracking state

DEV: add countTags to topic tracking state

This introduces a new core API to get counts per tag from topic tracking state

This API will only be useful if a plugin enable tags in topic tracking state using

TopicTrackingState.include_tags_in_report = true

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 be49ad4..65d1c21 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 709928c..ee6c0c0 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 };

GitHub sha: 82de9c53

1 Like