discourse-category-banners/javascripts/discourse/components/category-banner.js

150 lines
4.0 KiB
JavaScript

import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { getOwner } from "@ember/application";
import { action } from "@ember/object";
import { service } from "@ember/service";
import { htmlSafe } from "@ember/template";
import Category from "discourse/models/category";
export default class DiscourseCategoryBanners extends Component {
@service router;
@service site;
@service categoryBannerPresence;
@tracked category = null;
@tracked keepDuringLoadingRoute = false;
get hasIconComponent() {
return getOwner(this).hasRegistration("component:category-icon");
}
get categorySlugPathWithID() {
return this.router?.currentRoute?.params?.category_slug_path_with_id;
}
get shouldRender() {
return (
this.categorySlugPathWithID ||
(this.keepDuringLoadingRoute &&
this.router.currentRoute.name.includes("loading"))
);
}
get isVisible() {
if (this.categorySlugPathWithID) {
return true;
} else if (this.router.currentRoute.name.includes("loading")) {
return this.keepDuringLoadingRoute;
}
return false;
}
get safeStyle() {
return htmlSafe(
`background-color: #${this.category.color}; color: #${this.category.text_color};`
);
}
get consoleWarn() {
// eslint-disable-next-line no-console
return console.warn(
"The category banners component is trying to use the category icons component, but it is not available. https://meta.discourse.org/t/category-icons/104683"
);
}
get displayCategoryDescription() {
return settings.show_description && this.category.description?.length > 0;
}
#parseExceptions(exceptionsStr) {
return exceptionsStr
.split("|")
.filter(Boolean)
.map((value) => value.toLowerCase());
}
#checkTargetCategory() {
if (settings.categories.length === 0) {
return true;
}
const currentCategoryId = this.category?.id;
const activeCategory = settings.categories.find((category) => {
return category.category_id[0] === currentCategoryId;
});
if (
activeCategory &&
(activeCategory.target === "all" || activeCategory.target === "no_sub")
) {
return true;
}
const parentCategoryId = this.category?.parentCategory?.id;
if (parentCategoryId) {
const activeParentCategory = settings.categories.find((category) => {
return category.category_id[0] === parentCategoryId;
});
if (
activeParentCategory &&
(activeParentCategory.target === "all" ||
activeParentCategory.target === "only_sub")
) {
return true;
}
}
return false;
}
@action
teardownComponent() {
document.body.classList.remove("category-header");
this.category = null;
this.categoryBannerPresence.setTo(false);
}
@action
getCategory() {
if (!this.isVisible) {
return;
}
if (this.categorySlugPathWithID) {
this.category = Category.findBySlugPathWithID(
this.categorySlugPathWithID
);
this.categoryBannerPresence.setTo(true);
this.keepDuringLoadingRoute = true;
} else {
if (!this.router.currentRoute.name.includes("loading")) {
return (this.keepDuringLoadingRoute = false);
}
}
const exceptions = this.#parseExceptions(settings.exceptions);
const isException = exceptions.includes(this.category?.name.toLowerCase());
const isTarget = this.#checkTargetCategory();
const hideMobile = this.site.mobileView && !settings.show_mobile;
const hideSubCategory =
this.category?.parentCategory && !settings.show_subcategory;
const hasNoCategoryDescription =
settings.hide_if_no_description && !this.category?.description_text;
if (
isTarget &&
!isException &&
!hasNoCategoryDescription &&
!hideSubCategory &&
!hideMobile
) {
document.body.classList.add("category-header");
} else {
document.body.classList.remove("category-header");
this.categoryBannerPresence.setTo(false);
}
}
}