diff --git a/app/assets/javascripts/discourse/app/components/discovery/categories-display.gjs b/app/assets/javascripts/discourse/app/components/discovery/categories-display.gjs index 1837f591583..aaea91723ae 100644 --- a/app/assets/javascripts/discourse/app/components/discovery/categories-display.gjs +++ b/app/assets/javascripts/discourse/app/components/discovery/categories-display.gjs @@ -12,6 +12,7 @@ import ConditionalLoadingSpinner from "discourse/components/conditional-loading- import LoadMore from "discourse/components/load-more"; import PluginOutlet from "discourse/components/plugin-outlet"; import SubcategoriesWithFeaturedTopics from "discourse/components/subcategories-with-featured-topics"; +import { MAX_UNOPTIMIZED_CATEGORIES } from "discourse/lib/constants"; const mobileCompatibleViews = [ "categories_with_featured_topics", @@ -57,15 +58,22 @@ export default class CategoriesDisplay extends Component { return component; } - get #globalComponent() { + get style() { let style = this.siteSettings.desktop_category_page_style; if (this.site.mobileView && !mobileCompatibleViews.includes(style)) { style = mobileCompatibleViews[0]; } - const component = globalComponents[style]; + if (this.site.categories.length > MAX_UNOPTIMIZED_CATEGORIES) { + style = "categories_only_optimized"; + } + return style; + } + + get #globalComponent() { + const component = globalComponents[this.style]; if (!component) { // eslint-disable-next-line no-console - console.error("Unknown category list style: " + style); + console.error("Unknown category list style: " + this.style); return CategoriesOnly; } @@ -87,8 +95,7 @@ export default class CategoriesDisplay extends Component { return ( this.args.loadMore && (this.site.lazy_load_categories || - this.siteSettings.desktop_category_page_style === - "categories_only_optimized") + this.style === "categories_only_optimized") ); } diff --git a/app/assets/javascripts/discourse/app/lib/constants.js b/app/assets/javascripts/discourse/app/lib/constants.js index 3dd3f53935f..97fd6f78452 100644 --- a/app/assets/javascripts/discourse/app/lib/constants.js +++ b/app/assets/javascripts/discourse/app/lib/constants.js @@ -97,3 +97,5 @@ export const SITE_SETTING_REQUIRES_CONFIRMATION_TYPES = { simple: "simple", user_option: "user_option", }; + +export const MAX_UNOPTIMIZED_CATEGORIES = 1000; diff --git a/app/assets/javascripts/discourse/app/routes/discovery-categories.js b/app/assets/javascripts/discourse/app/routes/discovery-categories.js index 503cf0a2e22..15e7101b0a5 100644 --- a/app/assets/javascripts/discourse/app/routes/discovery-categories.js +++ b/app/assets/javascripts/discourse/app/routes/discovery-categories.js @@ -2,6 +2,7 @@ import { action } from "@ember/object"; import { service } from "@ember/service"; import { hash } from "rsvp"; import { ajax } from "discourse/lib/ajax"; +import { MAX_UNOPTIMIZED_CATEGORIES } from "discourse/lib/constants"; import PreloadStore from "discourse/lib/preload-store"; import { defaultHomepage } from "discourse/lib/utilities"; import Category from "discourse/models/category"; @@ -21,8 +22,11 @@ export default class DiscoveryCategoriesRoute extends DiscourseRoute { async findCategories(parentCategory) { let model; - const style = + let style = this.site.desktopView && this.siteSettings.desktop_category_page_style; + if (this.site.categories.length > MAX_UNOPTIMIZED_CATEGORIES) { + style = "categories_only_optimized"; + } if ( style === "categories_and_latest_topics" || diff --git a/app/models/category_list.rb b/app/models/category_list.rb index 3e0f58b0229..490f44416ee 100644 --- a/app/models/category_list.rb +++ b/app/models/category_list.rb @@ -4,6 +4,9 @@ class CategoryList CATEGORIES_PER_PAGE = 20 SUBCATEGORIES_PER_CATEGORY = 5 + # Maximum number of categories before the optimized category page style is enforced + MAX_UNOPTIMIZED_CATEGORIES = 1000 + include ActiveModel::Serialization cattr_accessor :preloaded_topic_custom_fields @@ -139,9 +142,14 @@ class CategoryList query = query.where(parent_category_id: @options[:parent_category_id]) end + style = + if Category.secured(@guardian).count > MAX_UNOPTIMIZED_CATEGORIES + "categories_only_optimized" + else + SiteSetting.desktop_category_page_style + end page = [1, @options[:page].to_i].max - if SiteSetting.desktop_category_page_style == "categories_only_optimized" || - @guardian.can_lazy_load_categories? + if style == "categories_only_optimized" || @guardian.can_lazy_load_categories? query = query.limit(CATEGORIES_PER_PAGE).offset((page - 1) * CATEGORIES_PER_PAGE) elsif page > 1 # Pagination is supported only when lazy load is enabled. If it is not, diff --git a/lib/tasks/javascript.rake b/lib/tasks/javascript.rake index 3f20bb981e8..bd7e8a6dbf3 100644 --- a/lib/tasks/javascript.rake +++ b/lib/tasks/javascript.rake @@ -160,9 +160,11 @@ task "javascript:update_constants" => :environment do export const TOPIC_VISIBILITY_REASONS = #{Topic.visibility_reasons.to_json}; - export const SYSTEM_FLAG_IDS = #{PostActionType.types.to_json} + export const SYSTEM_FLAG_IDS = #{PostActionType.types.to_json}; - export const SITE_SETTING_REQUIRES_CONFIRMATION_TYPES = #{SiteSettings::TypeSupervisor::REQUIRES_CONFIRMATION_TYPES.to_json} + export const SITE_SETTING_REQUIRES_CONFIRMATION_TYPES = #{SiteSettings::TypeSupervisor::REQUIRES_CONFIRMATION_TYPES.to_json}; + + export const MAX_UNOPTIMIZED_CATEGORIES = #{CategoryList::MAX_UNOPTIMIZED_CATEGORIES}; JS pretty_notifications = Notification.types.map { |n| " #{n[0]}: #{n[1]}," }.join("\n")