mirror of
https://github.com/Moe-Sakura/frontend.git
synced 2026-04-04 08:25:07 +08:00
* 在 `index.html` 中添加主题颜色变量,支持白天和黑夜模式。 * 更新多个组件的样式,确保在暗色主题下的视觉一致性。 * 在 `App.vue` 中引入 `TopToolbar` 组件,增强用户界面。 * 优化图片缓存逻辑,支持批量删除旧图片,提升性能。 * 移除不必要的分享按钮,简化 `FloatingButtons.vue` 组件结构。
90 lines
2.0 KiB
TypeScript
90 lines
2.0 KiB
TypeScript
/**
|
||
* 主题管理工具
|
||
* 支持白天/黑夜模式和跟随系统
|
||
*/
|
||
|
||
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)
|
||
}
|
||
}
|
||
|