diff --git a/app/assets/javascripts/discourse/app/components/edit-category-settings.js b/app/assets/javascripts/discourse/app/components/edit-category-settings.js index bfcfa19cd5e..93947368f3e 100644 --- a/app/assets/javascripts/discourse/app/components/edit-category-settings.js +++ b/app/assets/javascripts/discourse/app/components/edit-category-settings.js @@ -138,4 +138,10 @@ export default buildCategoryPanel("settings", { let hours = minutes ? minutes / 60 : null; this.set("category.auto_close_hours", hours); }, + + @action + onDefaultSlowModeDurationChange(minutes) { + let seconds = minutes ? minutes * 60 : null; + this.set("category.default_slow_mode_seconds", seconds); + }, }); diff --git a/app/assets/javascripts/discourse/app/models/category.js b/app/assets/javascripts/discourse/app/models/category.js index af65076dba4..940bb5ba39e 100644 --- a/app/assets/javascripts/discourse/app/models/category.js +++ b/app/assets/javascripts/discourse/app/models/category.js @@ -177,6 +177,11 @@ const Category = RestModel.extend({ return topicCount; }, + @discourseComputed("default_slow_mode_seconds") + defaultSlowModeMinutes(seconds) { + return seconds ? seconds / 60 : null; + }, + save() { const id = this.id; const url = id ? `/categories/${id}` : "/categories"; @@ -193,6 +198,7 @@ const Category = RestModel.extend({ auto_close_based_on_last_post: this.get( "auto_close_based_on_last_post" ), + default_slow_mode_seconds: this.default_slow_mode_seconds, position: this.position, email_in: this.email_in, email_in_allow_strangers: this.email_in_allow_strangers, diff --git a/app/assets/javascripts/discourse/app/templates/components/edit-category-settings.hbs b/app/assets/javascripts/discourse/app/templates/components/edit-category-settings.hbs index 78c3414a364..8dc72c57022 100644 --- a/app/assets/javascripts/discourse/app/templates/components/edit-category-settings.hbs +++ b/app/assets/javascripts/discourse/app/templates/components/edit-category-settings.hbs @@ -116,6 +116,21 @@ + + + + {{i18n "category.default_slow_mode"}} + + + {{relative-time-picker + id="category-default-slow-mode" + durationMinutes=category.defaultSlowModeMinutes + hiddenIntervals=hiddenRelativeIntervals + onChange=(action "onDefaultSlowModeDurationChange")}} + + + + diff --git a/app/assets/stylesheets/common/base/edit-category.scss b/app/assets/stylesheets/common/base/edit-category.scss index f454f49b80e..0fcbd518230 100644 --- a/app/assets/stylesheets/common/base/edit-category.scss +++ b/app/assets/stylesheets/common/base/edit-category.scss @@ -158,7 +158,8 @@ div.edit-category { padding: 0 1.5em 2em 0; } - .category-topic-auto-close-hours { + .category-topic-auto-close-hours, + .category-default-slow-mode-seconds { width: 200px; } } diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb index b60b1a2956b..c22d6be7e31 100644 --- a/app/controllers/categories_controller.rb +++ b/app/controllers/categories_controller.rb @@ -302,6 +302,7 @@ class CategoriesController < ApplicationController :mailinglist_mirror, :all_topics_wiki, :allow_unlimited_owner_edits_on_first_post, + :default_slow_mode_seconds, :parent_category_id, :auto_close_hours, :auto_close_based_on_last_post, diff --git a/app/models/category.rb b/app/models/category.rb index 73e8f6ee8f9..d36d490ace9 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -1027,6 +1027,7 @@ end # read_only_banner :string # default_list_filter :string(20) default("all") # allow_unlimited_owner_edits_on_first_post :boolean default(FALSE), not null +# default_slow_mode_seconds :integer # # Indexes # diff --git a/app/models/topic.rb b/app/models/topic.rb index 5150a289523..a618b569232 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -334,6 +334,7 @@ class Topic < ActiveRecord::Base if category_id_changed? || new_record? inherit_auto_close_from_category + inherit_slow_mode_from_category end end @@ -1251,6 +1252,12 @@ class Topic < ActiveRecord::Base end end + def inherit_slow_mode_from_category + if self.category&.default_slow_mode_seconds + self.slow_mode_seconds = self.category&.default_slow_mode_seconds + end + end + def inherit_auto_close_from_category(timer_type: :close) auto_close_hours = self.category&.auto_close_hours diff --git a/app/serializers/category_serializer.rb b/app/serializers/category_serializer.rb index fe42e1172a7..0efe3f5b5b6 100644 --- a/app/serializers/category_serializer.rb +++ b/app/serializers/category_serializer.rb @@ -20,7 +20,8 @@ class CategorySerializer < SiteCategorySerializer :custom_fields, :topic_featured_link_allowed, :search_priority, - :reviewable_by_group_name + :reviewable_by_group_name, + :default_slow_mode_seconds def reviewable_by_group_name object.reviewable_by_group.name diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 0a5974c9fee..02265ea3ce5 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -3217,6 +3217,7 @@ en: position_disabled: "Categories will be displayed in order of activity. To control the order of categories in lists, " position_disabled_click: 'enable the "fixed category positions" setting.' minimum_required_tags: "Minimum number of tags required in a topic:" + default_slow_mode: 'Enable "Slow Mode" for new topics in this category.' parent: "Parent Category" num_auto_bump_daily: "Number of open topics to automatically bump daily:" navigate_to_first_post_after_read: "Navigate to first post after topics are read" diff --git a/db/migrate/20210702204007_add_default_auto_close_seconds_to_category.rb b/db/migrate/20210702204007_add_default_auto_close_seconds_to_category.rb new file mode 100644 index 00000000000..dca44c36b2f --- /dev/null +++ b/db/migrate/20210702204007_add_default_auto_close_seconds_to_category.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddDefaultAutoCloseSecondsToCategory < ActiveRecord::Migration[6.1] + def change + add_column :categories, :default_slow_mode_seconds, :integer + end +end diff --git a/spec/requests/api/schemas/json/category_create_response.json b/spec/requests/api/schemas/json/category_create_response.json index 87aca679ffa..53823807ddf 100644 --- a/spec/requests/api/schemas/json/category_create_response.json +++ b/spec/requests/api/schemas/json/category_create_response.json @@ -170,6 +170,12 @@ "allow_unlimited_owner_edits_on_first_post": { "type": "boolean" }, + "default_slow_mode_seconds": { + "type": [ + "string", + "null" + ] + }, "group_permissions": { "type": "array", "items": [ @@ -274,6 +280,7 @@ "auto_close_hours", "auto_close_based_on_last_post", "allow_unlimited_owner_edits_on_first_post", + "default_slow_mode_seconds", "group_permissions", "email_in", "email_in_allow_strangers", diff --git a/spec/requests/api/schemas/json/category_update_response.json b/spec/requests/api/schemas/json/category_update_response.json index 94a8d50708f..f15c082677f 100644 --- a/spec/requests/api/schemas/json/category_update_response.json +++ b/spec/requests/api/schemas/json/category_update_response.json @@ -173,6 +173,12 @@ "allow_unlimited_owner_edits_on_first_post": { "type": "boolean" }, + "default_slow_mode_seconds": { + "type": [ + "string", + "null" + ] + }, "group_permissions": { "type": "array", "items": [ @@ -277,6 +283,7 @@ "auto_close_hours", "auto_close_based_on_last_post", "allow_unlimited_owner_edits_on_first_post", + "default_slow_mode_seconds", "group_permissions", "email_in", "email_in_allow_strangers",