FEATURE: add tracked filter to topic lists
This adds a special filter to topic lists that will filter to tracked and watched categories.
To use it you can visit:
https://sitename/?filter=tracked
https://sitename/unread?filter=tracked
and so on
Note, we do not include explicitly tracked and watched topics outside of the tracked categories and tags.
We can consider a filter=all_tracked
to cover this edge case.
diff --git a/lib/topic_query.rb b/lib/topic_query.rb
index f030c83..a838e79 100644
--- a/lib/topic_query.rb
+++ b/lib/topic_query.rb
@@ -824,6 +824,33 @@ class TopicQuery
action: action
)
end
+
+ if filter == "tracked"
+ sql = +<<~SQL
+ topics.category_id IN (
+ SELECT cu.category_id FROM category_users cu
+ WHERE cu.user_id = :user_id AND cu.notification_level >= :tracking
+ )
+ SQL
+
+ if SiteSetting.tagging_enabled
+ sql << <<~SQL
+ OR topics.id IN (
+ SELECT tt.topic_id FROM topic_tags tt WHERE tt.tag_id IN (
+ SELECT tu.tag_id
+ FROM tag_users tu
+ WHERE tu.user_id = :user_id AND tu.notification_level >= :tracking
+ )
+ )
+ SQL
+ end
+
+ result = result.where(
+ sql,
+ user_id: @user.id,
+ tracking: NotificationLevels.all[:tracking]
+ )
+ end
end
result = result.where('topics.deleted_at IS NULL') if require_deleted_clause
diff --git a/spec/components/topic_query_spec.rb b/spec/components/topic_query_spec.rb
index 6d97abf..fdfd67d 100644
--- a/spec/components/topic_query_spec.rb
+++ b/spec/components/topic_query_spec.rb
@@ -118,6 +118,39 @@ describe TopicQuery do
end
end
+ context 'tracked' do
+ it "filters tracked topics correctly" do
+ SiteSetting.tagging_enabled = true
+
+ tag = Fabricate(:tag)
+ Fabricate(:topic, tags: [tag])
+ topic2 = Fabricate(:topic)
+
+ query = TopicQuery.new(user, filter: 'tracked').list_latest
+ expect(query.topics.length).to eq(0)
+
+ TagUser.create!(
+ tag_id: tag.id,
+ user_id: user.id,
+ notification_level: NotificationLevels.all[:watching]
+ )
+
+ cu = CategoryUser.create!(
+ category_id: topic2.category_id,
+ user_id: user.id,
+ notification_level: NotificationLevels.all[:regular]
+ )
+
+ query = TopicQuery.new(user, filter: 'tracked').list_latest
+ expect(query.topics.length).to eq(1)
+
+ cu.update!(notification_level: NotificationLevels.all[:tracking])
+
+ query = TopicQuery.new(user, filter: 'tracked').list_latest
+ expect(query.topics.length).to eq(2)
+ end
+ end
+
context 'deleted filter' do
it "filters deleted topics correctly" do
_topic = Fabricate(:topic, deleted_at: 1.year.ago)
GitHub sha: 88dcdf77