diff --git a/src/@core/components/ThemeSwitcher.vue b/src/@core/components/ThemeSwitcher.vue index 6d2e8ec1..bfa746a9 100644 --- a/src/@core/components/ThemeSwitcher.vue +++ b/src/@core/components/ThemeSwitcher.vue @@ -2,6 +2,8 @@ import { ref } from 'vue' import { useTheme } from 'vuetify' import type { ThemeSwitcherTheme } from '@layouts/types' +import api from '@/api' +import { checkPrefersColorSchemeIsDark } from '@/@core/utils' const props = defineProps<{ themes: ThemeSwitcherTheme[] @@ -21,7 +23,7 @@ const { ) function updateTheme() { - const autoTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' + const autoTheme = checkPrefersColorSchemeIsDark() ? 'dark' : 'light' const theme = currentThemeName.value === 'auto' ? autoTheme : currentThemeName.value globalTheme.name.value = theme savedTheme.value = theme @@ -31,7 +33,11 @@ function updateTheme() { } // 监听系统主题变化 -window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', updateTheme) +try { + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', updateTheme) +} catch(e) { + console.error('当前设备不支持监听系统主题变化') +} watch( () => currentThemeName.value, @@ -42,6 +48,12 @@ function changeTheme() { const nextTheme = getNextThemeName() currentThemeName.value = nextTheme localStorage.setItem('theme', nextTheme) + // 保存主题到服务端 + api.post('/user/config/theme', nextTheme, { + headers: { + 'Content-Type': 'text/plain', + }, + }) } // Apply saved theme on page load diff --git a/src/@core/utils/index.ts b/src/@core/utils/index.ts index 2c97f674..b91bce96 100644 --- a/src/@core/utils/index.ts +++ b/src/@core/utils/index.ts @@ -118,3 +118,12 @@ export function isNullOrEmptyObject(obj: any): boolean { // 然后判断是否为空对象 return !!(typeof obj === 'object' && Object.keys(obj).length === 0) } + +// 判断系统配置色是否是黑暗的 +export function checkPrefersColorSchemeIsDark(): boolean { + try { + return window.matchMedia('(prefers-color-scheme: dark)').matches + } catch (e) { + return false + } +} diff --git a/src/App.vue b/src/App.vue index 1f367415..538d3ab6 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,18 +3,30 @@ import { useToast } from 'vue-toast-notification' import { useTheme } from 'vuetify' import api from '@/api' import store from './store' +import { checkPrefersColorSchemeIsDark } from '@/@core/utils' +const { global: globalTheme } = useTheme() // 提示框 const $toast = useToast() +// 获取用户主题配置 +async function fetchThemeConfig() { + const response = await api.get('/user/config/theme') + if (response && response.data && response.data.value) { + return response.data.value + } + return null +} + // 设置主题 -function setTheme() { - const { global: globalTheme } = useTheme() - let theme = localStorage.getItem('theme') || 'light' - if (theme === 'auto') - theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' - globalTheme.name.value = theme +async function setTheme() { + let themeValue = await fetchThemeConfig() || localStorage.getItem('theme') || 'light' + const autoTheme = checkPrefersColorSchemeIsDark() ? 'dark' : 'light' + globalTheme.name.value = themeValue === 'auto' ? autoTheme : themeValue + // 修改载入时背景色 + localStorage.setItem('materio-initial-loader-bg', globalTheme.current.value.colors.background) + localStorage.setItem('theme', themeValue) } // SSE持续接收消息 diff --git a/src/components/cards/MediaCard.vue b/src/components/cards/MediaCard.vue index edf082b6..809bf6a8 100644 --- a/src/components/cards/MediaCard.vue +++ b/src/components/cards/MediaCard.vue @@ -431,10 +431,10 @@ function getYear(airDate: string) { {{ props.media?.type }} - +