Files
writing-agent/web/theme.js
T
chenmoranzhiandCursor 770a8fdcdc Move theme menu to the header and group present chrome under it.
Also align Token stats with the settings shell and drop leftover lifecycle toggle wiring.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-03 00:58:25 +08:00

117 lines
3.1 KiB
JavaScript

/** Color themes + present chrome — aligned with llm_workflow_engine ThemeToggle. */
export const COLOR_THEMES = [
{
id: "paper",
name: "仿纸暖黄",
description: "经典护眼,像 Kindle",
icon: "📖",
},
{
id: "modern",
name: "现代清爽",
description: "干净明快,适合网文",
icon: "✨",
},
{
id: "dark",
name: "夜间暗色",
description: "黑底灰字,夜间必备",
icon: "🌙",
},
{
id: "green",
name: "豆沙绿",
description: "自然疗愈,绿色经典",
icon: "🍃",
},
];
/** 呈现壳气质(tone_chrome),与色主题同属「主题」菜单 */
export const PRESENT_CHROMES = [
{ id: "default", name: "默认", description: "跟随壳本身" },
{ id: "messenger", name: "讯息", description: "气泡对话感" },
{ id: "book", name: "书页", description: "阅读排版感" },
{ id: "terminal", name: "终端", description: "等宽终端感" },
];
const STORAGE_KEY = "wa-color-theme";
const CHROME_STORAGE_KEY = "wa-present-chrome";
const THEME_IDS = new Set(COLOR_THEMES.map((t) => t.id));
const CHROME_IDS = new Set(PRESENT_CHROMES.map((t) => t.id));
const DEFAULT_THEME = "modern";
const DEFAULT_CHROME = "default";
export function normalizeColorTheme(id) {
const v = String(id || "").trim();
return THEME_IDS.has(v) ? v : DEFAULT_THEME;
}
export function getStoredColorTheme() {
try {
return normalizeColorTheme(localStorage.getItem(STORAGE_KEY));
} catch {
return DEFAULT_THEME;
}
}
export function themeById(id) {
const tid = normalizeColorTheme(id);
return COLOR_THEMES.find((t) => t.id === tid) || COLOR_THEMES[1];
}
export function applyColorTheme(id) {
const theme = normalizeColorTheme(id);
document.documentElement.setAttribute("data-color-theme", theme);
document.documentElement.setAttribute("data-theme", theme);
try {
localStorage.setItem(STORAGE_KEY, theme);
} catch {
/* ignore quota / private mode */
}
return theme;
}
export function initColorTheme() {
return applyColorTheme(getStoredColorTheme());
}
export function normalizePresentChrome(id) {
const v = String(id || "").trim();
return CHROME_IDS.has(v) ? v : DEFAULT_CHROME;
}
export function getStoredPresentChrome() {
try {
return normalizePresentChrome(localStorage.getItem(CHROME_STORAGE_KEY));
} catch {
return DEFAULT_CHROME;
}
}
export function chromeById(id) {
const cid = normalizePresentChrome(id);
return PRESENT_CHROMES.find((t) => t.id === cid) || PRESENT_CHROMES[0];
}
export function applyPresentChrome(id) {
const chrome = normalizePresentChrome(id);
document.documentElement.setAttribute("data-present-chrome", chrome);
try {
localStorage.setItem(CHROME_STORAGE_KEY, chrome);
} catch {
/* ignore */
}
document.querySelectorAll(".present-shell").forEach((el) => {
for (const cls of [...el.classList]) {
if (cls.startsWith("present-tone--")) el.classList.remove(cls);
}
el.classList.add(`present-tone--${chrome}`);
});
return chrome;
}
export function initPresentChrome() {
return applyPresentChrome(getStoredPresentChrome());
}