feat: dark theme polish — fix sidebar layout, update button, chat input & theme switching

- Fix sidebar footer layout: separate update button from version row
- Replace custom update-hint with NButton for proper dark mode support
- Darken chat input background in dark theme for better contrast
- Fix system theme listener always applying dark mode

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
ekko
2026-04-17 08:37:57 +08:00
parent 6df7cada04
commit 16e07bcc9b
4 changed files with 16 additions and 29 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "hermes-web-ui",
"version": "0.2.9",
"version": "0.3.0",
"description": "Web dashboard for Hermes Agent — multi-platform AI chat, session management, scheduled jobs, usage analytics & channel configuration (Telegram, Discord, Slack, WhatsApp)",
"repository": {
"type": "git",
@@ -92,4 +92,4 @@
"vitest": "^3.2.4",
"vue-tsc": "^3.2.6"
}
}
}
@@ -356,11 +356,15 @@ function isImage(type: string): boolean {
border: 1px solid $border-color;
border-radius: $radius-md;
padding: 10px 12px;
transition: border-color $transition-fast;
transition: border-color $transition-fast, background-color $transition-fast;
&:focus-within {
border-color: $accent-primary;
}
.dark & {
background-color: #333333;
}
}
.input-textarea {
@@ -1,8 +1,8 @@
<script setup lang="ts">
import { computed, ref } from "vue";
import { computed } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useI18n } from "vue-i18n";
import { useMessage } from "naive-ui";
import { NButton, useMessage } from "naive-ui";
import { useAppStore } from "@/stores/hermes/app";
import ModelSelector from "./ModelSelector.vue";
import ProfileSelector from "./ProfileSelector.vue";
@@ -319,10 +319,10 @@ async function handleUpdate() {
<div class="version-info">
<span>Hermes Web UI v{{ appStore.serverVersion || "0.1.0" }}</span>
<ThemeSwitch />
<a v-if="appStore.updateAvailable" class="update-hint" :class="{ loading: appStore.updating }" @click="handleUpdate">
{{ appStore.updating ? t('sidebar.updating') : t('sidebar.updateVersion', { version: appStore.latestVersion }) }}
</a>
</div>
<NButton v-if="appStore.updateAvailable" type="primary" size="tiny" block class="update-btn" :loading="appStore.updating" @click="handleUpdate">
{{ appStore.updating ? t('sidebar.updating') : t('sidebar.updateVersion', { version: appStore.latestVersion }) }}
</NButton>
</div>
</aside>
</template>
@@ -476,26 +476,9 @@ async function handleUpdate() {
justify-content: space-between;
}
.update-hint {
display: block;
margin-top: 4px;
padding: 5px 10px;
border-radius: $radius-sm;
background: var(--accent-primary);
color: rgba(255, 255, 255, 0.7);
font-size: 11px;
text-align: center;
cursor: pointer;
transition: background $transition-fast;
&:hover {
background: var(--accent-hover);
}
&.loading {
pointer-events: none;
opacity: 0.7;
}
.update-btn {
margin: 4px 0 0;
border-radius: 4px;
}
@media (max-width: $breakpoint-mobile) {
+1 -1
View File
@@ -29,7 +29,7 @@ applyTheme(resolveDark(mode.value))
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
mediaQuery.addEventListener('change', () => {
if (mode.value === 'system') {
applyTheme(true)
applyTheme(resolveDark('system'))
}
})