summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSebastian <[email protected]>2026-03-24 10:00:19 +0100
committerGitHub <[email protected]>2026-03-24 10:00:19 +0100
commitd3debc191f116f8ed005bf0c3ddc8776546d53cd (patch)
treef32a0a9081e86ecf8ed5f24f1842f7c35f858d08
parent34f43fff89d14c72aada06e0dc1d9228ec4d667d (diff)
downloadopencode-d3debc191f116f8ed005bf0c3ddc8776546d53cd.tar.gz
opencode-d3debc191f116f8ed005bf0c3ddc8776546d53cd.zip
manually lock/unlock theme mode (#18905)
-rw-r--r--packages/opencode/src/cli/cmd/tui/app.tsx14
-rw-r--r--packages/opencode/src/cli/cmd/tui/context/theme.tsx39
2 files changed, 46 insertions, 7 deletions
diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx
index dc052c4d2..549c7c34a 100644
--- a/packages/opencode/src/cli/cmd/tui/app.tsx
+++ b/packages/opencode/src/cli/cmd/tui/app.tsx
@@ -212,7 +212,7 @@ function App() {
const command = useCommandDialog()
const sdk = useSDK()
const toast = useToast()
- const { theme, mode, setMode } = useTheme()
+ const { theme, mode, setMode, locked, lock, unlock } = useTheme()
const sync = useSync()
const exit = useExit()
const promptRef = usePromptRef()
@@ -557,7 +557,7 @@ function App() {
category: "System",
},
{
- title: "Toggle appearance",
+ title: "Toggle Theme Mode",
value: "theme.switch_mode",
onSelect: (dialog) => {
setMode(mode() === "dark" ? "light" : "dark")
@@ -566,6 +566,16 @@ function App() {
category: "System",
},
{
+ title: locked() ? "Unlock Theme Mode" : "Lock Theme Mode",
+ value: "theme.mode.lock",
+ onSelect: (dialog) => {
+ if (locked()) unlock()
+ else lock()
+ dialog.clear()
+ },
+ category: "System",
+ },
+ {
title: "Help",
value: "help.show",
slash: {
diff --git a/packages/opencode/src/cli/cmd/tui/context/theme.tsx b/packages/opencode/src/cli/cmd/tui/context/theme.tsx
index d786e0b49..a3d268afd 100644
--- a/packages/opencode/src/cli/cmd/tui/context/theme.tsx
+++ b/packages/opencode/src/cli/cmd/tui/context/theme.tsx
@@ -283,9 +283,15 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
const renderer = useRenderer()
const config = useTuiConfig()
const kv = useKV()
+ const pick = (value: unknown) => {
+ if (value === "dark" || value === "light") return value
+ return
+ }
+ const lock = pick(kv.get("theme_mode_lock"))
const [store, setStore] = createStore({
themes: DEFAULT_THEMES,
- mode: kv.get("theme_mode", props.mode),
+ mode: lock ?? pick(kv.get("theme_mode", props.mode)) ?? props.mode,
+ lock,
active: (config.theme ?? kv.get("theme", "opencode")) as string,
ready: false,
})
@@ -345,16 +351,30 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
})
}
- function update(mode: "dark" | "light") {
+ function apply(mode: "dark" | "light") {
+ kv.set("theme_mode", mode)
if (store.mode === mode) return
setStore("mode", mode)
- kv.set("theme_mode", mode)
renderer.clearPaletteCache()
resolveSystemTheme(mode)
}
+ function pin(mode: "dark" | "light" = store.mode) {
+ setStore("lock", mode)
+ kv.set("theme_mode_lock", mode)
+ apply(mode)
+ }
+
+ function free() {
+ setStore("lock", undefined)
+ kv.set("theme_mode_lock", undefined)
+ const mode = renderer.themeMode
+ if (mode) apply(mode)
+ }
+
const handle = (mode: "dark" | "light") => {
- update(mode)
+ if (store.lock) return
+ apply(mode)
}
renderer.on(CliRenderEvents.THEME_MODE, handle)
onCleanup(() => {
@@ -390,8 +410,17 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({
mode() {
return store.mode
},
+ locked() {
+ return store.lock !== undefined
+ },
+ lock() {
+ pin(store.mode)
+ },
+ unlock() {
+ free()
+ },
setMode(mode: "dark" | "light") {
- update(mode)
+ pin(mode)
},
set(theme: string) {
setStore("active", theme)