FIX: Muted tags are respected by TopicTrackingState (#8467)
When the tag is muted and topic contains that tag, we should not mark that message as NEW. There are 3 possible settings which site admin can set. remove_muted_tags_from_latest - always It means that if the topic got at least one muted tag, we should not mark that topic as NEW remove_muted_tags_from_latest - only muted Similar to above, however, if at least one tag is not muted, the topic is marked as NEW remove_muted_tags_from_latest - never Basically, mute tag setting is ignored and all topics are set as NEW
This commit is contained in:
parent
6740e08caa
commit
81c7d6a462
|
@ -31,6 +31,18 @@ function isUnseen(topic) {
|
|||
return !topic.is_seen;
|
||||
}
|
||||
|
||||
function hasMutedTags(topicTagIds, mutedTagIds) {
|
||||
if (!mutedTagIds || !topicTagIds) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
(Discourse.SiteSettings.remove_muted_tags_from_latest === "always" &&
|
||||
topicTagIds.any(tagId => mutedTagIds.includes(tagId))) ||
|
||||
(Discourse.SiteSettings.remove_muted_tags_from_latest === "only_muted" &&
|
||||
topicTagIds.every(tagId => mutedTagIds.includes(tagId)))
|
||||
);
|
||||
}
|
||||
|
||||
const TopicTrackingState = EmberObject.extend({
|
||||
messageCount: 0,
|
||||
|
||||
|
@ -60,6 +72,13 @@ const TopicTrackingState = EmberObject.extend({
|
|||
}
|
||||
}
|
||||
|
||||
if (["new_topic", "latest"].includes(data.message_type)) {
|
||||
const mutedTagIds = User.currentProp("muted_tag_ids");
|
||||
if (hasMutedTags(data.payload.topic_tag_ids, mutedTagIds)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// fill parent_category_id we need it for counting new/unread
|
||||
if (data.payload && data.payload.category_id) {
|
||||
var category = Category.findById(data.payload.category_id);
|
||||
|
|
|
@ -33,7 +33,8 @@ class TopicTrackingState
|
|||
created_at: topic.created_at,
|
||||
topic_id: topic.id,
|
||||
category_id: topic.category_id,
|
||||
archetype: topic.archetype
|
||||
archetype: topic.archetype,
|
||||
topic_tag_ids: topic.tags.pluck(:id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +53,8 @@ class TopicTrackingState
|
|||
payload: {
|
||||
bumped_at: topic.bumped_at,
|
||||
category_id: topic.category_id,
|
||||
archetype: topic.archetype
|
||||
archetype: topic.archetype,
|
||||
topic_tag_ids: topic.tags.pluck(:id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,7 +184,8 @@ class TopicTrackingState
|
|||
skip_order: true,
|
||||
staff: user.staff?,
|
||||
admin: user.admin?,
|
||||
user: user
|
||||
user: user,
|
||||
muted_tag_ids: muted_tag_ids(user)
|
||||
)
|
||||
|
||||
sql << "\nUNION ALL\n\n"
|
||||
|
@ -194,7 +197,8 @@ class TopicTrackingState
|
|||
staff: user.staff?,
|
||||
filter_old_unread: true,
|
||||
admin: user.admin?,
|
||||
user: user
|
||||
user: user,
|
||||
muted_tag_ids: muted_tag_ids(user)
|
||||
)
|
||||
|
||||
DB.query(
|
||||
|
@ -205,6 +209,10 @@ class TopicTrackingState
|
|||
)
|
||||
end
|
||||
|
||||
def self.muted_tag_ids(user)
|
||||
TagUser.lookup(user, :muted).pluck(:tag_id)
|
||||
end
|
||||
|
||||
def self.report_raw_sql(opts = nil)
|
||||
opts ||= {}
|
||||
|
||||
|
@ -268,6 +276,19 @@ class TopicTrackingState
|
|||
"(topics.visible #{append}) AND"
|
||||
end
|
||||
|
||||
tags_filter =
|
||||
if opts[:muted_tag_ids].present? && SiteSetting.remove_muted_tags_from_latest == 'always'
|
||||
<<~SQL
|
||||
NOT ((select array_agg(tag_id) from topic_tags where topic_tags.topic_id = topics.id) && ARRAY[#{opts[:muted_tag_ids].join(',')}]) AND
|
||||
SQL
|
||||
elsif opts[:muted_tag_ids].present? && SiteSetting.remove_muted_tags_from_latest == 'only_muted'
|
||||
<<~SQL
|
||||
NOT ((select array_agg(tag_id) from topic_tags where topic_tags.topic_id = topics.id) <@ ARRAY[#{opts[:muted_tag_ids].join(',')}]) AND
|
||||
SQL
|
||||
else
|
||||
""
|
||||
end
|
||||
|
||||
sql = +<<~SQL
|
||||
SELECT #{select}
|
||||
FROM topics
|
||||
|
@ -282,6 +303,7 @@ class TopicTrackingState
|
|||
topics.archetype <> 'private_message' AND
|
||||
((#{unread}) OR (#{new})) AND
|
||||
#{visibility_filter}
|
||||
#{tags_filter}
|
||||
topics.deleted_at IS NULL AND
|
||||
#{category_filter}
|
||||
(category_users.id IS NULL OR
|
||||
|
|
|
@ -27,6 +27,7 @@ class CurrentUserSerializer < BasicUserSerializer
|
|||
:redirected_to_top,
|
||||
:custom_fields,
|
||||
:muted_category_ids,
|
||||
:muted_tag_ids,
|
||||
:dismissed_banner_key,
|
||||
:is_anonymous,
|
||||
:reviewable_count,
|
||||
|
@ -169,6 +170,10 @@ class CurrentUserSerializer < BasicUserSerializer
|
|||
CategoryUser.lookup(object, :muted).pluck(:category_id)
|
||||
end
|
||||
|
||||
def muted_tag_ids
|
||||
TagUser.lookup(object, :muted).pluck(:tag_id)
|
||||
end
|
||||
|
||||
def ignored_users
|
||||
IgnoredUser.where(user: object.id).joins(:ignored_user).pluck(:username)
|
||||
end
|
||||
|
|
|
@ -353,6 +353,77 @@ describe TopicTrackingState do
|
|||
expect(report.length).to eq(1)
|
||||
end
|
||||
|
||||
context 'muted tags' do
|
||||
it "remove_muted_tags_from_latest is set to always" do
|
||||
SiteSetting.remove_muted_tags_from_latest = 'always'
|
||||
user = Fabricate(:user)
|
||||
tag1 = Fabricate(:tag)
|
||||
tag2 = Fabricate(:tag)
|
||||
Fabricate(:topic_tag, tag: tag1, topic: topic)
|
||||
Fabricate(:topic_tag, tag: tag2, topic: topic)
|
||||
post
|
||||
|
||||
report = TopicTrackingState.report(user)
|
||||
expect(report.length).to eq(1)
|
||||
|
||||
TagUser.create!(user_id: user.id,
|
||||
notification_level: TagUser.notification_levels[:muted],
|
||||
tag_id: tag1.id
|
||||
)
|
||||
|
||||
report = TopicTrackingState.report(user)
|
||||
expect(report.length).to eq(0)
|
||||
end
|
||||
|
||||
it "remove_muted_tags_from_latest is set to only_muted" do
|
||||
SiteSetting.remove_muted_tags_from_latest = 'only_muted'
|
||||
user = Fabricate(:user)
|
||||
tag1 = Fabricate(:tag)
|
||||
tag2 = Fabricate(:tag)
|
||||
Fabricate(:topic_tag, tag: tag1, topic: topic)
|
||||
Fabricate(:topic_tag, tag: tag2, topic: topic)
|
||||
post
|
||||
|
||||
report = TopicTrackingState.report(user)
|
||||
expect(report.length).to eq(1)
|
||||
|
||||
TagUser.create!(user_id: user.id,
|
||||
notification_level: TagUser.notification_levels[:muted],
|
||||
tag_id: tag1.id
|
||||
)
|
||||
|
||||
report = TopicTrackingState.report(user)
|
||||
expect(report.length).to eq(1)
|
||||
|
||||
TagUser.create!(user_id: user.id,
|
||||
notification_level: TagUser.notification_levels[:muted],
|
||||
tag_id: tag2.id
|
||||
)
|
||||
|
||||
report = TopicTrackingState.report(user)
|
||||
expect(report.length).to eq(0)
|
||||
end
|
||||
|
||||
it "remove_muted_tags_from_latest is set to never" do
|
||||
SiteSetting.remove_muted_tags_from_latest = 'never'
|
||||
user = Fabricate(:user)
|
||||
tag1 = Fabricate(:tag)
|
||||
Fabricate(:topic_tag, tag: tag1, topic: topic)
|
||||
post
|
||||
|
||||
report = TopicTrackingState.report(user)
|
||||
expect(report.length).to eq(1)
|
||||
|
||||
TagUser.create!(user_id: user.id,
|
||||
notification_level: TagUser.notification_levels[:muted],
|
||||
tag_id: tag1.id
|
||||
)
|
||||
|
||||
report = TopicTrackingState.report(user)
|
||||
expect(report.length).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
it "correctly handles seen categories" do
|
||||
user = Fabricate(:user)
|
||||
post
|
||||
|
|
|
@ -68,6 +68,25 @@ RSpec.describe CurrentUserSerializer do
|
|||
end
|
||||
end
|
||||
|
||||
context "#muted_tag_ids" do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:tag) { Fabricate(:tag) }
|
||||
let!(:tag_user) do
|
||||
TagUser.create!(user_id: user.id,
|
||||
notification_level: TagUser.notification_levels[:muted],
|
||||
tag_id: tag.id
|
||||
)
|
||||
end
|
||||
let :serializer do
|
||||
CurrentUserSerializer.new(user, scope: Guardian.new, root: false)
|
||||
end
|
||||
|
||||
it 'include muted tag ids' do
|
||||
payload = serializer.as_json
|
||||
expect(payload[:muted_tag_ids]).to eq([tag.id])
|
||||
end
|
||||
end
|
||||
|
||||
context "#second_factor_enabled" do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
let :serializer do
|
||||
|
|
Loading…
Reference in New Issue