still self referencing

This commit is contained in:
2026-02-05 01:43:10 -05:00
parent ea9ab4d3f9
commit 9fa52d71ca
13 changed files with 263 additions and 141 deletions

View File

@@ -1,23 +1,30 @@
import path from "path"
import { mkdir } from "fs/promises"
import type { ThemeJson } from "../types/theme-schema"
import { THEME_JSON } from "../constants/themes"
import { validateTheme } from "./theme-loader"
export async function getCustomThemes() {
const dirs = [
path.join(process.env.HOME ?? "", ".config/podtui/themes"),
path.resolve(process.cwd(), ".podtui/themes"),
path.resolve(process.cwd(), "themes"),
]
const home = process.env.HOME ?? ""
if (!home) return {}
const dir = path.join(home, ".config/podtui/themes")
await mkdir(dir, { recursive: true })
for (const [name, theme] of Object.entries(THEME_JSON)) {
const file = path.join(dir, `${name}.json`)
const exists = await Bun.file(file).exists()
if (exists) continue
await Bun.write(file, JSON.stringify(theme, null, 2))
}
const result: Record<string, ThemeJson> = {}
for (const dir of dirs) {
const glob = new Bun.Glob("*.json")
for await (const item of glob.scan({ absolute: true, followSymlinks: true, cwd: dir })) {
const name = path.basename(item, ".json")
const json = (await Bun.file(item).json()) as ThemeJson
validateTheme(json, item)
result[name] = json
}
const glob = new Bun.Glob("*.json")
for await (const item of glob.scan({ absolute: true, followSymlinks: true, cwd: dir })) {
const name = path.basename(item, ".json")
const json = (await Bun.file(item).json()) as ThemeJson
validateTheme(json, item)
result[name] = json
}
return result
}

View File

@@ -5,6 +5,9 @@ import { ansiToRgba } from "./ansi-to-rgba"
export type ThemeMode = "dark" | "light"
export function resolveTheme(theme: ThemeJson, mode: ThemeMode) {
if (!theme || !theme.theme) {
throw new Error("Invalid theme: missing theme object")
}
const defs = theme.defs ?? {}
function resolveColor(value: ColorValue): RGBA {
@@ -38,8 +41,21 @@ export function resolveTheme(theme: ThemeJson, mode: ThemeMode) {
const thinkingOpacity = theme.theme.thinkingOpacity ?? 0.6
const background = resolved.background
const backgroundPanel = resolved.backgroundPanel ?? background
const backgroundElement = resolved.backgroundElement ?? backgroundPanel
const backgroundMenu = resolved.backgroundMenu ?? backgroundElement
return {
...resolved,
muted: resolved.textMuted ?? resolved.muted,
surface: resolved.backgroundPanel ?? resolved.surface,
layerBackgrounds: {
layer0: background,
layer1: backgroundPanel,
layer2: backgroundElement,
layer3: backgroundMenu,
},
_hasSelectedListItemText: hasSelected,
thinkingOpacity,
}

View File

@@ -3,9 +3,13 @@
* Handles dynamic theme switching by updating CSS custom properties
*/
import { RGBA } from "@opentui/core"
import { RGBA, type TerminalColors } from "@opentui/core"
import type { ThemeColors } from "../types/settings"
import type { ColorValue } from "../types/theme-schema"
import type { ColorValue, ThemeJson } from "../types/theme-schema"
import { THEME_JSON } from "../constants/themes"
import { getCustomThemes } from "./custom-themes"
import { resolveTheme as resolveThemeJson } from "./theme-resolver"
import { generateSystemTheme } from "./system-theme"
const toCss = (value: ColorValue | RGBA) => {
if (value instanceof RGBA) {
@@ -60,3 +64,32 @@ export function setThemeAttribute(themeName: string) {
const root = document.documentElement
root.setAttribute("data-theme", themeName)
}
export async function loadThemes() {
return await getCustomThemes()
}
export async function loadTheme(name: string) {
const themes = await loadThemes()
return themes[name]
}
export function resolveTheme(theme: ThemeJson, mode: "dark" | "light") {
return resolveThemeJson(theme, mode)
}
export function resolveTerminalTheme(
themes: Record<string, ThemeJson>,
name: string,
mode: "dark" | "light",
system?: TerminalColors
) {
if (name === "system" && system) {
return resolveThemeJson(generateSystemTheme(system, mode), mode)
}
const theme = themes[name] ?? themes.opencode
if (!theme) {
return resolveThemeJson(THEME_JSON.opencode, mode)
}
return resolveThemeJson(theme, mode)
}