From 751e411b3ab321129083f86f0be53687185abd87 Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Mon, 1 Jun 2026 09:15:43 +0900 Subject: feat(settings): inline theme picker into Settings panel The Theme button + ThemeSwitcher modal were a header-triggered modal. That doesn't belong in a sidebar-panel architecture, and theme picking is a UI preference that belongs alongside the other Settings entries. - Add a "Theme" section as the first block in SettingsPanel with the same theme list as ThemeSwitcher. - The localStorage key (`dispatch-theme`) and apply-on-change behavior are unchanged, so the boot-time theme apply in App.svelte's onMount keeps working without modification. - Delete the now-unused ThemeSwitcher.svelte component; no remaining importers. --- .../src/lib/components/SettingsPanel.svelte | 52 +++++++++++++++++++ .../src/lib/components/ThemeSwitcher.svelte | 58 ---------------------- 2 files changed, 52 insertions(+), 58 deletions(-) delete mode 100644 packages/frontend/src/lib/components/ThemeSwitcher.svelte diff --git a/packages/frontend/src/lib/components/SettingsPanel.svelte b/packages/frontend/src/lib/components/SettingsPanel.svelte index 392852a..efbaf5f 100644 --- a/packages/frontend/src/lib/components/SettingsPanel.svelte +++ b/packages/frontend/src/lib/components/SettingsPanel.svelte @@ -11,6 +11,42 @@ const { apiBase?: string; } = $props(); +// Theme picker — was a header-triggered modal (`ThemeSwitcher.svelte`); +// inlined here so theme picking lives in Settings alongside other UI +// preferences. The list and localStorage key must stay in sync with the +// boot-time theme apply in `App.svelte`'s `onMount`. +const THEMES = [ + "light", + "dark", + "dracula", + "night", + "nord", + "sunset", + "cyberpunk", + "forest", + "cmyk", + "coffee", + "caramellatte", + "garden", + "luxury", +] as const; + +const THEME_STORAGE_KEY = "dispatch-theme"; + +let currentTheme = $state( + (typeof localStorage !== "undefined" && localStorage.getItem(THEME_STORAGE_KEY)) || "dark", +); + +function selectTheme(theme: string): void { + currentTheme = theme; + document.documentElement.setAttribute("data-theme", theme); + try { + localStorage.setItem(THEME_STORAGE_KEY, theme); + } catch { + // Best-effort — private mode / quota. + } +} + let titleKeyId = $state(null); let titleModelId = $state(null); let availableModels = $state([]); @@ -136,6 +172,22 @@ $effect(() => {
Settings
+

Theme

+ + +
+

Title Generation Model

Used to generate short titles for new tabs after the first message.

diff --git a/packages/frontend/src/lib/components/ThemeSwitcher.svelte b/packages/frontend/src/lib/components/ThemeSwitcher.svelte deleted file mode 100644 index 418fcea..0000000 --- a/packages/frontend/src/lib/components/ThemeSwitcher.svelte +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - -- cgit v1.2.3