feat: add dark theme support with CSS custom properties and Naive UI integration

Implement runtime theme switching using CSS custom properties delegated through SCSS variables, with light/dark/system modes, FOUC prevention, sidebar toggle, and settings selector. Add theme-aware video assets for sidebar and chat thinking indicator.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
ekko
2026-04-16 23:13:04 +08:00
co-authored by Claude Opus 4.6
parent 076a7c2a38
commit b5aeb876b8
32 changed files with 465 additions and 126 deletions
@@ -1,12 +1,20 @@
<script setup lang="ts">
import { NSwitch, useMessage } from 'naive-ui'
import { NSwitch, NSelect, useMessage } from 'naive-ui'
import { useI18n } from 'vue-i18n'
import { useSettingsStore } from '@/stores/hermes/settings'
import { useTheme, type ThemeMode } from '@/composables/useTheme'
import SettingRow from './SettingRow.vue'
const settingsStore = useSettingsStore()
const message = useMessage()
const { t } = useI18n()
const { mode, setMode } = useTheme()
const themeOptions = [
{ label: t('settings.display.themeLight'), value: 'light' },
{ label: t('settings.display.themeDark'), value: 'dark' },
{ label: t('settings.display.themeSystem'), value: 'system' },
]
async function save(values: Record<string, any>) {
try {
@@ -16,10 +24,19 @@ async function save(values: Record<string, any>) {
message.error(t('settings.saveFailed'))
}
}
function handleThemeChange(val: string) {
const m = val as ThemeMode
setMode(m)
save({ skin: m })
}
</script>
<template>
<section class="settings-section">
<SettingRow :label="t('settings.display.theme')" :hint="t('settings.display.themeHint')">
<NSelect :value="mode" :options="themeOptions" size="small" :consistent-menu-width="false" class="input-sm" @update:value="handleThemeChange" />
</SettingRow>
<SettingRow :label="t('settings.display.streaming')" :hint="t('settings.display.streamingHint')">
<NSwitch :value="settingsStore.display.streaming" @update:value="v => save({ streaming: v })" />
</SettingRow>
@@ -57,7 +57,7 @@ const configured = computed(() => {
overflow: hidden;
&.configured {
border-color: rgba($success, 0.2);
border-color: rgba(var(--success-rgb), 0.2);
}
}
@@ -70,7 +70,7 @@ const configured = computed(() => {
user-select: none;
&:hover {
background-color: rgba($text-primary, 0.03);
background-color: rgba(var(--text-primary-rgb), 0.03);
}
}