import { Select } from "@kobalte/core/select" import { createEffect, createMemo, createSignal, For, type Component } from "solid-js" import { Check, ChevronDown, Laptop, Moon, Sun } from "lucide-solid" import { useI18n } from "../../lib/i18n" import { useTheme, type ThemeMode } from "../../lib/theme" import { useConfig } from "../../stores/preferences" import { getBehaviorSettings, type BehaviorSetting } from "../../lib/settings/behavior-registry" const themeModeOptions: Array<{ value: ThemeMode; icon: typeof Laptop }> = [ { value: "system", icon: Laptop }, { value: "light", icon: Sun }, { value: "dark", icon: Moon }, ] export const AppearanceSettingsSection: Component = () => { const { t } = useI18n() const { themeMode, setThemeMode } = useTheme() const { preferences, updatePreferences, toggleShowThinkingBlocks, toggleKeyboardShortcutHints, toggleShowTimelineTools, toggleUsageMetrics, toggleAutoCleanupBlankSessions, togglePromptSubmitOnEnter, toggleShowPromptVoiceInput, setDiffViewMode, setToolOutputExpansion, setDiagnosticsExpansion, setThinkingBlocksExpansion, setToolInputsVisibility, } = useConfig() const behaviorSettings = createMemo(() => getBehaviorSettings({ preferences, updatePreferences, toggleShowThinkingBlocks, toggleKeyboardShortcutHints, toggleShowTimelineTools, toggleUsageMetrics, toggleAutoCleanupBlankSessions, togglePromptSubmitOnEnter, toggleShowPromptVoiceInput, setDiffViewMode, setToolOutputExpansion, setDiagnosticsExpansion, setThinkingBlocksExpansion, setToolInputsVisibility, }), ) const [overrides, setOverrides] = createSignal>(new Map()) const setOverride = (id: string, value: unknown) => { setOverrides((prev) => { const next = new Map(prev) next.set(id, value) return next }) } createEffect(() => { const current = overrides() if (current.size === 0) return const prefs = preferences() const settings = behaviorSettings() let changed = false const next = new Map(current) for (const setting of settings) { if (!next.has(setting.id)) continue const overrideValue = next.get(setting.id) const actualValue = setting.get(prefs) if (Object.is(actualValue, overrideValue)) { next.delete(setting.id) changed = true } } if (changed) { setOverrides(next) } }) const readSettingValue = (setting: BehaviorSetting) => { const current = overrides() if (current.has(setting.id)) return current.get(setting.id) return setting.get(preferences()) } type SelectOption = { value: string; label: string } const BehaviorRow: Component<{ setting: BehaviorSetting }> = (props) => { const setting = props.setting const disabled = createMemo(() => (setting.disabled ? Boolean(setting.disabled()) : false)) if (setting.kind === "toggle") { const options = createMemo(() => [ { value: "true", label: t("settings.common.enabled") }, { value: "false", label: t("settings.common.disabled") }, ]) const currentValue = createMemo(() => String(Boolean(readSettingValue(setting)))) const selectedOption = createMemo(() => options().find((opt) => opt.value === currentValue())) return (
{t(setting.titleKey)}
{t(setting.subtitleKey)}
value={selectedOption()} onChange={(opt) => { if (!opt) return const next = opt.value === "true" setOverride(setting.id, next) setting.set(next) }} options={options()} optionValue="value" optionTextValue="label" disabled={disabled()} itemComponent={(itemProps) => ( {itemProps.item.rawValue.label} )} >
> {(state) => ( {state.selectedOption()?.label} )}
) } const enumSetting = setting as Extract const options = createMemo(() => enumSetting.options.map((opt: { value: string; labelKey: string }) => ({ value: String(opt.value), label: t(opt.labelKey), })), ) const currentValue = createMemo(() => String(readSettingValue(setting) ?? "")) const selectedOption = createMemo(() => options().find((opt) => opt.value === currentValue())) return (
{t(setting.titleKey)}
{t(setting.subtitleKey)}
value={selectedOption()} onChange={(opt) => { if (!opt) return setOverride(setting.id, opt.value) enumSetting.set(opt.value as any) }} options={options()} optionValue="value" optionTextValue="label" disabled={disabled()} itemComponent={(itemProps) => ( {itemProps.item.rawValue.label} )} >
> {(state) => ( {state.selectedOption()?.label} )}
) } const modeLabel = (mode: ThemeMode) => { if (mode === "system") return t("theme.mode.system") if (mode === "light") return t("theme.mode.light") return t("theme.mode.dark") } return (

{t("settings.appearance.theme.title")}

{t("settings.appearance.theme.subtitle")}

{t("settings.scope.device")}
{themeModeOptions.map((option) => { const Icon = option.icon return ( ) })}

{t("settings.appearance.behavior.title")}

{t("settings.appearance.behavior.subtitle")}

{t("settings.scope.device")}
{(setting) => }
) }