import opencodeWordmarkDark from "../asset/logo-ornate-dark.svg" import { query } from "@solidjs/router" import { createEffect, createMemo, createSignal, For, onCleanup, onMount, Show } from "solid-js" import { useI18n } from "../context/i18n" import { useLanguage } from "../context/language" import { route, type Locale } from "../lib/language" export type HeaderLink = { href: string; label: string } export const githubLink = { href: "https://github.com/anomalyco/opencode", apiHref: "https://api.github.com/repos/anomalyco/opencode", fallbackStars: "195K", } export const themePreferences = ["dark", "light", "system"] as const export const themeStorageKey = "opencode:stats-theme" export type ThemePreference = (typeof themePreferences)[number] const compactNumberFormatter = new Intl.NumberFormat("en", { notation: "compact", maximumFractionDigits: 0, roundingIncrement: 5, }) export const getGitHubStars = query(async () => { "use server" return fetch(githubLink.apiHref, { headers: { Accept: "application/vnd.github+json", "X-GitHub-Api-Version": "2022-11-28", }, }) .then((response) => (response.ok ? response.json() : undefined)) .then((body: unknown) => body && typeof body === "object" && "stargazers_count" in body && typeof body.stargazers_count === "number" ? compactNumberFormatter.format(body.stargazers_count) : githubLink.fallbackStars, ) .catch(() => githubLink.fallbackStars) }, "getGitHubStars") export function isThemePreference(value: string | null): value is ThemePreference { return value === "dark" || value === "light" || value === "system" } export function applyThemePreference(preference: ThemePreference) { if (typeof document === "undefined") return document.documentElement.dataset.statsTheme = preference if (preference === "system") { document.documentElement.style.removeProperty("color-scheme") return } document.documentElement.style.setProperty("color-scheme", preference) } export function Header(props: { githubStars: string; links?: readonly HeaderLink[]; brandHref?: string }) { const i18n = useI18n() const language = useLanguage() const [menuOpen, setMenuOpen] = createSignal(false) const [menuViewport, setMenuViewport] = createSignal(false) const links = createMemo( () => props.links ?? [ { href: "#top-models", label: i18n.t("nav.topModels") }, { href: "#leaderboard", label: i18n.t("nav.leaderboard") }, { href: "#session-cost", label: i18n.t("nav.sessionCost") }, { href: "#token-cost", label: i18n.t("nav.tokenCost") }, { href: "#cache-ratio", label: i18n.t("nav.cacheRatio") }, { href: "#market-share", label: i18n.t("nav.marketShare") }, { href: "#geo-breakdown", label: i18n.t("nav.geoBreakdown") }, ], ) const localHref = (href: string) => (href.startsWith("/") ? language.route(href) : href) createEffect(() => { if (typeof window === "undefined") return const media = window.matchMedia("(max-width: 89.999rem)") const update = () => setMenuViewport(media.matches) update() media.addEventListener("change", update) onCleanup(() => media.removeEventListener("change", update)) }) createEffect(() => { if (!menuOpen()) return if (!menuViewport()) return if (typeof document === "undefined") return const page = document.querySelector('[data-page="stats"]') const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth const htmlOverflow = document.documentElement.style.overflow const pagePaddingRight = page?.style.paddingRight const bodyOverflow = document.body.style.overflow document.documentElement.style.overflow = "hidden" if (scrollbarWidth > 0 && page) page.style.paddingRight = `${scrollbarWidth}px` document.body.style.overflow = "hidden" onCleanup(() => { document.documentElement.style.overflow = htmlOverflow if (page && pagePaddingRight !== undefined) page.style.paddingRight = pagePaddingRight document.body.style.overflow = bodyOverflow }) }) return (
{i18n.t("header.github")} [{props.githubStars}] {i18n.t("header.tryOpenCode")}
) } function DataWordmark() { return ( ) } function OpenCodeMark() { return ( ) } export function Footer(props: { themePreference: ThemePreference onThemePreferenceChange: (preference: ThemePreference) => void links?: readonly HeaderLink[] bridge?: HeaderLink | null }) { const i18n = useI18n() const language = useLanguage() const [subscribeOpen, setSubscribeOpen] = createSignal(false) const localHref = (href: string) => (href.startsWith("/") ? language.route(href) : href) const modelStats = props.links ?? [ { href: "#top-models", label: i18n.t("nav.topModels") }, { href: "#leaderboard", label: i18n.t("nav.leaderboard") }, { href: "#session-cost", label: i18n.t("nav.sessionCost") }, { href: "#token-cost", label: i18n.t("nav.tokenCost") }, { href: "#cache-ratio", label: i18n.t("nav.cacheRatio") }, { href: "#market-share", label: i18n.t("nav.marketShare") }, { href: "#geo-breakdown", label: i18n.t("nav.geoBreakdown") }, ] const legal = [ { href: "https://opencode.ai/legal/terms-of-service", label: i18n.t("footer.terms") }, { href: "https://opencode.ai/legal/privacy-policy", label: i18n.t("footer.privacy") }, ] const connect = [ { href: "mailto:hello@opencode.ai", label: i18n.t("footer.contact") }, { href: "https://opencode.ai/discord", label: i18n.t("footer.community") }, { href: "https://x.com/opencode", label: "X" }, { href: githubLink.href, label: i18n.t("header.github") }, { href: "https://www.youtube.com/@anomalyco", label: i18n.t("footer.youtube") }, ] const bridge = () => props.bridge === undefined ? { href: "#geo-breakdown", label: i18n.t("nav.geoBreakdown").toUpperCase() } : props.bridge return ( ) } function FooterLanguageSwitcher() { const i18n = useI18n() const language = useLanguage() return ( ) } function SectionBridge(props: { label: string; href: string }) { const i18n = useI18n() return ( {i18n.t("bridge.learnMore")} {props.label} ▸ ) } function ThemePreferenceIcon(props: { preference: ThemePreference }) { return ( ) } function SubscribeModal(props: { onClose: () => void }) { const i18n = useI18n() const [status, setStatus] = createSignal<"idle" | "pending" | "success" | "error">("idle") const [message, setMessage] = createSignal("") let input: HTMLInputElement | undefined onMount(() => { if (typeof document === "undefined") return const activeElement = document.activeElement instanceof HTMLElement ? document.activeElement : undefined const htmlOverflow = document.documentElement.style.overflow const bodyOverflow = document.body.style.overflow document.documentElement.style.overflow = "hidden" document.body.style.overflow = "hidden" const focusTimeout = window.setTimeout(() => input?.focus(), 0) const onKeyDown = (event: KeyboardEvent) => { if (event.key === "Escape") props.onClose() } document.addEventListener("keydown", onKeyDown) onCleanup(() => { window.clearTimeout(focusTimeout) document.documentElement.style.overflow = htmlOverflow document.body.style.overflow = bodyOverflow document.removeEventListener("keydown", onKeyDown) activeElement?.focus() }) }) return (
) } function newsletterErrorMessage(response: Response, fallback: string) { return response.json().then( (body: unknown) => body && typeof body === "object" && "error" in body && typeof body.error === "string" ? body.error : fallback, () => fallback, ) } function FooterColumn(props: { title: string links: readonly { href: string; label: string }[] localHref: (href: string) => string }) { return (

{props.title}

) } function themePreferenceLabelKey(preference: ThemePreference) { if (preference === "dark") return "theme.dark" if (preference === "light") return "theme.light" return "theme.system" }