Files
SearcjGal-frontend/src/utils/theme.ts
AdingApkgg 49128d77c1 feat: 增加暗色主题支持与样式优化
* 在 `index.html` 中添加主题颜色变量,支持白天和黑夜模式。
* 更新多个组件的样式,确保在暗色主题下的视觉一致性。
* 在 `App.vue` 中引入 `TopToolbar` 组件,增强用户界面。
* 优化图片缓存逻辑,支持批量删除旧图片,提升性能。
* 移除不必要的分享按钮,简化 `FloatingButtons.vue` 组件结构。
2025-11-20 03:36:13 +08:00

90 lines
2.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 主题管理工具
* 支持白天/黑夜模式和跟随系统
*/
export type ThemeMode = 'light' | 'dark' | 'auto'
const THEME_STORAGE_KEY = 'searchgal_theme'
/**
* 获取系统主题偏好
*/
export function getSystemTheme(): 'light' | 'dark' {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
return 'dark'
}
return 'light'
}
/**
* 获取当前应该应用的主题(考虑 auto 模式)
*/
export function getEffectiveTheme(mode: ThemeMode): 'light' | 'dark' {
if (mode === 'auto') {
return getSystemTheme()
}
return mode
}
/**
* 应用主题到 DOM
*/
export function applyTheme(theme: 'light' | 'dark'): void {
const root = document.documentElement
if (theme === 'dark') {
root.classList.add('dark')
} else {
root.classList.remove('dark')
}
}
/**
* 保存主题偏好
*/
export function saveThemePreference(mode: ThemeMode): void {
try {
localStorage.setItem(THEME_STORAGE_KEY, mode)
} catch (error) {
// 静默处理
}
}
/**
* 加载主题偏好
*/
export function loadThemePreference(): ThemeMode {
try {
const saved = localStorage.getItem(THEME_STORAGE_KEY)
if (saved === 'light' || saved === 'dark' || saved === 'auto') {
return saved
}
} catch (error) {
// 静默处理
}
return 'auto' // 默认跟随系统
}
/**
* 监听系统主题变化
*/
export function watchSystemTheme(callback: (theme: 'light' | 'dark') => void): () => void {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
const handler = (e: MediaQueryListEvent) => {
callback(e.matches ? 'dark' : 'light')
}
// 使用新的 API如果可用
if (mediaQuery.addEventListener) {
mediaQuery.addEventListener('change', handler)
return () => mediaQuery.removeEventListener('change', handler)
} else {
// 降级到旧的 API
mediaQuery.addListener(handler)
return () => mediaQuery.removeListener(handler)
}
}