mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-08-28 19:47:49 +08:00
fix theme
This commit is contained in:
@@ -22,64 +22,17 @@ const {
|
|||||||
{ initialValue: savedTheme.value },
|
{ initialValue: savedTheme.value },
|
||||||
)
|
)
|
||||||
|
|
||||||
function updateTheme() {
|
// 主题切换动画
|
||||||
const autoTheme = checkPrefersColorSchemeIsDark() ? 'dark' : 'light'
|
|
||||||
const theme = currentThemeName.value === 'auto' ? autoTheme : currentThemeName.value
|
|
||||||
globalTheme.name.value = theme
|
|
||||||
savedTheme.value = theme
|
|
||||||
// 修改载入时背景色
|
|
||||||
localStorage.setItem('materio-initial-loader-bg', globalTheme.current.value.colors.background)
|
|
||||||
themeTransition()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听系统主题变化
|
|
||||||
try {
|
|
||||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', updateTheme)
|
|
||||||
} catch(e) {
|
|
||||||
console.error('当前设备不支持监听系统主题变化')
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => currentThemeName.value,
|
|
||||||
() => updateTheme(),
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
// onMounted(() => {
|
|
||||||
// globalTheme.name.value = savedTheme.value
|
|
||||||
// })
|
|
||||||
|
|
||||||
function hasScrollbar(el?: Element | null) {
|
|
||||||
if (!el || el.nodeType !== Node.ELEMENT_NODE)
|
|
||||||
return false
|
|
||||||
|
|
||||||
const style = window.getComputedStyle(el)
|
|
||||||
return style.overflowY === 'scroll' || (style.overflowY === 'auto' && el.scrollHeight > el.clientHeight)
|
|
||||||
}
|
|
||||||
|
|
||||||
function themeTransition() {
|
function themeTransition() {
|
||||||
const x = performance.now()
|
const x = performance.now()
|
||||||
for (let i = 0; i++ < 1e7; (i << 9) & ((9 % 9) * 9 + 9));
|
for (let i = 0; i++ < 1e7; (i << 9) & ((9 % 9) * 9 + 9));
|
||||||
const cost = performance.now() - x
|
const cost = performance.now() - x
|
||||||
if (cost > 10)
|
if (cost > 10) return
|
||||||
return
|
|
||||||
|
|
||||||
const el: HTMLElement = document.querySelector('[data-v-app]')!
|
const el: HTMLElement = document.querySelector('[data-v-app]')!
|
||||||
const children = el.querySelectorAll('*') as NodeListOf<HTMLElement>
|
const children = el.querySelectorAll('*') as NodeListOf<HTMLElement>
|
||||||
|
|
||||||
children.forEach((el) => {
|
children.forEach(el => {
|
||||||
if (hasScrollbar(el)) {
|
if (hasScrollbar(el)) {
|
||||||
el.dataset.scrollX = String(el.scrollLeft)
|
el.dataset.scrollX = String(el.scrollLeft)
|
||||||
el.dataset.scrollY = String(el.scrollTop)
|
el.dataset.scrollY = String(el.scrollTop)
|
||||||
@@ -111,7 +64,7 @@ function themeTransition() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
document.body.append(copy)
|
document.body.append(copy)
|
||||||
; (copy.querySelectorAll('[data-scroll-x], [data-scroll-y]') as NodeListOf<HTMLElement>).forEach((el) => {
|
;(copy.querySelectorAll('[data-scroll-x], [data-scroll-y]') as NodeListOf<HTMLElement>).forEach(el => {
|
||||||
el.scrollLeft = +el.dataset.scrollX!
|
el.scrollLeft = +el.dataset.scrollX!
|
||||||
el.scrollTop = +el.dataset.scrollY!
|
el.scrollTop = +el.dataset.scrollY!
|
||||||
})
|
})
|
||||||
@@ -129,6 +82,55 @@ function themeTransition() {
|
|||||||
el.addEventListener('transitionend', onTransitionend)
|
el.addEventListener('transitionend', onTransitionend)
|
||||||
el.addEventListener('transitioncancel', onTransitionend)
|
el.addEventListener('transitioncancel', onTransitionend)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新主题
|
||||||
|
function updateTheme() {
|
||||||
|
const autoTheme = checkPrefersColorSchemeIsDark() ? 'dark' : 'light'
|
||||||
|
const theme = currentThemeName.value === 'auto' ? autoTheme : currentThemeName.value
|
||||||
|
globalTheme.name.value = theme
|
||||||
|
savedTheme.value = theme
|
||||||
|
themeTransition()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换主题
|
||||||
|
function changeTheme() {
|
||||||
|
const nextTheme = getNextThemeName()
|
||||||
|
currentThemeName.value = nextTheme
|
||||||
|
// 保存主题到本地
|
||||||
|
localStorage.setItem('theme', nextTheme)
|
||||||
|
localStorage.setItem('materio-initial-loader-bg', globalTheme.current.value.colors.background)
|
||||||
|
// 保存主题到服务端
|
||||||
|
try {
|
||||||
|
api.post('/user/config/theme', nextTheme, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.error('保存主题到服务端失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 是否有滚动条
|
||||||
|
function hasScrollbar(el?: Element | null) {
|
||||||
|
if (!el || el.nodeType !== Node.ELEMENT_NODE) return false
|
||||||
|
|
||||||
|
const style = window.getComputedStyle(el)
|
||||||
|
return style.overflowY === 'scroll' || (style.overflowY === 'auto' && el.scrollHeight > el.clientHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听系统主题变化
|
||||||
|
try {
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', updateTheme)
|
||||||
|
} catch (e) {
|
||||||
|
console.error('当前设备不支持监听系统主题变化')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听设置主题变化
|
||||||
|
watch(
|
||||||
|
() => currentThemeName.value,
|
||||||
|
() => updateTheme(),
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
+10
-25
@@ -10,37 +10,22 @@ const { global: globalTheme } = useTheme()
|
|||||||
// 提示框
|
// 提示框
|
||||||
const $toast = useToast()
|
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置主题
|
|
||||||
async function setTheme() {
|
async function setTheme() {
|
||||||
let themeValue = await fetchThemeConfig() || localStorage.getItem('theme') || 'light'
|
let themeValue = localStorage.getItem('theme') || 'light'
|
||||||
const autoTheme = checkPrefersColorSchemeIsDark() ? 'dark' : 'light'
|
const autoTheme = checkPrefersColorSchemeIsDark() ? 'dark' : 'light'
|
||||||
globalTheme.name.value = themeValue === 'auto' ? autoTheme : themeValue
|
globalTheme.name.value = themeValue === 'auto' ? autoTheme : themeValue
|
||||||
// 修改载入时背景色
|
|
||||||
localStorage.setItem('materio-initial-loader-bg', globalTheme.current.value.colors.background)
|
|
||||||
localStorage.setItem('theme', themeValue)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SSE持续接收消息
|
// SSE持续接收消息
|
||||||
function startSSEMessager() {
|
function startSSEMessager() {
|
||||||
const token = store.state.auth.token
|
const token = store.state.auth.token
|
||||||
if (token) {
|
if (token) {
|
||||||
const eventSource = new EventSource(
|
const eventSource = new EventSource(`${import.meta.env.VITE_API_BASE_URL}system/message?token=${token}`)
|
||||||
`${import.meta.env.VITE_API_BASE_URL}system/message?token=${token}`,
|
|
||||||
)
|
|
||||||
|
|
||||||
eventSource.addEventListener('message', (event) => {
|
eventSource.addEventListener('message', event => {
|
||||||
const message = event.data
|
const message = event.data
|
||||||
if (message)
|
if (message) $toast.info(message)
|
||||||
$toast.info(message)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
@@ -53,16 +38,16 @@ function startSSEMessager() {
|
|||||||
async function loadDashboardConfig() {
|
async function loadDashboardConfig() {
|
||||||
const response = await api.get('/user/config/Dashboard')
|
const response = await api.get('/user/config/Dashboard')
|
||||||
if (response && response.data && response.data.value) {
|
if (response && response.data && response.data.value) {
|
||||||
const data = JSON.stringify(response.data.value)
|
const data = JSON.stringify(response.data.value)
|
||||||
if (data != localStorage.getItem("MP_DASHBOARD")) {
|
if (data != localStorage.getItem('MP_DASHBOARD')) {
|
||||||
localStorage.setItem("MP_DASHBOARD", data)
|
localStorage.setItem('MP_DASHBOARD', data)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 尝试加载用户监控面板配置(本地无配置时才加载)
|
// 尝试加载用户监控面板配置(本地无配置时才加载)
|
||||||
async function tryLoadDashboardConfig() {
|
async function tryLoadDashboardConfig() {
|
||||||
if (localStorage.getItem("MP_DASHBOARD")) {
|
if (localStorage.getItem('MP_DASHBOARD')) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await loadDashboardConfig()
|
await loadDashboardConfig()
|
||||||
|
|||||||
+5
-5
@@ -98,18 +98,18 @@ async function fetchThemeConfig() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置主题
|
// 生效主题
|
||||||
async function setTheme() {
|
async function setTheme() {
|
||||||
let themeValue = await fetchThemeConfig() || localStorage.getItem('theme') || 'light'
|
let themeValue = (await fetchThemeConfig()) || localStorage.getItem('theme') || 'light'
|
||||||
const autoTheme = checkPrefersColorSchemeIsDark() ? 'dark' : 'light'
|
const autoTheme = checkPrefersColorSchemeIsDark() ? 'dark' : 'light'
|
||||||
globalTheme.name.value = themeValue === 'auto' ? autoTheme : themeValue
|
globalTheme.name.value = themeValue === 'auto' ? autoTheme : themeValue
|
||||||
// 修改载入时背景色
|
// 存储主题到本地
|
||||||
localStorage.setItem('materio-initial-loader-bg', globalTheme.current.value.colors.background)
|
|
||||||
localStorage.setItem('theme', themeValue)
|
localStorage.setItem('theme', themeValue)
|
||||||
|
localStorage.setItem('materio-initial-loader-bg', globalTheme.current.value.colors.background)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function afterLogin() {
|
async function afterLogin() {
|
||||||
// 主题配置
|
// 生效主题配置
|
||||||
await setTheme()
|
await setTheme()
|
||||||
// 尝试加载用户监控面板配置(本地无配置时才加载)
|
// 尝试加载用户监控面板配置(本地无配置时才加载)
|
||||||
await tryLoadDashboardConfig()
|
await tryLoadDashboardConfig()
|
||||||
|
|||||||
Reference in New Issue
Block a user