From a379eb38673aad097e1f178307865ec40a5ac3ea Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Tue, 24 Mar 2026 18:36:37 -0500 Subject: Revert "fix(app): startup efficiency (#18854)" This reverts commit 546748a461539ca63e188ee07ab2b143c5ac2c83. --- packages/ui/package.json | 1 - .../icons/provider/alibaba-coding-plan-cn.svg | 3 - .../assets/icons/provider/alibaba-coding-plan.svg | 3 - packages/ui/src/assets/icons/provider/clarifai.svg | 24 -- .../ui/src/assets/icons/provider/dinference.svg | 1 - packages/ui/src/assets/icons/provider/drun.svg | 8 - .../src/assets/icons/provider/perplexity-agent.svg | 3 - .../assets/icons/provider/tencent-coding-plan.svg | 5 - packages/ui/src/assets/icons/provider/zenmux.svg | 5 +- packages/ui/src/components/font.tsx | 119 ++++++++- packages/ui/src/font-loader.ts | 133 ---------- packages/ui/src/theme/context.tsx | 286 +++++---------------- 12 files changed, 189 insertions(+), 402 deletions(-) delete mode 100644 packages/ui/src/assets/icons/provider/alibaba-coding-plan-cn.svg delete mode 100644 packages/ui/src/assets/icons/provider/alibaba-coding-plan.svg delete mode 100644 packages/ui/src/assets/icons/provider/clarifai.svg delete mode 100644 packages/ui/src/assets/icons/provider/dinference.svg delete mode 100644 packages/ui/src/assets/icons/provider/drun.svg delete mode 100644 packages/ui/src/assets/icons/provider/perplexity-agent.svg delete mode 100644 packages/ui/src/assets/icons/provider/tencent-coding-plan.svg delete mode 100644 packages/ui/src/font-loader.ts (limited to 'packages/ui') diff --git a/packages/ui/package.json b/packages/ui/package.json index 7d4a39a26..cc6be2abe 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -12,7 +12,6 @@ "./hooks": "./src/hooks/index.ts", "./context": "./src/context/index.ts", "./context/*": "./src/context/*.tsx", - "./font-loader": "./src/font-loader.ts", "./styles": "./src/styles/index.css", "./styles/tailwind": "./src/styles/tailwind/index.css", "./theme": "./src/theme/index.ts", diff --git a/packages/ui/src/assets/icons/provider/alibaba-coding-plan-cn.svg b/packages/ui/src/assets/icons/provider/alibaba-coding-plan-cn.svg deleted file mode 100644 index b3a2edc3c..000000000 --- a/packages/ui/src/assets/icons/provider/alibaba-coding-plan-cn.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/packages/ui/src/assets/icons/provider/alibaba-coding-plan.svg b/packages/ui/src/assets/icons/provider/alibaba-coding-plan.svg deleted file mode 100644 index b3a2edc3c..000000000 --- a/packages/ui/src/assets/icons/provider/alibaba-coding-plan.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/packages/ui/src/assets/icons/provider/clarifai.svg b/packages/ui/src/assets/icons/provider/clarifai.svg deleted file mode 100644 index 086e9aa1f..000000000 --- a/packages/ui/src/assets/icons/provider/clarifai.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - diff --git a/packages/ui/src/assets/icons/provider/dinference.svg b/packages/ui/src/assets/icons/provider/dinference.svg deleted file mode 100644 index e045c96fb..000000000 --- a/packages/ui/src/assets/icons/provider/dinference.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/ui/src/assets/icons/provider/drun.svg b/packages/ui/src/assets/icons/provider/drun.svg deleted file mode 100644 index 472dee912..000000000 --- a/packages/ui/src/assets/icons/provider/drun.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/packages/ui/src/assets/icons/provider/perplexity-agent.svg b/packages/ui/src/assets/icons/provider/perplexity-agent.svg deleted file mode 100644 index a0f38862a..000000000 --- a/packages/ui/src/assets/icons/provider/perplexity-agent.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/packages/ui/src/assets/icons/provider/tencent-coding-plan.svg b/packages/ui/src/assets/icons/provider/tencent-coding-plan.svg deleted file mode 100644 index 502e51a5b..000000000 --- a/packages/ui/src/assets/icons/provider/tencent-coding-plan.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/packages/ui/src/assets/icons/provider/zenmux.svg b/packages/ui/src/assets/icons/provider/zenmux.svg index 9eb8045e4..d8d9ef665 100644 --- a/packages/ui/src/assets/icons/provider/zenmux.svg +++ b/packages/ui/src/assets/icons/provider/zenmux.svg @@ -1,4 +1,3 @@ - - - + + diff --git a/packages/ui/src/components/font.tsx b/packages/ui/src/components/font.tsx index e1a508f16..f735747a4 100644 --- a/packages/ui/src/components/font.tsx +++ b/packages/ui/src/components/font.tsx @@ -1,9 +1,121 @@ -import { Link, Style } from "@solidjs/meta" import { Show } from "solid-js" +import { Style, Link } from "@solidjs/meta" import inter from "../assets/fonts/inter.woff2" -import ibmPlexMonoBold from "../assets/fonts/ibm-plex-mono-bold.woff2" -import ibmPlexMonoMedium from "../assets/fonts/ibm-plex-mono-medium.woff2" import ibmPlexMonoRegular from "../assets/fonts/ibm-plex-mono.woff2" +import ibmPlexMonoMedium from "../assets/fonts/ibm-plex-mono-medium.woff2" +import ibmPlexMonoBold from "../assets/fonts/ibm-plex-mono-bold.woff2" + +import cascadiaCode from "../assets/fonts/cascadia-code-nerd-font.woff2" +import cascadiaCodeBold from "../assets/fonts/cascadia-code-nerd-font-bold.woff2" +import firaCode from "../assets/fonts/fira-code-nerd-font.woff2" +import firaCodeBold from "../assets/fonts/fira-code-nerd-font-bold.woff2" +import hack from "../assets/fonts/hack-nerd-font.woff2" +import hackBold from "../assets/fonts/hack-nerd-font-bold.woff2" +import inconsolata from "../assets/fonts/inconsolata-nerd-font.woff2" +import inconsolataBold from "../assets/fonts/inconsolata-nerd-font-bold.woff2" +import intelOneMono from "../assets/fonts/intel-one-mono-nerd-font.woff2" +import intelOneMonoBold from "../assets/fonts/intel-one-mono-nerd-font-bold.woff2" +import jetbrainsMono from "../assets/fonts/jetbrains-mono-nerd-font.woff2" +import jetbrainsMonoBold from "../assets/fonts/jetbrains-mono-nerd-font-bold.woff2" +import mesloLgs from "../assets/fonts/meslo-lgs-nerd-font.woff2" +import mesloLgsBold from "../assets/fonts/meslo-lgs-nerd-font-bold.woff2" +import robotoMono from "../assets/fonts/roboto-mono-nerd-font.woff2" +import robotoMonoBold from "../assets/fonts/roboto-mono-nerd-font-bold.woff2" +import sourceCodePro from "../assets/fonts/source-code-pro-nerd-font.woff2" +import sourceCodeProBold from "../assets/fonts/source-code-pro-nerd-font-bold.woff2" +import ubuntuMono from "../assets/fonts/ubuntu-mono-nerd-font.woff2" +import ubuntuMonoBold from "../assets/fonts/ubuntu-mono-nerd-font-bold.woff2" +import iosevka from "../assets/fonts/iosevka-nerd-font.woff2" +import iosevkaBold from "../assets/fonts/iosevka-nerd-font-bold.woff2" +import geistMono from "../assets/fonts/GeistMonoNerdFontMono-Regular.woff2" +import geistMonoBold from "../assets/fonts/GeistMonoNerdFontMono-Bold.woff2" + +type MonoFont = { + family: string + regular: string + bold: string +} + +export const MONO_NERD_FONTS = [ + { + family: "JetBrains Mono Nerd Font", + regular: jetbrainsMono, + bold: jetbrainsMonoBold, + }, + { + family: "Fira Code Nerd Font", + regular: firaCode, + bold: firaCodeBold, + }, + { + family: "Cascadia Code Nerd Font", + regular: cascadiaCode, + bold: cascadiaCodeBold, + }, + { + family: "Hack Nerd Font", + regular: hack, + bold: hackBold, + }, + { + family: "Source Code Pro Nerd Font", + regular: sourceCodePro, + bold: sourceCodeProBold, + }, + { + family: "Inconsolata Nerd Font", + regular: inconsolata, + bold: inconsolataBold, + }, + { + family: "Roboto Mono Nerd Font", + regular: robotoMono, + bold: robotoMonoBold, + }, + { + family: "Ubuntu Mono Nerd Font", + regular: ubuntuMono, + bold: ubuntuMonoBold, + }, + { + family: "Intel One Mono Nerd Font", + regular: intelOneMono, + bold: intelOneMonoBold, + }, + { + family: "Meslo LGS Nerd Font", + regular: mesloLgs, + bold: mesloLgsBold, + }, + { + family: "Iosevka Nerd Font", + regular: iosevka, + bold: iosevkaBold, + }, + { + family: "GeistMono Nerd Font", + regular: geistMono, + bold: geistMonoBold, + }, +] satisfies MonoFont[] + +const monoNerdCss = MONO_NERD_FONTS.map( + (font) => ` + @font-face { + font-family: "${font.family}"; + src: url("${font.regular}") format("woff2"); + font-display: swap; + font-style: normal; + font-weight: 400; + } + @font-face { + font-family: "${font.family}"; + src: url("${font.bold}") format("woff2"); + font-display: swap; + font-style: normal; + font-weight: 700; + }`, +).join("") export const Font = () => { return ( @@ -53,6 +165,7 @@ export const Font = () => { descent-override: 25%; line-gap-override: 1%; } +${monoNerdCss} `} diff --git a/packages/ui/src/font-loader.ts b/packages/ui/src/font-loader.ts deleted file mode 100644 index f2b1e6be1..000000000 --- a/packages/ui/src/font-loader.ts +++ /dev/null @@ -1,133 +0,0 @@ -type MonoFont = { - id: string - family: string - regular: string - bold: string -} - -let files: Record Promise> | undefined - -function getFiles() { - if (files) return files - files = import.meta.glob("./assets/fonts/*.woff2", { import: "default" }) as Record Promise> - return files -} - -export const MONO_NERD_FONTS = [ - { - id: "jetbrains-mono", - family: "JetBrains Mono Nerd Font", - regular: "./assets/fonts/jetbrains-mono-nerd-font.woff2", - bold: "./assets/fonts/jetbrains-mono-nerd-font-bold.woff2", - }, - { - id: "fira-code", - family: "Fira Code Nerd Font", - regular: "./assets/fonts/fira-code-nerd-font.woff2", - bold: "./assets/fonts/fira-code-nerd-font-bold.woff2", - }, - { - id: "cascadia-code", - family: "Cascadia Code Nerd Font", - regular: "./assets/fonts/cascadia-code-nerd-font.woff2", - bold: "./assets/fonts/cascadia-code-nerd-font-bold.woff2", - }, - { - id: "hack", - family: "Hack Nerd Font", - regular: "./assets/fonts/hack-nerd-font.woff2", - bold: "./assets/fonts/hack-nerd-font-bold.woff2", - }, - { - id: "source-code-pro", - family: "Source Code Pro Nerd Font", - regular: "./assets/fonts/source-code-pro-nerd-font.woff2", - bold: "./assets/fonts/source-code-pro-nerd-font-bold.woff2", - }, - { - id: "inconsolata", - family: "Inconsolata Nerd Font", - regular: "./assets/fonts/inconsolata-nerd-font.woff2", - bold: "./assets/fonts/inconsolata-nerd-font-bold.woff2", - }, - { - id: "roboto-mono", - family: "Roboto Mono Nerd Font", - regular: "./assets/fonts/roboto-mono-nerd-font.woff2", - bold: "./assets/fonts/roboto-mono-nerd-font-bold.woff2", - }, - { - id: "ubuntu-mono", - family: "Ubuntu Mono Nerd Font", - regular: "./assets/fonts/ubuntu-mono-nerd-font.woff2", - bold: "./assets/fonts/ubuntu-mono-nerd-font-bold.woff2", - }, - { - id: "intel-one-mono", - family: "Intel One Mono Nerd Font", - regular: "./assets/fonts/intel-one-mono-nerd-font.woff2", - bold: "./assets/fonts/intel-one-mono-nerd-font-bold.woff2", - }, - { - id: "meslo-lgs", - family: "Meslo LGS Nerd Font", - regular: "./assets/fonts/meslo-lgs-nerd-font.woff2", - bold: "./assets/fonts/meslo-lgs-nerd-font-bold.woff2", - }, - { - id: "iosevka", - family: "Iosevka Nerd Font", - regular: "./assets/fonts/iosevka-nerd-font.woff2", - bold: "./assets/fonts/iosevka-nerd-font-bold.woff2", - }, - { - id: "geist-mono", - family: "GeistMono Nerd Font", - regular: "./assets/fonts/GeistMonoNerdFontMono-Regular.woff2", - bold: "./assets/fonts/GeistMonoNerdFontMono-Bold.woff2", - }, -] satisfies MonoFont[] - -const mono = Object.fromEntries(MONO_NERD_FONTS.map((font) => [font.id, font])) as Record -const loads = new Map>() - -function css(font: { family: string; regular: string; bold: string }) { - return ` - @font-face { - font-family: "${font.family}"; - src: url("${font.regular}") format("woff2"); - font-display: swap; - font-style: normal; - font-weight: 400; - } - @font-face { - font-family: "${font.family}"; - src: url("${font.bold}") format("woff2"); - font-display: swap; - font-style: normal; - font-weight: 700; - } - ` -} - -export function ensureMonoFont(id: string | undefined) { - if (!id || id === "ibm-plex-mono") return Promise.resolve() - if (typeof document !== "object") return Promise.resolve() - const font = mono[id] - if (!font) return Promise.resolve() - const styleId = `oc-font-${font.id}` - if (document.getElementById(styleId)) return Promise.resolve() - const hit = loads.get(font.id) - if (hit) return hit - const files = getFiles() - const load = Promise.all([files[font.regular]?.(), files[font.bold]?.()]).then(([regular, bold]) => { - if (!regular || !bold) return - if (document.getElementById(styleId)) return - const style = document.createElement("style") - style.id = styleId - style.textContent = css({ family: font.family, regular, bold }) - document.head.appendChild(style) - }) - loads.set(font.id, load) - return load -} diff --git a/packages/ui/src/theme/context.tsx b/packages/ui/src/theme/context.tsx index 7d25ac397..9808c8e84 100644 --- a/packages/ui/src/theme/context.tsx +++ b/packages/ui/src/theme/context.tsx @@ -1,7 +1,7 @@ import { createEffect, onCleanup, onMount } from "solid-js" import { createStore } from "solid-js/store" import { createSimpleContext } from "../context/helper" -import oc2ThemeJson from "./themes/oc-2.json" +import { DEFAULT_THEMES } from "./default-themes" import { resolveThemeVariant, themeToCss } from "./resolve" import type { DesktopTheme } from "./types" @@ -15,101 +15,14 @@ const STORAGE_KEYS = { } as const const THEME_STYLE_ID = "oc-theme" -let files: Record Promise<{ default: DesktopTheme }>> | undefined -let ids: string[] | undefined -let known: Set | undefined - -function getFiles() { - if (files) return files - files = import.meta.glob<{ default: DesktopTheme }>("./themes/*.json") - return files -} - -function themeIDs() { - if (ids) return ids - ids = Object.keys(getFiles()) - .map((path) => path.slice("./themes/".length, -".json".length)) - .sort() - return ids -} - -function knownThemes() { - if (known) return known - known = new Set(themeIDs()) - return known -} - -const names: Record = { - "oc-2": "OC-2", - amoled: "AMOLED", - aura: "Aura", - ayu: "Ayu", - carbonfox: "Carbonfox", - catppuccin: "Catppuccin", - "catppuccin-frappe": "Catppuccin Frappe", - "catppuccin-macchiato": "Catppuccin Macchiato", - cobalt2: "Cobalt2", - cursor: "Cursor", - dracula: "Dracula", - everforest: "Everforest", - flexoki: "Flexoki", - github: "GitHub", - gruvbox: "Gruvbox", - kanagawa: "Kanagawa", - "lucent-orng": "Lucent Orng", - material: "Material", - matrix: "Matrix", - mercury: "Mercury", - monokai: "Monokai", - nightowl: "Night Owl", - nord: "Nord", - "one-dark": "One Dark", - onedarkpro: "One Dark Pro", - opencode: "OpenCode", - orng: "Orng", - "osaka-jade": "Osaka Jade", - palenight: "Palenight", - rosepine: "Rose Pine", - shadesofpurple: "Shades of Purple", - solarized: "Solarized", - synthwave84: "Synthwave '84", - tokyonight: "Tokyonight", - vercel: "Vercel", - vesper: "Vesper", - zenburn: "Zenburn", -} -const oc2Theme = oc2ThemeJson as DesktopTheme function normalize(id: string | null | undefined) { return id === "oc-1" ? "oc-2" : id } -function read(key: string) { - if (typeof localStorage !== "object") return null - try { - return localStorage.getItem(key) - } catch { - return null - } -} - -function write(key: string, value: string) { - if (typeof localStorage !== "object") return - try { - localStorage.setItem(key, value) - } catch {} -} - -function drop(key: string) { - if (typeof localStorage !== "object") return - try { - localStorage.removeItem(key) - } catch {} -} - function clear() { - drop(STORAGE_KEYS.THEME_CSS_LIGHT) - drop(STORAGE_KEYS.THEME_CSS_DARK) + localStorage.removeItem(STORAGE_KEYS.THEME_CSS_LIGHT) + localStorage.removeItem(STORAGE_KEYS.THEME_CSS_DARK) } function ensureThemeStyleElement(): HTMLStyleElement { @@ -122,7 +35,6 @@ function ensureThemeStyleElement(): HTMLStyleElement { } function getSystemMode(): "light" | "dark" { - if (typeof window !== "object") return "light" return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" } @@ -133,7 +45,9 @@ function applyThemeCss(theme: DesktopTheme, themeId: string, mode: "light" | "da const css = themeToCss(tokens) if (themeId !== "oc-2") { - write(isDark ? STORAGE_KEYS.THEME_CSS_DARK : STORAGE_KEYS.THEME_CSS_LIGHT, css) + try { + localStorage.setItem(isDark ? STORAGE_KEYS.THEME_CSS_DARK : STORAGE_KEYS.THEME_CSS_LIGHT, css) + } catch {} } const fullCss = `:root { @@ -155,122 +69,74 @@ function cacheThemeVariants(theme: DesktopTheme, themeId: string) { const variant = isDark ? theme.dark : theme.light const tokens = resolveThemeVariant(variant, isDark) const css = themeToCss(tokens) - write(isDark ? STORAGE_KEYS.THEME_CSS_DARK : STORAGE_KEYS.THEME_CSS_LIGHT, css) + try { + localStorage.setItem(isDark ? STORAGE_KEYS.THEME_CSS_DARK : STORAGE_KEYS.THEME_CSS_LIGHT, css) + } catch {} } } export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({ name: "Theme", init: (props: { defaultTheme?: string; onThemeApplied?: (theme: DesktopTheme, mode: "light" | "dark") => void }) => { - const themeId = normalize(read(STORAGE_KEYS.THEME_ID) ?? props.defaultTheme) ?? "oc-2" - const colorScheme = (read(STORAGE_KEYS.COLOR_SCHEME) as ColorScheme | null) ?? "system" - const mode = colorScheme === "system" ? getSystemMode() : colorScheme const [store, setStore] = createStore({ - themes: { - "oc-2": oc2Theme, - } as Record, - themeId, - colorScheme, - mode, + themes: DEFAULT_THEMES as Record, + themeId: normalize(props.defaultTheme) ?? "oc-2", + colorScheme: "system" as ColorScheme, + mode: getSystemMode(), previewThemeId: null as string | null, previewScheme: null as ColorScheme | null, }) - const loads = new Map>() - - const load = (id: string) => { - const next = normalize(id) - if (!next) return Promise.resolve(undefined) - const hit = store.themes[next] - if (hit) return Promise.resolve(hit) - const pending = loads.get(next) - if (pending) return pending - const file = getFiles()[`./themes/${next}.json`] - if (!file) return Promise.resolve(undefined) - const task = file() - .then((mod) => { - const theme = mod.default - setStore("themes", next, theme) - return theme - }) - .finally(() => { - loads.delete(next) - }) - loads.set(next, task) - return task - } - - const applyTheme = (theme: DesktopTheme, themeId: string, mode: "light" | "dark") => { - applyThemeCss(theme, themeId, mode) - props.onThemeApplied?.(theme, mode) - } - - const ids = () => { - const extra = Object.keys(store.themes) - .filter((id) => !knownThemes().has(id)) - .sort() - const all = themeIDs() - if (extra.length === 0) return all - return [...all, ...extra] - } - - const loadThemes = () => Promise.all(themeIDs().map(load)).then(() => store.themes) - - const onStorage = (e: StorageEvent) => { - if (e.key === STORAGE_KEYS.THEME_ID && e.newValue) { - const next = normalize(e.newValue) - if (!next) return - if (next !== "oc-2" && !knownThemes().has(next) && !store.themes[next]) return - setStore("themeId", next) - if (next === "oc-2") { - clear() - return - } - void load(next).then((theme) => { - if (!theme || store.themeId !== next) return - cacheThemeVariants(theme, next) - }) - } + window.addEventListener("storage", (e) => { + if (e.key === STORAGE_KEYS.THEME_ID && e.newValue) setStore("themeId", e.newValue) if (e.key === STORAGE_KEYS.COLOR_SCHEME && e.newValue) { setStore("colorScheme", e.newValue as ColorScheme) - setStore("mode", e.newValue === "system" ? getSystemMode() : (e.newValue as "light" | "dark")) + setStore("mode", e.newValue === "system" ? getSystemMode() : (e.newValue as any)) } - } - - if (typeof window === "object") { - window.addEventListener("storage", onStorage) - onCleanup(() => window.removeEventListener("storage", onStorage)) - } + }) onMount(() => { const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)") - const onMedia = () => { - if (store.colorScheme !== "system") return - setStore("mode", getSystemMode()) + const handler = () => { + if (store.colorScheme === "system") { + setStore("mode", getSystemMode()) + } } - mediaQuery.addEventListener("change", onMedia) - onCleanup(() => mediaQuery.removeEventListener("change", onMedia)) - - const rawTheme = read(STORAGE_KEYS.THEME_ID) - const savedTheme = normalize(rawTheme ?? props.defaultTheme) ?? "oc-2" - const savedScheme = (read(STORAGE_KEYS.COLOR_SCHEME) as ColorScheme | null) ?? "system" - if (rawTheme && rawTheme !== savedTheme) { - write(STORAGE_KEYS.THEME_ID, savedTheme) + mediaQuery.addEventListener("change", handler) + onCleanup(() => mediaQuery.removeEventListener("change", handler)) + + const savedTheme = localStorage.getItem(STORAGE_KEYS.THEME_ID) + const themeId = normalize(savedTheme) + const savedScheme = localStorage.getItem(STORAGE_KEYS.COLOR_SCHEME) as ColorScheme | null + if (themeId && store.themes[themeId]) { + setStore("themeId", themeId) + } + if (savedTheme && themeId && savedTheme !== themeId) { + localStorage.setItem(STORAGE_KEYS.THEME_ID, themeId) clear() } - if (savedTheme !== store.themeId) setStore("themeId", savedTheme) - if (savedScheme !== store.colorScheme) setStore("colorScheme", savedScheme) - setStore("mode", savedScheme === "system" ? getSystemMode() : savedScheme) - void load(savedTheme).then((theme) => { - if (!theme || store.themeId !== savedTheme) return - cacheThemeVariants(theme, savedTheme) - }) + if (savedScheme) { + setStore("colorScheme", savedScheme) + if (savedScheme !== "system") { + setStore("mode", savedScheme) + } + } + const currentTheme = store.themes[store.themeId] + if (currentTheme) { + cacheThemeVariants(currentTheme, store.themeId) + } }) + const applyTheme = (theme: DesktopTheme, themeId: string, mode: "light" | "dark") => { + applyThemeCss(theme, themeId, mode) + props.onThemeApplied?.(theme, mode) + } + createEffect(() => { const theme = store.themes[store.themeId] - if (!theme) return - applyTheme(theme, store.themeId, store.mode) + if (theme) { + applyTheme(theme, store.themeId, store.mode) + } }) const setTheme = (id: string) => { @@ -279,26 +145,23 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({ console.warn(`Theme "${id}" not found`) return } - if (next !== "oc-2" && !knownThemes().has(next) && !store.themes[next]) { + const theme = store.themes[next] + if (!theme) { console.warn(`Theme "${id}" not found`) return } setStore("themeId", next) + localStorage.setItem(STORAGE_KEYS.THEME_ID, next) if (next === "oc-2") { - write(STORAGE_KEYS.THEME_ID, next) clear() return } - void load(next).then((theme) => { - if (!theme || store.themeId !== next) return - cacheThemeVariants(theme, next) - write(STORAGE_KEYS.THEME_ID, next) - }) + cacheThemeVariants(theme, next) } const setColorScheme = (scheme: ColorScheme) => { setStore("colorScheme", scheme) - write(STORAGE_KEYS.COLOR_SCHEME, scheme) + localStorage.setItem(STORAGE_KEYS.COLOR_SCHEME, scheme) setStore("mode", scheme === "system" ? getSystemMode() : scheme) } @@ -306,9 +169,6 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({ themeId: () => store.themeId, colorScheme: () => store.colorScheme, mode: () => store.mode, - ids, - name: (id: string) => store.themes[id]?.name ?? names[id] ?? id, - loadThemes, themes: () => store.themes, setTheme, setColorScheme, @@ -316,28 +176,24 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({ previewTheme: (id: string) => { const next = normalize(id) if (!next) return - if (next !== "oc-2" && !knownThemes().has(next) && !store.themes[next]) return + const theme = store.themes[next] + if (!theme) return setStore("previewThemeId", next) - void load(next).then((theme) => { - if (!theme || store.previewThemeId !== next) return - const mode = store.previewScheme - ? store.previewScheme === "system" - ? getSystemMode() - : store.previewScheme - : store.mode - applyTheme(theme, next, mode) - }) + const previewMode = store.previewScheme + ? store.previewScheme === "system" + ? getSystemMode() + : store.previewScheme + : store.mode + applyTheme(theme, next, previewMode) }, previewColorScheme: (scheme: ColorScheme) => { setStore("previewScheme", scheme) - const mode = scheme === "system" ? getSystemMode() : scheme + const previewMode = scheme === "system" ? getSystemMode() : scheme const id = store.previewThemeId ?? store.themeId - void load(id).then((theme) => { - if (!theme) return - if ((store.previewThemeId ?? store.themeId) !== id) return - if (store.previewScheme !== scheme) return - applyTheme(theme, id, mode) - }) + const theme = store.themes[id] + if (theme) { + applyTheme(theme, id, previewMode) + } }, commitPreview: () => { if (store.previewThemeId) { @@ -352,10 +208,10 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({ cancelPreview: () => { setStore("previewThemeId", null) setStore("previewScheme", null) - void load(store.themeId).then((theme) => { - if (!theme) return + const theme = store.themes[store.themeId] + if (theme) { applyTheme(theme, store.themeId, store.mode) - }) + } }, } }, -- cgit v1.2.3