FEATURE: support to mute all categories by default. (#8295)
Instead of enabling `suppress_from_latest` setting on many categories now we can enable `mute_all_categories_by_default` site setting. Then users should opt-in to categories for them to appear in the latest and categories pages.
This commit is contained in:
parent
deec2cf578
commit
ba5b78a348
|
@ -27,14 +27,16 @@
|
|||
</div>
|
||||
<div class="instructions">{{i18n 'user.watched_first_post_categories_instructions'}}</div>
|
||||
|
||||
<div class="controls tracking-controls">
|
||||
<label>{{d-icon "d-muted"}} {{i18n 'user.muted_categories'}}</label>
|
||||
{{#if canSee}}
|
||||
<a class="show-tracking" href="{{unbound model.mutedTopicsPath}}">{{i18n 'user.tracked_topics_link'}}</a>
|
||||
{{/if}}
|
||||
{{category-selector categories=model.mutedCategories blacklist=selectedCategories}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n (if hideMutedTags 'user.muted_categories_instructions' 'user.muted_categories_instructions_dont_hide')}}</div>
|
||||
{{#unless siteSettings.mute_all_categories_by_default}}
|
||||
<div class="controls tracking-controls">
|
||||
<label>{{d-icon "d-muted"}} {{i18n 'user.muted_categories'}}</label>
|
||||
{{#if canSee}}
|
||||
<a class="show-tracking" href="{{unbound model.mutedTopicsPath}}">{{i18n 'user.tracked_topics_link'}}</a>
|
||||
{{/if}}
|
||||
{{category-selector categories=model.mutedCategories blacklist=selectedCategories}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n (if hideMutedTags 'user.muted_categories_instructions' 'user.muted_categories_instructions_dont_hide')}}</div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
|
||||
{{plugin-outlet name="user-preferences-categories" args=(hash model=model save=(action "save"))}}
|
||||
|
|
|
@ -173,7 +173,7 @@ export default createWidget("hamburger-menu", {
|
|||
listCategories() {
|
||||
const maxCategoriesToDisplay = this.siteSettings
|
||||
.header_dropdown_category_count;
|
||||
let categories = this.site.get("categoriesByCount");
|
||||
let categories = [];
|
||||
|
||||
if (this.currentUser) {
|
||||
const allCategories = this.site
|
||||
|
@ -203,6 +203,10 @@ export default createWidget("hamburger-menu", {
|
|||
.filter(c => !categories.includes(c))
|
||||
.sort((a, b) => b.topic_count - a.topic_count)
|
||||
);
|
||||
} else {
|
||||
categories = this.site
|
||||
.get("categoriesByCount")
|
||||
.filter(c => c.notification_level !== NotificationLevels.MUTED);
|
||||
}
|
||||
|
||||
if (!this.siteSettings.allow_uncategorized_topics) {
|
||||
|
|
|
@ -92,16 +92,12 @@ class CategoryList
|
|||
|
||||
@categories = @categories.to_a
|
||||
|
||||
category_user = {}
|
||||
default_notification_level = nil
|
||||
unless @guardian.anonymous?
|
||||
category_user = Hash[*CategoryUser.where(user: @guardian.user).pluck(:category_id, :notification_level).flatten]
|
||||
default_notification_level = CategoryUser.notification_levels[:regular]
|
||||
end
|
||||
notification_levels = CategoryUser.notification_levels_for(@guardian)
|
||||
default_notification_level = CategoryUser.default_notification_level
|
||||
|
||||
allowed_topic_create = Set.new(Category.topic_create_allowed(@guardian).pluck(:id))
|
||||
@categories.each do |category|
|
||||
category.notification_level = category_user[category.id] || default_notification_level
|
||||
category.notification_level = notification_levels[category.id] || default_notification_level
|
||||
category.permission = CategoryGroup.permission_types[:full] if allowed_topic_create.include?(category.id)
|
||||
category.has_children = category.subcategories.present?
|
||||
end
|
||||
|
|
|
@ -197,6 +197,26 @@ class CategoryUser < ActiveRecord::Base
|
|||
SQL
|
||||
end
|
||||
|
||||
def self.default_notification_level
|
||||
SiteSetting.mute_all_categories_by_default ? notification_levels[:muted] : notification_levels[:regular]
|
||||
end
|
||||
|
||||
def self.notification_levels_for(guardian)
|
||||
if guardian.anonymous?
|
||||
notification_levels = [
|
||||
SiteSetting.default_categories_watching.split("|"),
|
||||
SiteSetting.default_categories_tracking.split("|"),
|
||||
SiteSetting.default_categories_watching_first_post.split("|"),
|
||||
].flatten.map { |id| [id.to_i, 1] }
|
||||
|
||||
notification_levels += SiteSetting.default_categories_muted.split("|").map { |id| [id.to_i, 0] }
|
||||
else
|
||||
notification_levels = CategoryUser.where(user: guardian.user).pluck(:category_id, :notification_level)
|
||||
end
|
||||
|
||||
Hash[*notification_levels.flatten]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# == Schema Information
|
||||
|
|
|
@ -55,15 +55,11 @@ class Site
|
|||
|
||||
by_id = {}
|
||||
|
||||
category_user = {}
|
||||
unless @guardian.anonymous?
|
||||
category_user = Hash[*CategoryUser.where(user: @guardian.user).pluck(:category_id, :notification_level).flatten]
|
||||
end
|
||||
|
||||
regular = CategoryUser.notification_levels[:regular]
|
||||
notification_levels = CategoryUser.notification_levels_for(@guardian)
|
||||
default_notification_level = CategoryUser.default_notification_level
|
||||
|
||||
categories.each do |category|
|
||||
category.notification_level = category_user[category.id] || regular
|
||||
category.notification_level = notification_levels[category.id] || default_notification_level
|
||||
category.permission = CategoryGroup.permission_types[:full] if allowed_topic_create&.include?(category.id) || @guardian.is_admin?
|
||||
category.has_children = with_children.include?(category.id)
|
||||
by_id[category.id] = category
|
||||
|
|
|
@ -2067,6 +2067,7 @@ en:
|
|||
default_categories_tracking: "List of categories that are tracked by default."
|
||||
default_categories_muted: "List of categories that are muted by default."
|
||||
default_categories_watching_first_post: "List of categories in which first post in each new topic will be watched by default."
|
||||
mute_all_categories_by_default: "Set the default notification level of all the categories to muted. Require users opt-in to categories for them to appear in 'latest' and 'categories' pages. If you wish to amend the defaults for anonymous users set 'default_categories_' settings."
|
||||
|
||||
default_tags_watching: "List of tags that are watched by default."
|
||||
default_tags_tracking: "List of tags that are tracked by default."
|
||||
|
|
|
@ -2022,6 +2022,9 @@ user_preferences:
|
|||
default_categories_watching_first_post:
|
||||
type: category_list
|
||||
default: ""
|
||||
mute_all_categories_by_default:
|
||||
default: false
|
||||
client: true
|
||||
|
||||
default_tags_watching:
|
||||
type: tag_list
|
||||
|
|
|
@ -869,7 +869,34 @@ class TopicQuery
|
|||
def remove_muted_categories(list, user, opts = nil)
|
||||
category_id = get_category_id(opts[:exclude]) if opts
|
||||
|
||||
if user
|
||||
if SiteSetting.mute_all_categories_by_default
|
||||
if user
|
||||
list = list.references("cu")
|
||||
.where("
|
||||
NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM categories c
|
||||
LEFT OUTER JOIN category_users cu
|
||||
ON c.id = cu.category_id AND cu.user_id = :user_id
|
||||
WHERE c.id = topics.category_id
|
||||
AND c.id <> :category_id
|
||||
AND (COALESCE(cu.notification_level, :muted) = :muted)
|
||||
AND (COALESCE(tu.notification_level, :regular) <= :regular)
|
||||
)", user_id: user.id,
|
||||
muted: CategoryUser.notification_levels[:muted],
|
||||
regular: TopicUser.notification_levels[:regular],
|
||||
category_id: category_id || -1)
|
||||
else
|
||||
category_ids = [
|
||||
SiteSetting.default_categories_watching.split("|"),
|
||||
SiteSetting.default_categories_tracking.split("|"),
|
||||
SiteSetting.default_categories_watching_first_post.split("|")
|
||||
].flatten.map(&:to_i)
|
||||
category_ids << category_id if category_id.present? && category_ids.exclude?(category_id)
|
||||
|
||||
list = list.where("topics.category_id IN (?)", category_ids) if category_ids.present?
|
||||
end
|
||||
elsif user
|
||||
list = list.references("cu")
|
||||
.where("
|
||||
NOT EXISTS (
|
||||
|
|
|
@ -240,6 +240,39 @@ describe TopicQuery do
|
|||
end
|
||||
end
|
||||
|
||||
context 'mute_all_categories_by_default' do
|
||||
fab!(:category) { Fabricate(:category_with_definition) }
|
||||
fab!(:topic) { Fabricate(:topic, category: category) }
|
||||
|
||||
before do
|
||||
SiteSetting.mute_all_categories_by_default = true
|
||||
end
|
||||
|
||||
it 'should remove all topics from new and latest lists by default' do
|
||||
expect(topic_query.list_new.topics.map(&:id)).not_to include(topic.id)
|
||||
expect(topic_query.list_latest.topics.map(&:id)).not_to include(topic.id)
|
||||
end
|
||||
|
||||
it 'should include tracked category topics in new and latest lists' do
|
||||
topic = Fabricate(:topic, category: category)
|
||||
CategoryUser.create!(user_id: user.id,
|
||||
category_id: category.id,
|
||||
notification_level: CategoryUser.notification_levels[:tracking])
|
||||
expect(topic_query.list_new.topics.map(&:id)).to include(topic.id)
|
||||
expect(topic_query.list_latest.topics.map(&:id)).to include(topic.id)
|
||||
end
|
||||
|
||||
it 'should include default watched category topics in latest list for anonymous users' do
|
||||
SiteSetting.default_categories_watching = category.id.to_s
|
||||
expect(TopicQuery.new.list_latest.topics.map(&:id)).to include(topic.id)
|
||||
end
|
||||
|
||||
it 'should include topics when filtered by category' do
|
||||
topic_query = TopicQuery.new(user, category: topic.category_id)
|
||||
expect(topic_query.list_latest.topics.map(&:id)).to include(topic.id)
|
||||
end
|
||||
end
|
||||
|
||||
context 'muted tags' do
|
||||
it 'is removed from new and latest lists' do
|
||||
SiteSetting.tagging_enabled = true
|
||||
|
|
|
@ -65,6 +65,35 @@ describe CategoryList do
|
|||
end
|
||||
end
|
||||
|
||||
context "when mute_all_categories_by_default enabled" do
|
||||
fab!(:category) { Fabricate(:category) }
|
||||
|
||||
before do
|
||||
SiteSetting.mute_all_categories_by_default = true
|
||||
end
|
||||
|
||||
it "removes the category by default" do
|
||||
expect(category_list.categories).not_to include(category)
|
||||
end
|
||||
|
||||
it "returns correct notification level for user tracking category" do
|
||||
CategoryUser.set_notification_level_for_category(user, NotificationLevels.all[:tracking], category.id)
|
||||
notification_level = category_list.categories.find { |c| c.id == category.id }.notification_level
|
||||
expect(notification_level).to eq(CategoryUser.notification_levels[:tracking])
|
||||
end
|
||||
|
||||
it "returns correct notification level in default categories for anonymous" do
|
||||
SiteSetting.default_categories_watching = category.id.to_s
|
||||
notification_level = CategoryList.new(Guardian.new).categories.find { |c| c.id == category.id }.notification_level
|
||||
expect(notification_level).to eq(CategoryUser.notification_levels[:regular])
|
||||
end
|
||||
|
||||
it "removes the default muted categories for anonymous" do
|
||||
SiteSetting.default_categories_muted = category.id.to_s
|
||||
expect(CategoryList.new(Guardian.new).categories).not_to include(category)
|
||||
end
|
||||
end
|
||||
|
||||
context "with a category" do
|
||||
|
||||
fab!(:topic_category) { Fabricate(:category_with_definition, num_featured_topics: 2) }
|
||||
|
@ -114,11 +143,11 @@ describe CategoryList do
|
|||
expect(category.notification_level).to eq(NotificationLevels.all[:watching])
|
||||
end
|
||||
|
||||
it "returns no notication level for anonymous users" do
|
||||
it "returns default notication level for anonymous users" do
|
||||
category_list = CategoryList.new(Guardian.new(nil))
|
||||
category = category_list.categories.find { |c| c.id == topic_category.id }
|
||||
|
||||
expect(category.notification_level).to be_nil
|
||||
expect(category.notification_level).to eq(NotificationLevels.all[:regular])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -41,6 +41,16 @@ describe Site do
|
|||
|
||||
end
|
||||
|
||||
it "returns correct notification level for categories" do
|
||||
category = Fabricate(:category)
|
||||
guardian = Guardian.new
|
||||
expect(Site.new(guardian).categories.last.notification_level).to eq(1)
|
||||
SiteSetting.mute_all_categories_by_default = true
|
||||
expect(Site.new(guardian).categories.last.notification_level).to eq(0)
|
||||
SiteSetting.default_categories_tracking = category.id.to_s
|
||||
expect(Site.new(guardian).categories.last.notification_level).to eq(1)
|
||||
end
|
||||
|
||||
it "omits categories users can not write to from the category list" do
|
||||
category = Fabricate(:category)
|
||||
user = Fabricate(:user)
|
||||
|
|
Loading…
Reference in New Issue