Files
planet/frontend/public/earth/js/brand.js
rayd1o 81970a1d05
Some checks failed
ci / backend (push) Has been cancelled
ci / frontend (push) Has been cancelled
ci / delivery (push) Has been cancelled
release / images (push) Has been cancelled
release: bump version to 0.60.0
2026-05-17 02:50:42 +08:00

111 lines
3.7 KiB
JavaScript

const DEFAULT_BRAND_LANGUAGE = "zh";
const EARTH_BRAND_API = "/api/v1/earth/brand";
const BRANDS = {
zh: {
ariaLabel: "智能星球计划品牌标识",
titleAlt: "智能星球计划",
logoSrc: "/earth/assets/brand/earth-logo.png",
titleSrc: "/earth/assets/brand/title-zh.png",
titleText: "智能星球计划",
subtitle: "现实层宇宙全息感知系统",
description: "卫星 · 海底光缆 · 算力基础设施",
},
en: {
ariaLabel: "Intelligent Planet Program brand banner",
titleAlt: "Intelligent Planet Program",
logoSrc: "/earth/assets/brand/earth-logo.png",
titleSrc: "/earth/assets/brand/title-en.png",
titleText: "Intelligent Planet Program",
subtitle: "Physical-Universe Holography",
description: "Satellites · Cables · Compute Infra",
},
};
export function getDefaultBrandConfig(variant = DEFAULT_BRAND_LANGUAGE) {
return BRANDS[variant] ?? BRANDS[DEFAULT_BRAND_LANGUAGE];
}
function escapeHtml(value = "") {
return String(value)
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#39;");
}
function normalizeBrandConfig(config = {}, variant = DEFAULT_BRAND_LANGUAGE) {
const defaults = getDefaultBrandConfig(variant);
const normalized = {
...defaults,
...config,
ariaLabel: config.aria_label ?? config.ariaLabel ?? defaults.ariaLabel,
titleAlt: config.title_alt ?? config.titleAlt ?? defaults.titleAlt,
logoSrc: config.logo_src ?? config.logoSrc ?? defaults.logoSrc,
titleSrc: config.title_src ?? config.titleSrc ?? defaults.titleSrc,
titleText: config.title_text ?? config.titleText ?? defaults.titleText,
};
if (!normalized.titleText) normalized.titleText = defaults.titleText;
if (!normalized.ariaLabel) normalized.ariaLabel = normalized.titleText;
if (!normalized.titleAlt) normalized.titleAlt = normalized.titleText;
return normalized;
}
export function renderBrand(configOrVariant = DEFAULT_BRAND_LANGUAGE) {
const variant =
typeof configOrVariant === "string"
? configOrVariant
: configOrVariant.variant ?? DEFAULT_BRAND_LANGUAGE;
const config =
typeof configOrVariant === "string"
? normalizeBrandConfig({}, variant)
: normalizeBrandConfig(configOrVariant, variant);
const titleMarkup = config.titleSrc
? `
<img
class="earth-brand__title"
src="${escapeHtml(config.titleSrc)}"
alt="${escapeHtml(config.titleAlt)}"
fetchpriority="high"
loading="eager"
>
`
: `<div class="earth-brand__title-text">${escapeHtml(config.titleText)}</div>`;
return `
<div class="earth-brand earth-brand--${escapeHtml(variant)}" aria-label="${escapeHtml(config.ariaLabel)}">
<img
class="earth-brand__logo"
src="${escapeHtml(config.logoSrc)}"
alt=""
aria-hidden="true"
fetchpriority="high"
loading="eager"
>
<div class="earth-brand__copy">
${titleMarkup}
<div class="earth-brand__meta">
<span class="earth-brand__subtitle">${escapeHtml(config.subtitle)}</span>
<span class="earth-brand__description">${escapeHtml(config.description)}</span>
</div>
</div>
</div>
`.trim();
}
export function mountBrand(target, configOrVariant = DEFAULT_BRAND_LANGUAGE) {
if (!target) return;
target.innerHTML = renderBrand(configOrVariant);
}
export async function fetchEarthBrandConfig() {
const response = await fetch(EARTH_BRAND_API, { cache: "no-store" });
if (!response.ok) {
throw new Error(`Earth brand config request failed: ${response.status}`);
}
const payload = await response.json();
return payload?.brand ?? getDefaultBrandConfig();
}