FEATURE: Per-category default slow mode duration for topics.

FEATURE: Per-category default slow mode duration for topics.

When configured, all topics in the category inherits the slow mode duration from the category’s default.

Note that currently there is no way to remove the slow mode from the topics once it has been set.

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 bfcfa19..9394736 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 af65076..940bb5b 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 78c3414..8dc72c5 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 @@
     </label>
   </section>
 
+  <section class="field default-slow-mode">
+    <div class="control-group">
+      <label for="category-default-slow-mode">
+        {{i18n "category.default_slow_mode"}}
+      </label>
+      <div class="category-default-slow-mode-seconds">
+        {{relative-time-picker
+            id="category-default-slow-mode"
+            durationMinutes=category.defaultSlowModeMinutes
+            hiddenIntervals=hiddenRelativeIntervals
+            onChange=(action "onDefaultSlowModeDurationChange")}}
+      </div>
+    </div>
+  </section>
+
   <section class="field auto-close">
     <div class="control-group">
       <label for="topic-auto-close">
diff --git a/app/assets/stylesheets/common/base/edit-category.scss b/app/assets/stylesheets/common/base/edit-category.scss
index f454f49..0fcbd51 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 b60b1a2..c22d6be 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 73e8f6e..d36d490 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 5150a28..a618b56 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 fe42e11..0efe3f5 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 0a5974c..02265ea 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 0000000..dca44c3
--- /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 87aca67..5382380 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 94a8d50..f15c082 100644
--- a/spec/requests/api/schemas/json/category_update_response.json

[... diff too long, it was truncated ...]

GitHub sha: 7162ecfb04cca5f8778b7cf9cdbbe524c3132b43

This commit appears in #13666 which was approved by techAPJ. It was merged by tgxworld.