{meta[1]}
+ +{meta.label}
{meta.description}
-
P
+
{#each turn.blocks as block (block.id)}
{#if block.type === "reasoning"}
diff --git a/webui/src/lib/components/ActivitySpine.svelte b/webui/src/lib/components/ActivitySpine.svelte
index e60244e..a883751 100644
--- a/webui/src/lib/components/ActivitySpine.svelte
+++ b/webui/src/lib/components/ActivitySpine.svelte
@@ -19,36 +19,34 @@
});
const running = $derived(chat.turn?.status === "running");
- const turnLabel = $derived(chat.turn ? `TURN ${String(chat.turn.id ?? "").slice(0, 6).toUpperCase()}` : "");
+ const turnLabel = $derived(chat.turn ? `Turn ${String(chat.turn.id ?? "").slice(0, 6).toUpperCase()}` : "");
const ctx = $derived(chat.turn?.usage?.prompt_tokens != null
? `${(chat.turn.usage.prompt_tokens / 1000).toFixed(1)}k` : null);
-
+
diff --git a/webui/src/lib/theme.js b/webui/src/lib/theme.js
index 3606e6b..8903976 100644
--- a/webui/src/lib/theme.js
+++ b/webui/src/lib/theme.js
@@ -1,4 +1,16 @@
const STORAGE_KEY = "picobot-theme";
+const ACCENT_STORAGE_KEY = "picobot-accent";
+
+export const ACCENT_THEMES = Object.freeze([
+ { id: "blue", label: "海蓝", swatch: "#0f6cbd", description: "Fluent 默认蓝" },
+ { id: "purple", label: "紫罗兰", swatch: "#5c2e91", description: "沉静而专注" },
+ { id: "teal", label: "青绿", swatch: "#006c4c", description: "清晰且克制" },
+ { id: "green", label: "森林", swatch: "#107c10", description: "稳定与活力" },
+ { id: "orange", label: "暖橙", swatch: "#ca5010", description: "醒目而友好" },
+ { id: "magenta", label: "莓红", swatch: "#9b0062", description: "鲜明有个性" }
+]);
+
+const ACCENT_IDS = new Set(ACCENT_THEMES.map((theme) => theme.id));
export function preferredTheme() {
const saved = localStorage.getItem(STORAGE_KEY);
@@ -6,11 +18,34 @@ export function preferredTheme() {
return matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
+export function preferredAccent() {
+ const saved = localStorage.getItem(ACCENT_STORAGE_KEY);
+ return ACCENT_IDS.has(saved) ? saved : "blue";
+}
+
+function notifyAppearance() {
+ window.dispatchEvent(new CustomEvent("picobot-appearance-change", {
+ detail: {
+ theme: document.documentElement.dataset.theme,
+ accent: document.documentElement.dataset.accent
+ }
+ }));
+}
+
export function applyTheme(theme) {
- document.documentElement.dataset.theme = theme;
- document.documentElement.style.colorScheme = theme;
+ const next = theme === "dark" ? "dark" : "light";
+ document.documentElement.dataset.theme = next;
+ document.documentElement.style.colorScheme = next;
document
.querySelector('meta[name="theme-color"]')
- ?.setAttribute("content", theme === "dark" ? "#0b1017" : "#eef1f5");
- localStorage.setItem(STORAGE_KEY, theme);
+ ?.setAttribute("content", next === "dark" ? "#1f1f1f" : "#f5f5f5");
+ localStorage.setItem(STORAGE_KEY, next);
+ notifyAppearance();
+}
+
+export function applyAccent(accent) {
+ const next = ACCENT_IDS.has(accent) ? accent : "blue";
+ document.documentElement.dataset.accent = next;
+ localStorage.setItem(ACCENT_STORAGE_KEY, next);
+ notifyAppearance();
}
diff --git a/webui/src/pages/ChatPage.svelte b/webui/src/pages/ChatPage.svelte
index 562173d..e3a402d 100644
--- a/webui/src/pages/ChatPage.svelte
+++ b/webui/src/pages/ChatPage.svelte
@@ -6,6 +6,7 @@
import Markdown from "../lib/Markdown.svelte";
import ToolCallCard from "../lib/ToolCallCard.svelte";
import TurnView from "../lib/TurnView.svelte";
+ import Icon from "../lib/Icon.svelte";
let { notify } = $props();
let sessions = $state([]);
@@ -377,9 +378,9 @@
{#if running}
- {turnLabel} · STREAMING
+ {turnLabel} · 生成中
{#if rate != null}▲ {rate} tok/s{/if}
{#if ctx}ctx {ctx}{/if}
{:else if chat.turn}
- IDLE
- 最近 {turnLabel}
+ 空闲
+ 最近 {turnLabel}
{:else}
- READY
+ 就绪
{/if}
{chat.connected ? "已连接" : "重连中"}
- {#if version}{version}{/if}
diff --git a/webui/src/lib/components/AppearanceSettings.svelte b/webui/src/lib/components/AppearanceSettings.svelte
new file mode 100644
index 0000000..dbcb9b7
--- /dev/null
+++ b/webui/src/lib/components/AppearanceSettings.svelte
@@ -0,0 +1,149 @@
+
+
+
+
+
+
diff --git a/webui/src/lib/components/CapacityMeter.svelte b/webui/src/lib/components/CapacityMeter.svelte
index 0555b2f..13f20b6 100644
--- a/webui/src/lib/components/CapacityMeter.svelte
+++ b/webui/src/lib/components/CapacityMeter.svelte
@@ -1,30 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 显示模式
选择更适合当前环境的页面明暗度。
+
+
+
+
+
+
+ 主题色
品牌色会应用到主操作、选中状态、进度和焦点提示。
+ {#each ACCENT_THEMES as option}
+
+ {/each}
+
+ 外观设置仅保存在当前浏览器中,不会写入 Gateway 配置或同步到其他设备。
+
- {#each Array(segments) as _, i}
-
- {/each}
+
diff --git a/webui/src/lib/components/MetricTile.svelte b/webui/src/lib/components/MetricTile.svelte
index 1d9d843..d6b1942 100644
--- a/webui/src/lib/components/MetricTile.svelte
+++ b/webui/src/lib/components/MetricTile.svelte
@@ -16,9 +16,9 @@