From 0492d04a10532e9d3c2003f23f9e5070e00e12e3 Mon Sep 17 00:00:00 2001 From: fylorn <249551762+fylorn@users.noreply.github.com> Date: Sun, 4 Oct 2026 19:30:03 +0800 Subject: [PATCH] Header: the GitHub pill shows ThinkWatch Lite, the enterprise repository only on its own pages The pill linked to and counted the enterprise repository on every page. It now shows ThinkWatch Lite by default, and the enterprise repository on the enterprise page (/thinkwatch) and its guides (/docs/). The live count fetched in the browser follows the same repository. Co-Authored-By: Claude Opus 5.5 --- src/components/SiteHeader.astro | 20 +++++++++++++++----- src/lib/github.ts | 32 +++++++++++++++++--------------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/components/SiteHeader.astro b/src/components/SiteHeader.astro index 99120f2..49734f5 100644 --- a/src/components/SiteHeader.astro +++ b/src/components/SiteHeader.astro @@ -1,6 +1,7 @@ --- import { getLang, t, localePath, type Lang } from "~/i18n"; import { getStarCount, formatStars } from "~/lib/github"; +import { productRepos } from "~/lib/releases.mjs"; import { findDoc, getProduct } from "~/content/docs/_meta"; import SearchModal from "./SearchModal.astro"; import TwMark from "./TwMark.astro"; @@ -20,8 +21,6 @@ const sEn = t("en"); const sZh = t("zh-CN"); /** data-localize for a link on a bilingual page: the 404 page's script prefixes /zh-CN for Chinese visitors */ const localize = (path: string) => (bilingual ? path : undefined); -const stars = await getStarCount(); -const starLabel = formatStars(stars); // On the home page anchor links work as in-page jumps; on /docs/* and // /changelog they need to navigate back to the home first. @@ -46,6 +45,15 @@ const currentDocMeta = currentDocSlug ? findDoc(currentDocSlug, (docMatch?.[1] as "lite" | "core" | undefined) ?? "thinkwatch") : undefined; +// The GitHub pill shows ThinkWatch Lite's repository, except on the enterprise +// edition's page and its guides (/docs/), which show the enterprise one. +const enterprise = + /^\/thinkwatch(\/|$)/.test(cleanPath) || + (docMatch !== null && !docMatch[1] && docMatch[2] !== "lite" && docMatch[2] !== "core"); +const starRepo = enterprise ? productRepos.enterprise : productRepos.lite; +const stars = await getStarCount(starRepo); +const starLabel = formatStars(stars); + function targetPath(target: Lang): string { // The 404 page stands in for every missing path, and /404 itself does not // exist: its language choice leads to the home page. @@ -137,9 +145,10 @@ const zhAttrs = (attrs: Record) => (bilingual ? JSON.stringify(a @@ -311,8 +320,9 @@ const zhAttrs = (attrs: Record) => (bilingual ? JSON.stringify(a // Fetch live GitHub star count and update the pill { const el = document.querySelector("[data-star-count]"); - if (el) { - fetch("https://api.github.com/repos/ThinkWatchProject/ThinkWatch", { + const repo = el?.closest("[data-star-repo]")?.dataset.starRepo; + if (el && repo) { + fetch(`https://api.github.com/repos/${repo}`, { headers: { Accept: "application/vnd.github+json" }, }) .then((r) => r.ok ? r.json() : null) diff --git a/src/lib/github.ts b/src/lib/github.ts index 268693b..8adcc1c 100644 --- a/src/lib/github.ts +++ b/src/lib/github.ts @@ -9,23 +9,25 @@ export type { Product, Release }; const REPO = productRepos.enterprise; -let cached: number | null | undefined; +const starCache = new Map>(); -export async function getStarCount(): Promise { - if (cached !== undefined) return cached; - try { - const res = await fetch(`https://api.github.com/repos/${REPO}`, { headers: githubHeaders() }); - if (!res.ok) { - cached = null; - return null; - } - const data: { stargazers_count?: number } = await res.json(); - cached = typeof data.stargazers_count === "number" ? data.stargazers_count : null; - return cached; - } catch { - cached = null; - return null; +/** A repository's star count, fetched once per build and repository. */ +export function getStarCount(repo: string): Promise { + let cached = starCache.get(repo); + if (!cached) { + cached = (async () => { + try { + const res = await fetch(`https://api.github.com/repos/${repo}`, { headers: githubHeaders() }); + if (!res.ok) return null; + const data: { stargazers_count?: number } = await res.json(); + return typeof data.stargazers_count === "number" ? data.stargazers_count : null; + } catch { + return null; + } + })(); + starCache.set(repo, cached); } + return cached; } export function formatStars(n: number | null): string {