rebuild(stage-4): deliver shared shell and account interfaces

This commit is contained in:
leefer
2026-07-30 02:08:20 +08:00
parent d1c658d8ef
commit 3b75bf2d63
47 changed files with 3042 additions and 99 deletions
+53
View File
@@ -0,0 +1,53 @@
import { defineStore } from "pinia";
import { ref } from "vue";
export type DialogName = "profile" | "membership" | "password" | "search" | null;
export type Theme = "light" | "dark";
const THEME_KEY = "xiaobai-theme";
export function preferredTheme(): Theme {
const stored = localStorage.getItem(THEME_KEY);
if (stored === "light" || stored === "dark") return stored;
return matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
export function applyTheme(theme: Theme): void {
document.documentElement.dataset.theme = theme;
document.documentElement.style.colorScheme = theme;
}
export const useUiStore = defineStore("ui", () => {
const theme = ref<Theme>(preferredTheme());
const dialog = ref<DialogName>(null);
const toast = ref("");
let toastTimer: ReturnType<typeof setTimeout> | undefined;
function setTheme(next: Theme): void {
theme.value = next;
localStorage.setItem(THEME_KEY, next);
applyTheme(next);
}
function toggleTheme(): void {
setTheme(theme.value === "light" ? "dark" : "light");
}
function openDialog(name: Exclude<DialogName, null>): void {
dialog.value = name;
}
function closeDialog(): void {
dialog.value = null;
}
function showToast(message: string): void {
toast.value = message;
if (toastTimer) clearTimeout(toastTimer);
toastTimer = setTimeout(() => {
toast.value = "";
}, 2200);
}
return { theme, dialog, toast, setTheme, toggleTheme, openDialog, closeDialog, showToast };
});