feat: toggle transparent background

This commit is contained in:
JosXa 2025-12-17 02:29:53 +01:00
parent c137babea3
commit 003dafc534
2 changed files with 31 additions and 7 deletions

View file

@ -2,9 +2,8 @@ import { render, useKeyboard, useRenderer, useTerminalDimensions } from "@opentu
import { Clipboard } from "@tui/util/clipboard"
import { TextAttributes } from "@opentui/core"
import { RouteProvider, useRoute } from "@tui/context/route"
import { Switch, Match, createEffect, untrack, ErrorBoundary, createSignal, onMount, batch, Show, on } from "solid-js"
import { Switch, Match, createEffect, untrack, ErrorBoundary, createSignal, onMount, batch, on } from "solid-js"
import { Installation } from "@/installation"
import { Global } from "@/global"
import { Flag } from "@/flag/flag"
import { DialogProvider, useDialog } from "@tui/ui/dialog"
import { DialogProvider as DialogProviderList } from "@tui/component/dialog-provider"
@ -163,7 +162,7 @@ function App() {
const command = useCommandDialog()
const { event } = useSDK()
const toast = useToast()
const { theme, mode, setMode } = useTheme()
const { theme, mode, setMode, transparent, setTransparent } = useTheme()
const sync = useSync()
const exit = useExit()
const promptRef = usePromptRef()
@ -387,6 +386,15 @@ function App() {
},
category: "System",
},
{
title: "Toggle transparency",
value: "theme.transparency",
onSelect: (dialog) => {
setTransparent(!transparent())
dialog.clear()
},
category: "System",
},
{
title: "Help",
value: "help.show",

View file

@ -1,6 +1,6 @@
import { SyntaxStyle, RGBA, type TerminalColors } from "@opentui/core"
import path from "path"
import { createEffect, createMemo, onMount } from "solid-js"
import { createEffect, createMemo } from "solid-js"
import { useSync } from "@tui/context/sync"
import { createSimpleContext } from "./helper"
import aura from "./theme/aura.json" with { type: "json" }
@ -95,6 +95,7 @@ type ThemeColors = {
type Theme = ThemeColors & {
_hasSelectedListItemText: boolean
thinkingOpacity: number
transparent: boolean
}
export function selectedForeground(theme: Theme): RGBA {
@ -157,12 +158,12 @@ export const DEFAULT_THEMES: Record<string, ThemeJson> = {
solarized,
synthwave84,
tokyonight,
vesper,
vercel,
vesper,
zenburn,
}
function resolveTheme(theme: ThemeJson, mode: "dark" | "light") {
function resolveTheme(theme: ThemeJson, mode: "dark" | "light", transparent: boolean) {
const defs = theme.defs ?? {}
function resolveColor(c: ColorValue): RGBA {
if (c instanceof RGBA) return c
@ -213,10 +214,17 @@ function resolveTheme(theme: ThemeJson, mode: "dark" | "light") {
// Handle thinkingOpacity - optional with default of 0.6
const thinkingOpacity = theme.theme.thinkingOpacity ?? 0.6
if (transparent) {
resolved.background = RGBA.fromInts(0, 0, 0, 0)
// NOTE: Could alternatively apply an alpha channel to the theme's base background color
// instead of forcing full transparency, allowing for adjustable opacity levels
}
return {
...resolved,
_hasSelectedListItemText: hasSelectedListItemText,
thinkingOpacity,
transparent,
} as Theme
}
@ -274,6 +282,7 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
themes: DEFAULT_THEMES,
mode: kv.get("theme_mode", props.mode),
active: (sync.data.config.theme ?? kv.get("theme", "opencode")) as string,
transparent: kv.get("theme_transparent", false),
ready: false,
})
@ -298,7 +307,7 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
})
const values = createMemo(() => {
return resolveTheme(store.themes[store.active] ?? store.themes.opencode, store.mode)
return resolveTheme(store.themes[store.active] ?? store.themes.opencode, store.mode, store.transparent)
})
const syntax = createMemo(() => generateSyntax(values()))
@ -330,6 +339,13 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
setStore("active", theme)
kv.set("theme", theme)
},
transparent() {
return store.transparent
},
setTransparent(transparent: boolean) {
setStore("transparent", transparent)
kv.set("theme_transparent", transparent)
},
get ready() {
return store.ready
},