mirror of
https://github.com/NanmiCoder/MediaCrawler.git
synced 2026-07-28 15:30:25 +08:00
refactor: 将 WebUI 源码纳入仓库,移除打包产物
- 新增 webui/ 前端源码目录(React+Vite+TypeScript+Tailwind) - 删除 api/webui/ 中旧的打包静态资源 - 更新 .gitignore 忽略 api/webui/ 构建输出和 webui/node_modules - 更新 README 增加前端构建说明
This commit is contained in:
69
webui/src/store/themeStore.ts
Normal file
69
webui/src/store/themeStore.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { create } from 'zustand'
|
||||
|
||||
type Theme = 'light' | 'dark' | 'system'
|
||||
|
||||
interface ThemeState {
|
||||
theme: Theme
|
||||
resolvedTheme: 'light' | 'dark'
|
||||
setTheme: (theme: Theme) => void
|
||||
}
|
||||
|
||||
const THEME_KEY = 'mediacrawler_theme'
|
||||
|
||||
function getSystemTheme(): 'light' | 'dark' {
|
||||
if (typeof window === 'undefined') return 'light'
|
||||
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
||||
}
|
||||
|
||||
function getStoredTheme(): Theme {
|
||||
if (typeof window === 'undefined') return 'light'
|
||||
const stored = localStorage.getItem(THEME_KEY) as Theme | null
|
||||
if (stored && ['light', 'dark', 'system'].includes(stored)) {
|
||||
return stored
|
||||
}
|
||||
return 'light' // Default to light
|
||||
}
|
||||
|
||||
function applyTheme(resolved: 'light' | 'dark') {
|
||||
const root = document.documentElement
|
||||
if (resolved === 'dark') {
|
||||
root.classList.add('dark')
|
||||
} else {
|
||||
root.classList.remove('dark')
|
||||
}
|
||||
}
|
||||
|
||||
function resolveTheme(theme: Theme): 'light' | 'dark' {
|
||||
return theme === 'system' ? getSystemTheme() : theme
|
||||
}
|
||||
|
||||
// Initialize theme immediately to prevent flash
|
||||
const initialTheme = getStoredTheme()
|
||||
const initialResolved = resolveTheme(initialTheme)
|
||||
if (typeof window !== 'undefined') {
|
||||
applyTheme(initialResolved)
|
||||
}
|
||||
|
||||
export const useThemeStore = create<ThemeState>((set) => ({
|
||||
theme: initialTheme,
|
||||
resolvedTheme: initialResolved,
|
||||
|
||||
setTheme: (theme) => {
|
||||
const resolved = resolveTheme(theme)
|
||||
localStorage.setItem(THEME_KEY, theme)
|
||||
applyTheme(resolved)
|
||||
set({ theme, resolvedTheme: resolved })
|
||||
},
|
||||
}))
|
||||
|
||||
// Listen for system theme changes
|
||||
if (typeof window !== 'undefined') {
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
|
||||
const state = useThemeStore.getState()
|
||||
if (state.theme === 'system') {
|
||||
const resolved = e.matches ? 'dark' : 'light'
|
||||
applyTheme(resolved)
|
||||
useThemeStore.setState({ resolvedTheme: resolved })
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user