fix(ui): 初始背景跟随外观 + 修复跟随系统
- app.config 移除写死的浅色背景,交给 theme.json 按系统外观选择首帧底色 - 跟随系统模式增加 setInterval 轮询兜底,onThemeChange 不回调时也能跟上切换
This commit is contained in:
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1 +1 @@
|
||||
{"darkmode":true,"themeLocation":"theme.json","pages":["pages/index/index","pages/shop/index","pages/shop/detail/index","pages/product/index","pages/diy/index","pages/diy/stickerEdit/index","pages/checkout/index","pages/designList/index","pages/orders/index","pages/profile/index","pages/service/index","pages/wordcloud/index","pages/orderDetail/index","pages/address/index","pages/settings/index","pages/agreement/index","pages/userDatabase/index"],"window":{"backgroundTextStyle":"dark","navigationStyle":"custom","navigationBarBackgroundColor":"#faf7f2","backgroundColor":"#faf7f2","backgroundColorTop":"#faf7f2","backgroundColorBottom":"#faf7f2","navigationBarTextStyle":"black"},"tabBar":{"custom":true,"list":[{"pagePath":"pages/index/index","text":"首页"},{"pagePath":"pages/shop/index","text":"商品"},{"pagePath":"pages/designList/index","text":"设计清单"},{"pagePath":"pages/orders/index","text":"订单"},{"pagePath":"pages/profile/index","text":"我的"}]}}
|
||||
{"darkmode":true,"themeLocation":"theme.json","pages":["pages/index/index","pages/shop/index","pages/shop/detail/index","pages/product/index","pages/diy/index","pages/diy/stickerEdit/index","pages/checkout/index","pages/designList/index","pages/orders/index","pages/profile/index","pages/service/index","pages/wordcloud/index","pages/orderDetail/index","pages/address/index","pages/settings/index","pages/agreement/index","pages/userDatabase/index"],"window":{"navigationStyle":"custom"},"tabBar":{"custom":true,"list":[{"pagePath":"pages/index/index","text":"首页"},{"pagePath":"pages/shop/index","text":"商品"},{"pagePath":"pages/designList/index","text":"设计清单"},{"pagePath":"pages/orders/index","text":"订单"},{"pagePath":"pages/profile/index","text":"我的"}]}}
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+2
-9
@@ -23,16 +23,9 @@ export default defineAppConfig({
|
||||
'pages/userDatabase/index'
|
||||
],
|
||||
window: {
|
||||
backgroundTextStyle: 'dark',
|
||||
// 初始窗口/导航背景交给 theme.json 按系统外观自动选择,
|
||||
// 避免首帧先固定成浅色再被 JS 切到深色而闪烁。
|
||||
navigationStyle: 'custom',
|
||||
// 顶部/窗口颜色先显式固定为小程序浅色主题,避免 iOS 顶部区域跟随系统深色;
|
||||
// 应用启动后页面 Hook 会按小程序内主题实时覆盖上面的值。
|
||||
navigationBarBackgroundColor: '#faf7f2',
|
||||
backgroundColor: '#faf7f2',
|
||||
backgroundColorTop: '#faf7f2',
|
||||
backgroundColorBottom: '#faf7f2',
|
||||
// 状态栏文字默认黑字;各页面 useStatusBar 会按小程序主题覆盖它。
|
||||
navigationBarTextStyle: 'black',
|
||||
},
|
||||
tabBar: {
|
||||
custom: true,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createContext, useContext, useState, useCallback, useEffect } from 'react'
|
||||
import { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react'
|
||||
import Taro, { useDidShow } from '@tarojs/taro'
|
||||
import { View } from '@tarojs/components'
|
||||
import { getTheme, setTheme as saveTheme, resolveTheme, setDetectedSystemTheme, type ThemeMode } from '../utils/store'
|
||||
@@ -31,6 +31,7 @@ type ThemeChangeApi = {
|
||||
export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
||||
const [theme, set] = useState<ThemeMode>(getTheme())
|
||||
const [resolvedTheme, setResolved] = useState<'light' | 'dark'>(resolveTheme(getTheme()))
|
||||
const systemThemeRef = useRef<'light' | 'dark' | null>(null)
|
||||
|
||||
const updateResolved = useCallback((mode: ThemeMode) => {
|
||||
setResolved(resolveTheme(mode))
|
||||
@@ -42,6 +43,7 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
||||
*/
|
||||
const updateFromSystem = useCallback((t: 'light' | 'dark') => {
|
||||
setDetectedSystemTheme(t)
|
||||
systemThemeRef.current = t
|
||||
if (getTheme() === 'auto') {
|
||||
setResolved(t)
|
||||
}
|
||||
@@ -102,6 +104,23 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
||||
}
|
||||
}, [updateFromSystem])
|
||||
|
||||
// 部分机型/工具上 onThemeChange 不回调,自动模式再轮询兜底,保证系统切换能跟上
|
||||
useEffect(() => {
|
||||
if (theme !== 'auto') return
|
||||
const timer = setInterval(() => {
|
||||
try {
|
||||
const info = Taro.getAppBaseInfo()
|
||||
const next = info.theme === 'dark' ? 'dark' : 'light'
|
||||
if (next !== systemThemeRef.current) {
|
||||
updateFromSystem(next)
|
||||
}
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
}, 2000)
|
||||
return () => clearInterval(timer)
|
||||
}, [theme, updateFromSystem])
|
||||
|
||||
// 广播实际生效主题,供 custom-tab-bar 等独立组件订阅
|
||||
useEffect(() => {
|
||||
Taro.eventCenter.trigger(THEME_CHANGE_EVENT, resolvedTheme)
|
||||
|
||||
@@ -42,3 +42,16 @@ test('app sets page background before first render without a blinking full fade'
|
||||
assert.match(appSource, /componentWillMount/)
|
||||
assert.doesNotMatch(appCss, /animation:\s*page-fade-in/)
|
||||
})
|
||||
|
||||
test('delegates initial background to themeLocation instead of hardcoding light', () => {
|
||||
const config = read('src/app.config.ts')
|
||||
assert.match(config, /themeLocation:\s*'theme\.json'/)
|
||||
assert.doesNotMatch(config, /navigationBarBackgroundColor:\s*'#faf7f2'/)
|
||||
assert.doesNotMatch(config, /backgroundColorTop:\s*'#faf7f2'/)
|
||||
})
|
||||
|
||||
test('polls the system theme while following the system', () => {
|
||||
const ctx = read('src/context/ThemeContext.tsx')
|
||||
assert.match(ctx, /setInterval/)
|
||||
assert.match(ctx, /getAppBaseInfo\(\)/)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user