feat: 让应用 Logo 跟随主题色 (#538)

* fix(login): show form with logo

* feat(theme): sync logos with primary color

* test(theme): cover favicon color sync

* chore(login): remove unused metal logo component

---------

Co-authored-by: jxxghp <jxxghp@gmail.com>
This commit is contained in:
InfinityPacer
2026-07-17 13:01:25 +08:00
committed by GitHub
co-authored by jxxghp
parent 807711cae8
commit 39dd1b9e00
11 changed files with 170 additions and 700 deletions
+25
View File
@@ -0,0 +1,25 @@
import { applyDocumentThemeChrome } from '@/utils/themePalette'
import { describe, expect, it, vi } from 'vitest'
describe('theme palette', () => {
it('notifies the favicon renderer with the applied primary color', () => {
const handleFaviconChange = vi.fn()
window.addEventListener('moviepilot-theme-primary-color-change', handleFaviconChange)
try {
const result = applyDocumentThemeChrome('dark', {
background: '#0E1116',
primary: '#00BCD4',
})
const event = handleFaviconChange.mock.calls[0]?.[0] as CustomEvent<{ color: string }>
expect(result.primary).toBe('#00BCD4')
expect(document.documentElement.style.getPropertyValue('--initial-loader-color')).toBe('#00BCD4')
expect(handleFaviconChange).toHaveBeenCalledOnce()
expect(event.detail).toEqual({ color: '#00BCD4' })
} finally {
window.removeEventListener('moviepilot-theme-primary-color-change', handleFaviconChange)
}
})
})
+10
View File
@@ -80,6 +80,15 @@ function ensureThemeColorMeta(themeColor: string) {
document.head.appendChild(meta)
}
/** 通知启动层刷新浏览器 Tab 图标,图标颜色与当前主题主色保持一致。 */
export function syncThemeFavicon(primaryColor: string) {
window.dispatchEvent(
new CustomEvent('moviepilot-theme-primary-color-change', {
detail: { color: primaryColor },
}),
)
}
/**
* 同步浏览器首帧会使用的根节点底色和系统控件配色。
* iOS PWA 从后台恢复时可能先绘制 WebView 外壳,再等 Vue 响应式主题更新。
@@ -110,6 +119,7 @@ export function applyDocumentThemeChrome(
setMetaContent('meta[name="color-scheme"]', colorScheme === 'dark' ? 'dark light' : 'light dark')
ensureThemeColorMeta(background)
syncThemeFavicon(primary)
if (options.persistLoaderColors) {
localStorage.setItem('materio-initial-loader-bg', background)