Plugin Rewrite v2.3.0

This update constitutes a plugin rewrite to manage all options needed in the plugin into separate tabs and split files for maintenance.
This commit is contained in:
2026-03-06 17:45:04 -04:00
parent 1c66805242
commit af75ea54a6
11 changed files with 1300 additions and 805 deletions

View File

@@ -0,0 +1,189 @@
import { withPluginApi } from "discourse/lib/plugin-api";
const TABS = [
{
id: "general",
label: "General",
settings: new Set([
"community_landing_enabled",
"logo_dark_url", "logo_light_url", "logo_height", "footer_logo_url",
"accent_color", "accent_hover_color", "dark_bg_color", "light_bg_color",
"scroll_animation"
])
},
{
id: "navbar",
label: "Navbar",
settings: new Set([
"navbar_signin_label", "navbar_join_label", "navbar_bg_color", "navbar_border_style"
])
},
{
id: "hero",
label: "Hero",
settings: new Set([
"hero_title", "hero_subtitle", "hero_card_enabled", "hero_background_image_url",
"hero_image_urls", "hero_image_max_height",
"hero_primary_button_label", "hero_primary_button_url",
"hero_secondary_button_label", "hero_secondary_button_url",
"hero_bg_dark", "hero_bg_light", "hero_min_height", "hero_border_style"
])
},
{
id: "stats",
label: "Stats",
settings: new Set([
"stats_title", "stat_icon_color",
"stat_members_label", "stat_topics_label", "stat_posts_label",
"stat_likes_label", "stat_chats_label",
"stats_bg_dark", "stats_bg_light", "stats_min_height", "stats_border_style"
])
},
{
id: "about",
label: "About",
settings: new Set([
"about_enabled", "about_heading_enabled", "about_heading",
"about_title", "about_role", "about_body", "about_image_url",
"about_gradient_start", "about_gradient_mid", "about_gradient_end",
"about_background_image_url",
"about_bg_dark", "about_bg_light", "about_min_height", "about_border_style"
])
},
{
id: "topics",
label: "Trending",
settings: new Set([
"topics_enabled", "topics_title", "topics_count",
"topics_bg_dark", "topics_bg_light", "topics_min_height", "topics_border_style"
])
},
{
id: "contributors",
label: "Creators",
settings: new Set([
"contributors_enabled", "contributors_title", "contributors_days", "contributors_count",
"contributors_bg_dark", "contributors_bg_light", "contributors_min_height", "contributors_border_style"
])
},
{
id: "groups",
label: "Spaces",
settings: new Set([
"groups_enabled", "groups_title", "groups_count",
"groups_bg_dark", "groups_bg_light", "groups_min_height", "groups_border_style"
])
},
{
id: "appcta",
label: "App CTA",
settings: new Set([
"show_app_ctas", "ios_app_url", "android_app_url",
"ios_app_badge_image_url", "android_app_badge_image_url",
"app_badge_height", "app_badge_style",
"app_cta_headline", "app_cta_subtext",
"app_cta_gradient_start", "app_cta_gradient_mid", "app_cta_gradient_end",
"app_cta_image_url",
"app_cta_bg_dark", "app_cta_bg_light", "app_cta_min_height", "app_cta_border_style"
])
},
{
id: "footer",
label: "Footer",
settings: new Set([
"footer_description", "footer_text", "footer_links",
"footer_bg_dark", "footer_bg_light", "footer_border_style"
])
},
{
id: "css",
label: "Custom CSS",
settings: new Set(["custom_css"])
}
];
let currentTab = "general";
function applyTabFilter(container) {
const tab = TABS.find((t) => t.id === currentTab);
if (!tab) return;
container.querySelectorAll(".row.setting[data-setting]").forEach((row) => {
const name = row.getAttribute("data-setting");
row.style.display = tab.settings.has(name) ? "" : "none";
});
}
function buildTabsUI() {
const container =
document.querySelector(".admin-plugin-config-area") ||
document.querySelector(".admin-detail");
if (!container) return false;
// Already injected?
if (container.querySelector(".cl-admin-tabs")) return true;
const allRows = container.querySelectorAll(".row.setting[data-setting]");
if (allRows.length < 5) return false;
// Verify our settings are present
const firstTab = TABS[0];
const hasOurs = Array.from(allRows).some((row) =>
firstTab.settings.has(row.getAttribute("data-setting"))
);
if (!hasOurs) return false;
// Create tab bar
const tabBar = document.createElement("div");
tabBar.className = "cl-admin-tabs";
TABS.forEach((tab) => {
const btn = document.createElement("button");
btn.className = "cl-admin-tab" + (tab.id === currentTab ? " active" : "");
btn.textContent = tab.label;
btn.setAttribute("data-tab", tab.id);
btn.addEventListener("click", () => {
currentTab = tab.id;
tabBar
.querySelectorAll(".cl-admin-tab")
.forEach((b) => b.classList.remove("active"));
btn.classList.add("active");
applyTabFilter(container);
});
tabBar.appendChild(btn);
});
// Insert tab bar before the first setting row
const settingsParent = allRows[0].parentNode;
settingsParent.insertBefore(tabBar, allRows[0]);
// Add class to disable separator borders
container.classList.add("cl-tabs-active");
// Apply initial filter
applyTabFilter(container);
return true;
}
export default {
name: "community-landing-admin-tabs",
initialize() {
withPluginApi("1.0", (api) => {
api.onPageChange((url) => {
if (
url.includes("community-landing") ||
url.includes("community_landing")
) {
let attempts = 0;
const tryInject = () => {
if (buildTabsUI() || attempts > 15) return;
attempts++;
setTimeout(tryInject, 200);
};
tryInject();
}
});
});
},
};

View File

@@ -1,74 +1,123 @@
/* ═══════════════════════════════════════════════════════════════════
Community Landing — Admin Settings Panel Styles
Adds visual separators and spacing between setting groups
Tab navigation + fallback separators
═══════════════════════════════════════════════════════════════════ */
/* All community_landing settings get extra bottom spacing */
.admin-detail .row.setting[data-setting^="community_landing_"] {
/* ── Tab Navigation ── */
.cl-admin-tabs {
display: flex;
flex-wrap: wrap;
gap: 0;
margin: 0 0 24px 0;
padding: 0;
border-bottom: 1px solid var(--primary-low, rgba(0, 0, 0, 0.1));
}
.cl-admin-tab {
padding: 10px 14px;
border: none;
background: none;
color: var(--primary-medium, #888);
font-size: 13px;
font-weight: 600;
cursor: pointer;
border-bottom: 2px solid transparent;
margin-bottom: -1px;
transition: color 0.15s ease, border-color 0.15s ease;
}
.cl-admin-tab:hover {
color: var(--primary, #333);
}
.cl-admin-tab.active {
color: var(--tertiary, #0088cc);
border-bottom-color: var(--tertiary, #0088cc);
}
/* Dark mode tabs */
html.dark-scheme .cl-admin-tabs {
border-bottom-color: rgba(255, 255, 255, 0.1);
}
html.dark-scheme .cl-admin-tab:hover {
color: var(--primary, #ddd);
}
/* ── When tabs are active, remove separator borders ── */
.cl-tabs-active .row.setting[data-setting] {
border-top: none !important;
margin-top: 0 !important;
padding-top: 0 !important;
}
/* ── Fallback: Separator borders when tabs are NOT active ──
(e.g. if JS fails to load or on older Discourse) */
/* All plugin settings spacing */
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="community_landing_enabled"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="logo_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="accent_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="dark_bg_color"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="light_bg_color"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="scroll_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="navbar_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="hero_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="stats_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="stat_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="about_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="topics_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="contributors_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="groups_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="show_app_ctas"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="ios_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="android_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="app_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting^="footer_"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="custom_css"] {
margin-bottom: 20px;
}
/* ── Section separator borders ──
These selectors target the FIRST setting of each group to add
a visible border-top separator with extra padding above it. */
/* Branding section */
.admin-detail .row.setting[data-setting="community_landing_logo_dark_url"],
/* Global Colors section */
.admin-detail .row.setting[data-setting="community_landing_accent_color"],
/* Custom CSS section */
.admin-detail .row.setting[data-setting="community_landing_custom_css"],
/* Scroll Animations section */
.admin-detail .row.setting[data-setting="community_landing_scroll_animation"],
/* Row 1: Navbar */
.admin-detail .row.setting[data-setting="community_landing_navbar_signin_label"],
/* Row 2: Hero Section */
.admin-detail .row.setting[data-setting="community_landing_hero_title"],
/* Row 3: Premium Stats */
.admin-detail .row.setting[data-setting="community_landing_stats_title"],
/* Row 4: About Community */
.admin-detail .row.setting[data-setting="community_landing_about_enabled"],
/* Row 5: Trending Discussions */
.admin-detail .row.setting[data-setting="community_landing_topics_enabled"],
/* Row 6: Top Creators */
.admin-detail .row.setting[data-setting="community_landing_contributors_enabled"],
/* Row 7: Community Spaces */
.admin-detail .row.setting[data-setting="community_landing_groups_enabled"],
/* Row 8: App Download CTA */
.admin-detail .row.setting[data-setting="community_landing_show_app_ctas"],
/* Row 9: Footer */
.admin-detail .row.setting[data-setting="community_landing_footer_description"] {
/* Section separator borders (fallback only) */
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="logo_dark_url"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="accent_color"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="scroll_animation"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="navbar_signin_label"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="hero_title"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="stats_title"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="about_enabled"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="topics_enabled"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="contributors_enabled"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="groups_enabled"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="show_app_ctas"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="footer_description"],
.admin-detail:not(.cl-tabs-active) .row.setting[data-setting="custom_css"] {
border-top: 2px solid rgba(0, 0, 0, 0.12);
margin-top: 28px;
padding-top: 24px;
}
/* Dark mode admin panel support */
.admin-detail.dark .row.setting[data-setting="community_landing_logo_dark_url"],
.admin-detail.dark .row.setting[data-setting="community_landing_accent_color"],
.admin-detail.dark .row.setting[data-setting="community_landing_custom_css"],
.admin-detail.dark .row.setting[data-setting="community_landing_scroll_animation"],
.admin-detail.dark .row.setting[data-setting="community_landing_navbar_signin_label"],
.admin-detail.dark .row.setting[data-setting="community_landing_hero_title"],
.admin-detail.dark .row.setting[data-setting="community_landing_stats_title"],
.admin-detail.dark .row.setting[data-setting="community_landing_about_enabled"],
.admin-detail.dark .row.setting[data-setting="community_landing_topics_enabled"],
.admin-detail.dark .row.setting[data-setting="community_landing_contributors_enabled"],
.admin-detail.dark .row.setting[data-setting="community_landing_groups_enabled"],
.admin-detail.dark .row.setting[data-setting="community_landing_show_app_ctas"],
.admin-detail.dark .row.setting[data-setting="community_landing_footer_description"],
html.dark-scheme .admin-detail .row.setting[data-setting="community_landing_logo_dark_url"],
html.dark-scheme .admin-detail .row.setting[data-setting="community_landing_accent_color"],
html.dark-scheme .admin-detail .row.setting[data-setting="community_landing_custom_css"],
html.dark-scheme .admin-detail .row.setting[data-setting="community_landing_scroll_animation"],
html.dark-scheme .admin-detail .row.setting[data-setting="community_landing_navbar_signin_label"],
html.dark-scheme .admin-detail .row.setting[data-setting="community_landing_hero_title"],
html.dark-scheme .admin-detail .row.setting[data-setting="community_landing_stats_title"],
html.dark-scheme .admin-detail .row.setting[data-setting="community_landing_about_enabled"],
html.dark-scheme .admin-detail .row.setting[data-setting="community_landing_topics_enabled"],
html.dark-scheme .admin-detail .row.setting[data-setting="community_landing_contributors_enabled"],
html.dark-scheme .admin-detail .row.setting[data-setting="community_landing_groups_enabled"],
html.dark-scheme .admin-detail .row.setting[data-setting="community_landing_show_app_ctas"],
html.dark-scheme .admin-detail .row.setting[data-setting="community_landing_footer_description"] {
/* Dark mode separators (fallback only) */
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="logo_dark_url"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="accent_color"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="scroll_animation"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="navbar_signin_label"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="hero_title"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="stats_title"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="about_enabled"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="topics_enabled"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="contributors_enabled"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="groups_enabled"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="show_app_ctas"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="footer_description"],
html.dark-scheme .admin-detail:not(.cl-tabs-active) .row.setting[data-setting="custom_css"] {
border-top-color: rgba(255, 255, 255, 0.12);
}
/* ── Tab content spacing ── */
.cl-tabs-active .row.setting[data-setting] {
margin-bottom: 16px;
}

View File

@@ -493,9 +493,10 @@
font-size: 0.82rem; font-weight: 600; color: var(--cl-text-strong);
white-space: nowrap;
}
.cl-creator-pill__activity {
font-size: 0.72rem; color: var(--cl-muted); white-space: nowrap;
font-weight: 500;
.cl-creator-pill__count {
font-size: 0.72rem; color: var(--cl-accent); white-space: nowrap;
font-weight: 700; margin-left: auto; padding-left: 0.4rem;
min-width: 1.2em; text-align: center;
}
/* ═══════════════════════════════════════════════════════════════════