|
|
@@ -1,5 +1,6 @@
|
|
|
import { SyntaxStyle, RGBA, type TerminalColors } from "@opentui/core"
|
|
|
-import { createMemo } from "solid-js"
|
|
|
+import path from "path"
|
|
|
+import { createEffect, createMemo, onMount } from "solid-js"
|
|
|
import { useSync } from "@tui/context/sync"
|
|
|
import { createSimpleContext } from "./helper"
|
|
|
import aura from "./theme/aura.json" with { type: "json" }
|
|
|
@@ -27,7 +28,9 @@ import vesper from "./theme/vesper.json" with { type: "json" }
|
|
|
import zenburn from "./theme/zenburn.json" with { type: "json" }
|
|
|
import { useKV } from "./kv"
|
|
|
import { useRenderer } from "@opentui/solid"
|
|
|
-import { createStore } from "solid-js/store"
|
|
|
+import { createStore, produce } from "solid-js/store"
|
|
|
+import { Global } from "@/global"
|
|
|
+import { Filesystem } from "@/util/filesystem"
|
|
|
|
|
|
type Theme = {
|
|
|
primary: RGBA
|
|
|
@@ -144,6 +147,17 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
|
|
|
themes: DEFAULT_THEMES,
|
|
|
mode: props.mode,
|
|
|
active: (sync.data.config.theme ?? kv.get("theme", "opencode")) as string,
|
|
|
+ ready: false,
|
|
|
+ })
|
|
|
+
|
|
|
+ createEffect(async () => {
|
|
|
+ const custom = await getCustomThemes()
|
|
|
+ setStore(
|
|
|
+ produce((draft) => {
|
|
|
+ Object.assign(draft.themes, custom)
|
|
|
+ draft.ready = true
|
|
|
+ }),
|
|
|
+ )
|
|
|
})
|
|
|
|
|
|
const renderer = useRenderer()
|
|
|
@@ -187,12 +201,39 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
|
|
|
kv.set("theme", theme)
|
|
|
},
|
|
|
get ready() {
|
|
|
- return sync.ready
|
|
|
+ return store.ready
|
|
|
},
|
|
|
}
|
|
|
},
|
|
|
})
|
|
|
|
|
|
+const CUSTOM_THEME_GLOB = new Bun.Glob("themes/*.json")
|
|
|
+async function getCustomThemes() {
|
|
|
+ const directories = [
|
|
|
+ Global.Path.config,
|
|
|
+ ...(await Array.fromAsync(
|
|
|
+ Filesystem.up({
|
|
|
+ targets: [".opencode"],
|
|
|
+ start: process.cwd(),
|
|
|
+ }),
|
|
|
+ )),
|
|
|
+ ]
|
|
|
+
|
|
|
+ const result: Record<string, ThemeJson> = {}
|
|
|
+ for (const dir of directories) {
|
|
|
+ for await (const item of CUSTOM_THEME_GLOB.scan({
|
|
|
+ absolute: true,
|
|
|
+ followSymlinks: true,
|
|
|
+ dot: true,
|
|
|
+ cwd: dir,
|
|
|
+ })) {
|
|
|
+ const name = path.basename(item, ".json")
|
|
|
+ result[name] = await Bun.file(item).json()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result
|
|
|
+}
|
|
|
+
|
|
|
function generateSystem(colors: TerminalColors, mode: "dark" | "light"): ThemeJson {
|
|
|
const bg = RGBA.fromHex(colors.defaultBackground ?? colors.palette[0]!)
|
|
|
const fg = RGBA.fromHex(colors.defaultForeground ?? colors.palette[7]!)
|