diff --git a/common/common.scss b/common/common.scss index 3201b6a..70bda58 100644 --- a/common/common.scss +++ b/common/common.scss @@ -38,6 +38,10 @@ color: var(--primary-high); } } + + &__group { + margin-bottom: 1rem; + } } } diff --git a/javascripts/discourse/components/topic-in-gated-category.gjs b/javascripts/discourse/components/topic-in-gated-category.gjs index 25bbc5d..472811e 100644 --- a/javascripts/discourse/components/topic-in-gated-category.gjs +++ b/javascripts/discourse/components/topic-in-gated-category.gjs @@ -14,6 +14,10 @@ export default class TopicInGatedCategory extends Component { .map((id) => parseInt(id, 10)) .filter((id) => id); enabledTags = settings.enabled_tags.split("|").filter(Boolean); + enabledGroups = settings.enabled_groups + .split("|") + .map((id) => parseInt(id, 10)) + .filter((id) => !isNaN(id)); didInsertElement() { super.didInsertElement(...arguments); @@ -31,29 +35,41 @@ export default class TopicInGatedCategory extends Component { } recalculate() { - // do nothing if: - // a) topic does not have a category and does not have a gated tag - // b) component setting is empty - // c) user is logged in // TODO(https://github.com/discourse/discourse/pull/36678): The string check can be // removed using .discourse-compatibility once the PR is merged. - const gatedByTag = this.tags?.some((t) => { - const name = typeof t === "string" ? t : t.name; - return this.enabledTags.includes(name); - }); + // user is in an enabled group — always bypass if ( - (!this.categoryId && !gatedByTag) || - (this.enabledCategories.length === 0 && this.enabledTags.length === 0) || - this.currentUser + this.currentUser?.groups?.some((g) => this.enabledGroups.includes(g.id)) ) { return; } - if (this.enabledCategories.includes(this.categoryId) || gatedByTag) { - document.body.classList.add("topic-in-gated-category"); - this.set("hidden", false); + const hasGroupGating = this.enabledGroups.length > 0; + const gatedByCategory = this.enabledCategories.includes(this.categoryId); + const gatedByTag = this.tags?.some((t) => { + const name = typeof t === "string" ? t : t.name; + return this.enabledTags.includes(name); + }); + const hasAnyCategoryOrTag = + this.enabledCategories.length > 0 || this.enabledTags.length > 0; + + if (!hasAnyCategoryOrTag && !hasGroupGating) { + return; } + + // when categories/tags are configured, topic must match one + if (hasAnyCategoryOrTag && !gatedByCategory && !gatedByTag) { + return; + } + + // no groups configured — original behavior: any logged-in user bypasses + if (!hasGroupGating && this.currentUser) { + return; + } + + document.body.classList.add("topic-in-gated-category"); + this.set("hidden", false); } @computed("hidden") @@ -61,6 +77,10 @@ export default class TopicInGatedCategory extends Component { return !this.hidden; } + get showGroupGate() { + return this.currentUser && this.enabledGroups.length > 0; + } +