From 82a876da4de0074ca3d4d6af9a31dc6e8cf20c3a Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Sun, 28 Dec 2025 06:41:54 -0600 Subject: [PATCH] chore: cleanup --- packages/app/index.html | 31 ++++++++++- packages/app/script/inject-theme-preload.ts | 18 ------- packages/app/vite.js | 18 ------- packages/desktop/index.html | 31 ++++++++++- packages/ui/src/theme/context.tsx | 14 +++-- packages/ui/src/theme/preload.ts | 58 +++++++-------------- 6 files changed, 85 insertions(+), 85 deletions(-) delete mode 100644 packages/app/script/inject-theme-preload.ts diff --git a/packages/app/index.html b/packages/app/index.html index 4f003c05bc..ea42378044 100644 --- a/packages/app/index.html +++ b/packages/app/index.html @@ -13,9 +13,36 @@ - + diff --git a/packages/app/script/inject-theme-preload.ts b/packages/app/script/inject-theme-preload.ts deleted file mode 100644 index 511ab7a3b5..0000000000 --- a/packages/app/script/inject-theme-preload.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Injects the theme preload script into index.html. - * Run this as part of the build process. - */ - -import { generatePreloadScript } from "@opencode-ai/ui/theme" - -const htmlPath = new URL("../index.html", import.meta.url).pathname -const html = await Bun.file(htmlPath).text() - -const script = generatePreloadScript() -const injectedHtml = html.replace( - /`, -) - -await Bun.write(htmlPath, injectedHtml) -console.log("Injected theme preload script into index.html") diff --git a/packages/app/vite.js b/packages/app/vite.js index 5ab3688365..6b8fd61376 100644 --- a/packages/app/vite.js +++ b/packages/app/vite.js @@ -1,23 +1,6 @@ import solidPlugin from "vite-plugin-solid" import tailwindcss from "@tailwindcss/vite" import { fileURLToPath } from "url" -import { generatePreloadScript } from "@opencode-ai/ui/theme" - -/** - * Vite plugin that injects the theme preload script into index.html. - * This ensures the theme is applied before the page renders, avoiding FOUC. - * @type {import("vite").Plugin} - */ -const themePreloadPlugin = { - name: "opencode-desktop:theme-preload", - transformIndexHtml(html) { - const script = generatePreloadScript() - return html.replace( - /`, - ) - }, -} /** * @type {import("vite").PluginOption} @@ -38,7 +21,6 @@ export default [ } }, }, - themePreloadPlugin, tailwindcss(), solidPlugin(), ] diff --git a/packages/desktop/index.html b/packages/desktop/index.html index ea656068ca..83826b602c 100644 --- a/packages/desktop/index.html +++ b/packages/desktop/index.html @@ -13,9 +13,36 @@ - + diff --git a/packages/ui/src/theme/context.tsx b/packages/ui/src/theme/context.tsx index d8ca6d5077..9a2013ee98 100644 --- a/packages/ui/src/theme/context.tsx +++ b/packages/ui/src/theme/context.tsx @@ -126,11 +126,13 @@ function applyThemeCss(theme: DesktopTheme, themeId: string, mode: "light" | "da const css = themeToCss(tokens) // Cache to localStorage for preload script - const cacheKey = getThemeCacheKey(themeId, mode) - try { - localStorage.setItem(cacheKey, css) - } catch { - // localStorage might be full or disabled + if (themeId !== "oc-1") { + const cacheKey = getThemeCacheKey(themeId, mode) + try { + localStorage.setItem(cacheKey, css) + } catch { + // localStorage might be full or disabled + } } // Build full CSS @@ -159,6 +161,8 @@ function applyThemeCss(theme: DesktopTheme, themeId: string, mode: "light" | "da * Cache both light and dark variants of a theme */ function cacheThemeVariants(theme: DesktopTheme, themeId: string): void { + if (themeId === "oc-1") return + for (const mode of ["light", "dark"] as const) { const isDark = mode === "dark" const variant = isDark ? theme.dark : theme.light diff --git a/packages/ui/src/theme/preload.ts b/packages/ui/src/theme/preload.ts index eb54082faf..7e1143202e 100644 --- a/packages/ui/src/theme/preload.ts +++ b/packages/ui/src/theme/preload.ts @@ -4,15 +4,13 @@ * Generates a minimal inline script that: * 1. Reads theme preferences from localStorage * 2. Applies cached theme CSS immediately (avoiding FOUC) - * 3. Falls back to embedded default theme CSS on first visit + * + * The default (oc-1) theme is provided by `@opencode-ai/ui/styles` via `theme.css`, + * so the preload script only runs when a non-default theme is selected. * * The script should be placed in the document before any stylesheets. */ -import { resolveThemeVariant, themeToCss } from "./resolve" -import type { DesktopTheme } from "./types" -import oc1Theme from "./themes/oc-1.json" - // Storage keys used by both the preload script and the ThemeProvider export const STORAGE_KEYS = { THEME_ID: "opencode-theme-id", @@ -27,34 +25,17 @@ export function getThemeCacheKey(themeId: string, mode: "light" | "dark"): strin return `${STORAGE_KEYS.THEME_CSS_PREFIX}-${themeId}-${mode}` } -/** - * Generate the embedded default theme CSS for the preload script. - * This is used as a fallback when no cached theme exists. - */ -function generateEmbeddedDefaults(): { light: string; dark: string } { - const theme = oc1Theme as DesktopTheme - const lightTokens = resolveThemeVariant(theme.light, false) - const darkTokens = resolveThemeVariant(theme.dark, true) - - return { - light: themeToCss(lightTokens), - dark: themeToCss(darkTokens), - } -} - /** * Generate the inline preload script. * * This script should be placed in the document to avoid FOUC. - * It reads theme preferences from localStorage and applies the theme CSS - * immediately, falling back to an embedded default theme. + * It reads theme preferences from localStorage and applies cached theme CSS + * immediately. */ export function generatePreloadScript(): string { - const defaults = generateEmbeddedDefaults() - // Minified version of the preload logic // Variables: T=themeId, S=scheme, D=isDark, M=mode, C=css, K=cacheKey - return `(function(){var T=localStorage.getItem("${STORAGE_KEYS.THEME_ID}")||"oc-1";var S=localStorage.getItem("${STORAGE_KEYS.COLOR_SCHEME}")||"system";var D=S==="dark"||(S==="system"&&matchMedia("(prefers-color-scheme:dark)").matches);var M=D?"dark":"light";var K="${STORAGE_KEYS.THEME_CSS_PREFIX}-"+T+"-"+M;var C=localStorage.getItem(K);if(!C&&T==="oc-1"){C=D?${JSON.stringify(defaults.dark)}:${JSON.stringify(defaults.light)}}if(C){var s=document.createElement("style");s.id="oc-theme-preload";s.textContent=":root{color-scheme:"+M+";--text-mix-blend-mode:"+(D?"plus-lighter":"multiply")+";"+C+"}";document.head.appendChild(s)}document.documentElement.dataset.theme=T;document.documentElement.dataset.colorScheme=M})();` + return `(function(){var T=localStorage.getItem("${STORAGE_KEYS.THEME_ID}");if(!T)return;var S=localStorage.getItem("${STORAGE_KEYS.COLOR_SCHEME}")||"system";var D=S==="dark"||(S==="system"&&matchMedia("(prefers-color-scheme:dark)").matches);var M=D?"dark":"light";document.documentElement.dataset.theme=T;document.documentElement.dataset.colorScheme=M;if(T==="oc-1")return;var K="${STORAGE_KEYS.THEME_CSS_PREFIX}-"+T+"-"+M;var C=localStorage.getItem(K);if(C){var s=document.createElement("style");s.id="oc-theme-preload";s.textContent=":root{color-scheme:"+M+";--text-mix-blend-mode:"+(D?"plus-lighter":"multiply")+";"+C+"}";document.head.appendChild(s)}})();` } /** @@ -62,15 +43,16 @@ export function generatePreloadScript(): string { * Useful for debugging. */ export function generatePreloadScriptFormatted(): string { - const defaults = generateEmbeddedDefaults() - return `(function() { var THEME_KEY = "${STORAGE_KEYS.THEME_ID}"; var SCHEME_KEY = "${STORAGE_KEYS.COLOR_SCHEME}"; var CSS_PREFIX = "${STORAGE_KEYS.THEME_CSS_PREFIX}"; - // Read preferences from localStorage - var themeId = localStorage.getItem(THEME_KEY) || "oc-1"; + // Only preload when a theme is selected + var themeId = localStorage.getItem(THEME_KEY); + if (!themeId) return; + + // Read color scheme preference var scheme = localStorage.getItem(SCHEME_KEY) || "system"; // Determine if dark mode @@ -78,17 +60,17 @@ export function generatePreloadScriptFormatted(): string { (scheme === "system" && matchMedia("(prefers-color-scheme: dark)").matches); var mode = isDark ? "dark" : "light"; + // Set data attributes for CSS/JS reference + document.documentElement.dataset.theme = themeId; + document.documentElement.dataset.colorScheme = mode; + + // Default theme is handled by theme.css + if (themeId === "oc-1") return; + // Try to get cached CSS for this theme + mode var cacheKey = CSS_PREFIX + "-" + themeId + "-" + mode; var css = localStorage.getItem(cacheKey); - // Fallback to embedded default for oc-1 theme - if (!css && themeId === "oc-1") { - css = isDark - ? ${JSON.stringify(defaults.dark)} - : ${JSON.stringify(defaults.light)}; - } - // Apply CSS if we have it if (css) { var style = document.createElement("style"); @@ -100,9 +82,5 @@ export function generatePreloadScriptFormatted(): string { "}"; document.head.appendChild(style); } - - // Set data attributes for CSS/JS reference - document.documentElement.dataset.theme = themeId; - document.documentElement.dataset.colorScheme = mode; })();` }