diff --git a/app/assets/javascripts/filters.js b/app/assets/javascripts/filters.js
index f080f492a..b8b8d63e1 100644
--- a/app/assets/javascripts/filters.js
+++ b/app/assets/javascripts/filters.js
@@ -54,7 +54,7 @@ $(() => {
const filters = await QPixel.filters();
function template(option) {
- if (option.id == '') { return 'None'; }
+ if (option.id == '') { return 'Default'; }
const filter = filters[option.id];
const name = `${option.text}`;
diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb
index e0e9b0668..c319160f3 100644
--- a/app/controllers/categories_controller.rb
+++ b/app/controllers/categories_controller.rb
@@ -143,7 +143,8 @@ def category_params
params.require(:category).permit(:name, :short_wiki, :tag_set_id, :is_homepage, :min_trust_level, :button_text,
:color_code, :min_view_trust_level, :license_id, :sequence,
:asking_guidance_override, :answering_guidance_override,
- :use_for_hot_posts, :use_for_advertisement, :min_title_length, :min_body_length,
+ :use_for_hot_posts, :use_for_advertisement,
+ :min_title_length, :min_body_length, :default_filter_id,
display_post_types: [], post_type_ids: [], required_tag_ids: [],
topic_tag_ids: [], moderator_tag_ids: [])
end
@@ -165,13 +166,22 @@ def set_list_posts
filter_qualifiers = helpers.params_to_qualifiers
@active_filter = helpers.active_filter
- if filter_qualifiers.blank? && user_signed_in?
- default_filter_id = helpers.default_filter(current_user.id, @category.id)
- default_filter = Filter.find_by(id: default_filter_id)
+ if filter_qualifiers.blank? && @active_filter[:name].blank?
+ if user_signed_in?
+ default_filter_id = helpers.default_filter(current_user.id, @category.id)
+ default_filter = Filter.find_by(id: default_filter_id)
+ default = :user if default_filter.present?
+ end
+
+ if default_filter.nil?
+ default_filter = @category.default_filter
+ default = :category if default_filter.present?
+ end
+
unless default_filter.nil?
filter_qualifiers = helpers.filter_to_qualifiers default_filter
@active_filter = {
- default: true,
+ default: default,
name: default_filter.name,
min_score: default_filter.min_score,
max_score: default_filter.max_score,
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 7b45d9ea6..332933e6d 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -80,7 +80,7 @@ def filter_json(filter)
end
def filters_json
- system_filters = Rails.cache.fetch 'system_filters' do
+ system_filters = Rails.cache.fetch 'default_system_filters', expires_in: 1.day do
User.find(-1).filters.to_h { |filter| [filter.name, filter_json(filter)] }
end
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index c6af23af2..a655eef1f 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -41,7 +41,7 @@ def filter_to_qualifiers(filter)
def active_filter
{
- default: false,
+ default: nil,
name: params[:predefined_filter],
min_score: params[:min_score],
max_score: params[:max_score],
diff --git a/app/models/category.rb b/app/models/category.rb
index 9cdaea765..f5951519c 100644
--- a/app/models/category.rb
+++ b/app/models/category.rb
@@ -9,6 +9,7 @@ class Category < ApplicationRecord
has_many :posts
belongs_to :tag_set
belongs_to :license
+ belongs_to :default_filter, class_name: 'Filter', optional: true
serialize :display_post_types, Array
diff --git a/app/views/categories/_form.html.erb b/app/views/categories/_form.html.erb
index ac507654c..064e2444d 100644
--- a/app/views/categories/_form.html.erb
+++ b/app/views/categories/_form.html.erb
@@ -145,6 +145,13 @@
<%= f.number_field :sequence, class: 'form-element' %>
+
+
+ <%= f.label :default_filter_id, class: 'form-element' %>
+ The default filter for this category, used for anonymous users.
+ <% system_filters = User.find(-1).filters.to_h { |filter| [filter.name, filter.id] } %>
+ <%= f.select :default_filter_id, options_for_select(system_filters, selected: @category.default_filter_id), { include_blank: "No default" } %>
+
diff --git a/app/views/categories/show.html.erb b/app/views/categories/show.html.erb
index c4be90307..7deb5785f 100644
--- a/app/views/categories/show.html.erb
+++ b/app/views/categories/show.html.erb
@@ -52,10 +52,18 @@
Filters (<%= @filtered ? @active_filter[:name] || 'Custom' : 'None' %>)
- <% if @active_filter[:default] == true %>
+ <% if @active_filter[:default] == :user %>
You are currently filtering by <%= @active_filter[:name] %> because it is set as your default for this category
+ <% elsif @active_filter[:default] == :category and not user_signed_in? %>
+
+ You are currently filtering by <%= @active_filter[:name] %> because it is the default for this category
+
+ <% elsif @active_filter[:default] == :category and user_signed_in? %>
+
+ You are currently filtering by <%= @active_filter[:name] %> because it is the default for this category and you do not have a personal default set
+
<% end %>
<%= form_tag request.original_url, method: :get do %>
<%= render 'search/filters' %>
diff --git a/db/migrate/20230627035349_add_default_filter_to_category.rb b/db/migrate/20230627035349_add_default_filter_to_category.rb
new file mode 100644
index 000000000..b6f49a4b4
--- /dev/null
+++ b/db/migrate/20230627035349_add_default_filter_to_category.rb
@@ -0,0 +1,5 @@
+class AddDefaultFilterToCategory < ActiveRecord::Migration[7.0]
+ def change
+ add_reference :categories, :default_filter, foreign_key: { to_table: :filters }, null: true
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 4daf390d7..8fd9d1c32 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -111,7 +111,9 @@
t.boolean "use_for_advertisement", default: true
t.integer "min_title_length", default: 15, null: false
t.integer "min_body_length", default: 30, null: false
+ t.bigint "default_filter_id"
t.index ["community_id"], name: "index_categories_on_community_id"
+ t.index ["default_filter_id"], name: "index_categories_on_default_filter_id"
t.index ["license_id"], name: "index_categories_on_license_id"
t.index ["sequence"], name: "index_categories_on_sequence"
t.index ["tag_set_id"], name: "index_categories_on_tag_set_id"
@@ -425,8 +427,8 @@
t.boolean "is_top_level", default: false, null: false
t.boolean "is_freely_editable", default: false, null: false
t.string "icon_name"
- t.boolean "has_reactions"
t.bigint "answer_type_id"
+ t.boolean "has_reactions"
t.boolean "has_only_specific_reactions"
t.index ["answer_type_id"], name: "index_post_types_on_answer_type_id"
t.index ["name"], name: "index_post_types_on_name"
@@ -756,8 +758,8 @@
t.datetime "created_at", precision: nil, null: false
t.datetime "updated_at", precision: nil, null: false
t.boolean "read", default: false
- t.index ["author_id"], name: "index_warnings_on_author_id"
- t.index ["community_user_id"], name: "index_warnings_on_community_user_id"
+ t.index ["author_id"], name: "index_mod_messages_on_author_id"
+ t.index ["community_user_id"], name: "index_mod_messages_on_community_user_id"
end
add_foreign_key "abilities", "communities"
@@ -765,6 +767,7 @@
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
add_foreign_key "audit_logs", "communities"
add_foreign_key "audit_logs", "users"
+ add_foreign_key "categories", "filters", column: "default_filter_id"
add_foreign_key "categories", "licenses"
add_foreign_key "categories", "tag_sets"
add_foreign_key "category_filter_defaults", "categories"
diff --git a/db/seeds/filters.yml b/db/seeds/filters.yml
index 4e97a8f40..d23f91b9e 100644
--- a/db/seeds/filters.yml
+++ b/db/seeds/filters.yml
@@ -1,3 +1,6 @@
+- name: None
+ user_id: -1
+
- name: Positive
user_id: -1
min_score: 0.5