chore: cleanup

This commit is contained in:
Adam
2025-12-28 06:41:54 -06:00
parent 69a15ae9c1
commit 82a876da4d
6 changed files with 85 additions and 85 deletions

View File

@@ -13,9 +13,36 @@
<meta name="theme-color" content="#131010" media="(prefers-color-scheme: dark)" />
<meta property="og:image" content="/social-share.png" />
<meta property="twitter:image" content="/social-share.png" />
<!-- Theme preload script - injected by Vite plugin to avoid FOUC -->
<!-- Theme preload script - applies cached theme to avoid FOUC -->
<script id="oc-theme-preload-script">
/* THEME_PRELOAD_SCRIPT */
;(function () {
var themeId = localStorage.getItem("opencode-theme-id")
if (!themeId) return
var scheme = localStorage.getItem("opencode-color-scheme") || "system"
var isDark = scheme === "dark" || (scheme === "system" && matchMedia("(prefers-color-scheme: dark)").matches)
var mode = isDark ? "dark" : "light"
document.documentElement.dataset.theme = themeId
document.documentElement.dataset.colorScheme = mode
if (themeId === "oc-1") return
var css = localStorage.getItem("opencode-theme-css-" + themeId + "-" + mode)
if (css) {
var style = document.createElement("style")
style.id = "oc-theme-preload"
style.textContent =
":root{color-scheme:" +
mode +
";--text-mix-blend-mode:" +
(isDark ? "plus-lighter" : "multiply") +
";" +
css +
"}"
document.head.appendChild(style)
}
})()
</script>
</head>
<body class="antialiased overscroll-none text-12-regular overflow-hidden">

View File

@@ -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(
/<script id="oc-theme-preload-script">\s*\/\* THEME_PRELOAD_SCRIPT \*\/\s*<\/script>/,
`<script id="oc-theme-preload-script">${script}</script>`,
)
await Bun.write(htmlPath, injectedHtml)
console.log("Injected theme preload script into index.html")

View File

@@ -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(
/<script id="oc-theme-preload-script">\s*\/\* THEME_PRELOAD_SCRIPT \*\/\s*<\/script>/,
`<script id="oc-theme-preload-script">${script}</script>`,
)
},
}
/**
* @type {import("vite").PluginOption}
@@ -38,7 +21,6 @@ export default [
}
},
},
themePreloadPlugin,
tailwindcss(),
solidPlugin(),
]

View File

@@ -13,9 +13,36 @@
<meta name="theme-color" content="#131010" media="(prefers-color-scheme: dark)" />
<meta property="og:image" content="/social-share.png" />
<meta property="twitter:image" content="/social-share.png" />
<!-- Theme preload script - injected by Vite plugin to avoid FOUC -->
<!-- Theme preload script - applies cached theme to avoid FOUC -->
<script id="oc-theme-preload-script">
/* THEME_PRELOAD_SCRIPT */
;(function () {
var themeId = localStorage.getItem("opencode-theme-id")
if (!themeId) return
var scheme = localStorage.getItem("opencode-color-scheme") || "system"
var isDark = scheme === "dark" || (scheme === "system" && matchMedia("(prefers-color-scheme: dark)").matches)
var mode = isDark ? "dark" : "light"
document.documentElement.dataset.theme = themeId
document.documentElement.dataset.colorScheme = mode
if (themeId === "oc-1") return
var css = localStorage.getItem("opencode-theme-css-" + themeId + "-" + mode)
if (css) {
var style = document.createElement("style")
style.id = "oc-theme-preload"
style.textContent =
":root{color-scheme:" +
mode +
";--text-mix-blend-mode:" +
(isDark ? "plus-lighter" : "multiply") +
";" +
css +
"}"
document.head.appendChild(style)
}
})()
</script>
</head>
<body class="antialiased overscroll-none text-12-regular overflow-hidden">

View File

@@ -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

View File

@@ -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 <head> 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 <head> 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;
})();`
}