FEATURE: allow user to override watched_precedence_over_muted setting (#22340)

Recently, site setting watched_precedence_over_muted was introduced - https://github.com/discourse/discourse/pull/22252

In this PR, we are allowing users to override it. The option is only displayed when the user has watched categories and muted tags, or vice versa.
This commit is contained in:
Krzysztof Kotlarek 2023-07-04 15:08:29 +10:00 committed by GitHub
parent 82d6420e31
commit 134dcdd63a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 107 additions and 28 deletions

View File

@ -101,6 +101,20 @@ export default class extends Controller {
)
.filter((t) => t);
}
@computed(
"model.watchedCategories",
"model.mutedCategories",
"model.watched_tags.[]",
"model.muted_tags.[]"
)
get showMutePrecedenceSetting() {
return (
(this.model.watchedCategories?.length > 0 &&
this.model.muted_tags?.length > 0) ||
(this.model.watched_tags?.length > 0 &&
this.model.mutedCategories?.length > 0)
);
}
@computed(
"model.watchedCategories",
@ -147,6 +161,7 @@ export default class extends Controller {
"watched_category_ids",
"tracked_category_ids",
"watched_first_post_category_ids",
"watched_precedence_over_muted",
];
if (this.siteSettings.tagging_enabled) {

View File

@ -131,6 +131,7 @@ let userOptionFields = [
"bookmark_auto_delete_preference",
"sidebar_link_to_filtered_list",
"sidebar_show_count_of_new_items",
"watched_precedence_over_muted",
];
export function addSaveableUserOptionField(fieldName) {

View File

@ -72,6 +72,15 @@
/>
</div>
</div>
{{#if this.showMutePrecedenceSetting}}
<div class="control-group user-preferences__watched-precedence-over-muted">
<PreferenceCheckbox
data-setting-name="watched-precedence-over-muted"
@labelKey="user.watched_precedence_over_muted"
@checked={{this.model.user_option.watched_precedence_over_muted}}
/>
</div>
{{/if}}
{{#if this.canSave}}
<SaveControls

View File

@ -1811,6 +1811,14 @@ class User < ActiveRecord::Base
in_any_groups?(SiteSetting.experimental_search_menu_groups_map)
end
def watched_precedence_over_muted
if user_option.watched_precedence_over_muted.nil?
SiteSetting.watched_precedence_over_muted
else
user_option.watched_precedence_over_muted
end
end
protected
def badge_grant

View File

@ -289,6 +289,7 @@ end
# chat_header_indicator_preference :integer default(0), not null
# sidebar_link_to_filtered_list :boolean default(FALSE), not null
# sidebar_show_count_of_new_items :boolean default(FALSE), not null
# watched_precedence_over_muted :boolean
#
# Indexes
#

View File

@ -38,7 +38,8 @@ class UserOptionSerializer < ApplicationSerializer
:oldest_search_log_date,
:seen_popups,
:sidebar_link_to_filtered_list,
:sidebar_show_count_of_new_items
:sidebar_show_count_of_new_items,
:watched_precedence_over_muted
def auto_track_topics_after_msecs
object.auto_track_topics_after_msecs || SiteSetting.default_other_auto_track_topics_after_msecs

View File

@ -200,9 +200,7 @@ class PostAlerter
DiscourseEvent.trigger(:post_alerter_before_post, post, new_record, notified)
if !SiteSetting.watched_precedence_over_muted
notified = notified + category_or_tag_muters(post.topic)
end
notified = notified + category_or_tag_muters(post.topic)
if new_record
if post.topic.private_message?
@ -275,7 +273,12 @@ class PostAlerter
UNION
SELECT user_id FROM tag_users tu JOIN topic_tags tt ON tt.tag_id = tu.tag_id AND tt.topic_id = #{topic.id} AND tu.notification_level = #{TagUser.notification_levels[:muted]}
SQL
User.where("id IN (#{user_ids_sql})")
User
.where("id IN (#{user_ids_sql})")
.joins("LEFT JOIN user_options ON user_options.user_id = users.id")
.where(
"user_options.watched_precedence_over_muted IS false OR (user_options.watched_precedence_over_muted IS NULL AND #{!SiteSetting.watched_precedence_over_muted})",
)
end
def notify_first_post_watchers(post, user_ids, notified = nil)

View File

@ -51,6 +51,7 @@ class UserUpdater
bookmark_auto_delete_preference
sidebar_link_to_filtered_list
sidebar_show_count_of_new_items
watched_precedence_over_muted
]
NOTIFICATION_SCHEDULE_ATTRS = -> do

View File

@ -1248,6 +1248,7 @@ en:
watched_first_post_categories_instructions: "You will be notified of the first post in each new topic in these categories."
watched_first_post_tags: "Watching First Post"
watched_first_post_tags_instructions: "You will be notified of the first post in each new topic with these tags."
watched_precedence_over_muted: "Notify me about topics in categories or tags Im watching that also belong to one I have muted"
muted_categories: "Muted"
muted_categories_instructions: "You will not be notified of anything about new topics in these categories, and they will not appear on the categories or latest pages."

View File

@ -0,0 +1,6 @@
# frozen_string_literal: true
class AddWatchedPrecedenceOverMutedToUserOptions < ActiveRecord::Migration[7.0]
def change
add_column :user_options, :watched_precedence_over_muted, :boolean
end
end

View File

@ -898,7 +898,7 @@ class TopicQuery
if user
watched_tag_ids =
if SiteSetting.watched_precedence_over_muted
if user.watched_precedence_over_muted
TagUser
.where(user: user)
.where("notification_level >= ?", TopicUser.notification_levels[:watching])
@ -981,6 +981,19 @@ class TopicQuery
end
end
query_params = { tag_ids: muted_tag_ids }
if user && !opts[:skip_categories]
query_params[:regular] = CategoryUser.notification_levels[:regular]
query_params[:watching_or_infinite] = if user.watched_precedence_over_muted ||
SiteSetting.watched_precedence_over_muted
CategoryUser.notification_levels[:watching]
else
99
end
end
if SiteSetting.remove_muted_tags_from_latest == "always"
list =
list.where(
@ -991,16 +1004,7 @@ class TopicQuery
WHERE tt.tag_id IN (:tag_ids)
AND tt.topic_id = topics.id
#{user && !opts[:skip_categories] ? "AND COALESCE(category_users.notification_level, :regular) < :watching_or_infinite" : ""})",
tag_ids: muted_tag_ids,
regular: CategoryUser.notification_levels[:regular],
watching_or_infinite:
(
if SiteSetting.watched_precedence_over_muted
CategoryUser.notification_levels[:watching]
else
99
end
),
query_params,
)
else
list =
@ -1013,16 +1017,7 @@ class TopicQuery
AND tt.topic_id = topics.id)
#{user && !opts[:skip_categories] ? "OR COALESCE(category_users.notification_level, :regular) >= :watching_or_infinite" : ""}
) OR NOT EXISTS (SELECT 1 FROM topic_tags tt WHERE tt.topic_id = topics.id)",
tag_ids: muted_tag_ids,
regular: CategoryUser.notification_levels[:regular],
watching_or_infinite:
(
if SiteSetting.watched_precedence_over_muted
CategoryUser.notification_levels[:watching]
else
99
end
),
query_params,
)
end
end

View File

@ -2160,5 +2160,18 @@ RSpec.describe TopicQuery do
expect(query.topics.map(&:id)).to contain_exactly(topic.id)
end
end
context "when disabled but overridden by user" do
it "returns topics even if category or tag is muted but another tag or category is watched" do
SiteSetting.watched_precedence_over_muted = false
user.user_option.update!(watched_precedence_over_muted: true)
query = TopicQuery.new(user).list_latest
expect(query.topics.map(&:id)).to contain_exactly(
topic.id,
topic_in_watched_category_and_muted_tag.id,
topic_in_muted_category_and_watched_tag.id,
)
end
end
end
end

View File

@ -777,6 +777,9 @@
"sidebar_show_count_of_new_items": {
"type": "boolean"
},
"watched_precedence_over_muted": {
"type": ["boolean", "null"]
},
"seen_popups": {
"type": ["array", "null"]
}

View File

@ -1918,7 +1918,7 @@ RSpec.describe PostAlerter do
)
end
it "adds notification when watched_precedence_over_mute setting is true" do
it "adds notification when watched_precedence_over_muted setting is true" do
SiteSetting.watched_precedence_over_muted = true
expect {
PostAlerter.post_created(topic_with_muted_tag_and_watched_category.posts.first)
@ -1928,7 +1928,18 @@ RSpec.describe PostAlerter do
}.to change { Notification.count }.by(1)
end
it "does not add notification when watched_precedence_over_mute setting is false" do
it "respects user option even if watched_precedence_over_muted site setting is true" do
SiteSetting.watched_precedence_over_muted = true
user.user_option.update!(watched_precedence_over_muted: false)
expect {
PostAlerter.post_created(topic_with_muted_tag_and_watched_category.posts.first)
}.not_to change { Notification.count }
expect {
PostAlerter.post_created(topic_with_muted_category_and_watched_tag.posts.first)
}.not_to change { Notification.count }
end
it "does not add notification when watched_precedence_over_muted setting is false" do
SiteSetting.watched_precedence_over_muted = false
expect {
PostAlerter.post_created(topic_with_muted_tag_and_watched_category.posts.first)
@ -1940,6 +1951,17 @@ RSpec.describe PostAlerter do
Notification.count
}.by(1)
end
it "respects user option even if watched_precedence_over_muted site setting is false" do
SiteSetting.watched_precedence_over_muted = false
user.user_option.update!(watched_precedence_over_muted: true)
expect {
PostAlerter.post_created(topic_with_muted_tag_and_watched_category.posts.first)
}.to change { Notification.count }.by(1)
expect {
PostAlerter.post_created(topic_with_muted_category_and_watched_tag.posts.first)
}.to change { Notification.count }.by(1)
end
end
context "with on change" do