From d37a0d401ceca044002fd640be3745de643a3f2a Mon Sep 17 00:00:00 2001 From: Bianca Nenciu Date: Thu, 24 Oct 2024 13:46:42 +0300 Subject: [PATCH] FEATURE: Introduce an optimized style for category page (#29239) The new style is called `categories_only_optimized` and it is designed to show only the parent categories, without any subcategories. This works best for communities with many categories (over a thousand). --- .../components/categories-only-optimized.hbs | 83 +++++++++++++++++++ .../components/categories-only-optimized.js | 56 +++++++++++++ .../discovery/categories-display.gjs | 10 ++- .../parent-category-row-optimized.hbs | 46 ++++++++++ .../parent-category-row-optimized.js | 3 + .../components/categories-only-optimized.hbs | 36 ++++++++ .../parent-category-row-optimized.hbs | 29 +++++++ app/assets/stylesheets/mobile/topic-list.scss | 10 +++ app/models/category_list.rb | 3 +- app/models/category_page_style.rb | 1 + config/locales/client.en.yml | 1 + spec/requests/categories_controller_spec.rb | 14 +++- 12 files changed, 289 insertions(+), 3 deletions(-) create mode 100644 app/assets/javascripts/discourse/app/components/categories-only-optimized.hbs create mode 100644 app/assets/javascripts/discourse/app/components/categories-only-optimized.js create mode 100644 app/assets/javascripts/discourse/app/components/parent-category-row-optimized.hbs create mode 100644 app/assets/javascripts/discourse/app/components/parent-category-row-optimized.js create mode 100644 app/assets/javascripts/discourse/app/templates/mobile/components/categories-only-optimized.hbs create mode 100644 app/assets/javascripts/discourse/app/templates/mobile/components/parent-category-row-optimized.hbs diff --git a/app/assets/javascripts/discourse/app/components/categories-only-optimized.hbs b/app/assets/javascripts/discourse/app/components/categories-only-optimized.hbs new file mode 100644 index 00000000000..6c36c1c6106 --- /dev/null +++ b/app/assets/javascripts/discourse/app/components/categories-only-optimized.hbs @@ -0,0 +1,83 @@ + + {{#if this.categories}} + {{#if this.filteredCategories}} + + + + + + {{#if this.showTopics}} + + {{/if}} + + + + {{#each this.categories as |category|}} + + {{/each}} + +
{{i18n "categories.category"}}{{i18n "categories.topics"}}{{i18n "categories.latest"}}
+ {{/if}} + + {{#if this.mutedCategories}} +
+ +

{{i18n "categories.muted"}}

+ {{#if this.mutedToggleIcon}} + {{d-icon this.mutedToggleIcon}} + {{/if}} +
+ + + + + + {{#if this.showTopics}} + + {{/if}} + + + + {{#each this.categories as |category|}} + + {{/each}} + +
{{i18n "categories.category"}}{{i18n "categories.topics"}}{{i18n "categories.latest"}}
+
+ {{/if}} + {{/if}} +
+ + \ No newline at end of file diff --git a/app/assets/javascripts/discourse/app/components/categories-only-optimized.js b/app/assets/javascripts/discourse/app/components/categories-only-optimized.js new file mode 100644 index 00000000000..992c588e272 --- /dev/null +++ b/app/assets/javascripts/discourse/app/components/categories-only-optimized.js @@ -0,0 +1,56 @@ +import Component from "@ember/component"; +import { action } from "@ember/object"; +import { tagName } from "@ember-decorators/component"; +import discourseComputed from "discourse-common/utils/decorators"; + +@tagName("") +export default class CategoriesOnlyOptimized extends Component { + showMuted = false; + + @discourseComputed("showMutedCategories", "filteredCategories.length") + mutedToggleIcon(showMutedCategories, filteredCategoriesLength) { + if (filteredCategoriesLength === 0) { + return; + } + + if (showMutedCategories) { + return "minus"; + } + + return "plus"; + } + + @discourseComputed("showMuted", "filteredCategories.length") + showMutedCategories(showMuted, filteredCategoriesLength) { + return showMuted || filteredCategoriesLength === 0; + } + + @discourseComputed("categories", "categories.length") + filteredCategories(categories, categoriesLength) { + if (!categories || categoriesLength === 0) { + return []; + } + + return categories.filter((cat) => !cat.isHidden); + } + + @discourseComputed("categories", "categories.length") + mutedCategories(categories, categoriesLength) { + if (!categories || categoriesLength === 0) { + return []; + } + + // hide in single category pages + if (categories.firstObject.parent_category_id) { + return []; + } + + return categories.filterBy("hasMuted"); + } + + @action + toggleShowMuted(event) { + event?.preventDefault(); + this.toggleProperty("showMuted"); + } +} 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 e1e0bd8d6ce..1837f591583 100644 --- a/app/assets/javascripts/discourse/app/components/discovery/categories-display.gjs +++ b/app/assets/javascripts/discourse/app/components/discovery/categories-display.gjs @@ -6,6 +6,7 @@ import CategoriesAndTopTopics from "discourse/components/categories-and-top-topi import CategoriesBoxes from "discourse/components/categories-boxes"; import CategoriesBoxesWithTopics from "discourse/components/categories-boxes-with-topics"; import CategoriesOnly from "discourse/components/categories-only"; +import CategoriesOnlyOptimized from "discourse/components/categories-only-optimized"; import CategoriesWithFeaturedTopics from "discourse/components/categories-with-featured-topics"; import ConditionalLoadingSpinner from "discourse/components/conditional-loading-spinner"; import LoadMore from "discourse/components/load-more"; @@ -15,6 +16,7 @@ import SubcategoriesWithFeaturedTopics from "discourse/components/subcategories- const mobileCompatibleViews = [ "categories_with_featured_topics", "subcategories_with_featured_topics", + "categories_only_optimized", ]; const subcategoryComponents = { @@ -31,6 +33,7 @@ const globalComponents = { categories_boxes_with_topics: CategoriesBoxesWithTopics, categories_boxes: CategoriesBoxes, categories_only: CategoriesOnly, + categories_only_optimized: CategoriesOnlyOptimized, categories_with_featured_topics: CategoriesWithFeaturedTopics, subcategories_with_featured_topics: SubcategoriesWithFeaturedTopics, }; @@ -81,7 +84,12 @@ export default class CategoriesDisplay extends Component { } get canLoadMore() { - return this.site.lazy_load_categories && this.args.loadMore; + return ( + this.args.loadMore && + (this.site.lazy_load_categories || + this.siteSettings.desktop_category_page_style === + "categories_only_optimized") + ); }