feat: 深色模式基础设施 (system theme + 跟随系统)

This commit is contained in:
2026-07-08 11:33:09 +08:00
parent a88c4da361
commit c43f1d7389
6 changed files with 88 additions and 4 deletions
+11
View File
@@ -1,9 +1,20 @@
const themeMod = require('./utils/theme') const themeMod = require('./utils/theme')
const cloud = require('./utils/cloud') const cloud = require('./utils/cloud')
const storage = require('./utils/storage') const storage = require('./utils/storage')
const darkMod = require('./utils/darkMode')
App({ App({
async onLaunch() { async onLaunch() {
// Init dark mode listener (refreshes all open pages when system theme changes)
darkMod.watchDarkMode((isDark) => {
const pages = getCurrentPages()
pages.forEach(p => {
if (p && typeof p.applyThemeToPage === 'function') {
p.applyThemeToPage()
}
})
})
// Init cloud storage (no-op if not configured) // Init cloud storage (no-op if not configured)
cloud.init() cloud.init()
+2
View File
@@ -25,5 +25,7 @@
{ "pagePath": "pages/settings/settings", "text": "设置" } { "pagePath": "pages/settings/settings", "text": "设置" }
] ]
}, },
"darkmode": true,
"themeLocation": "theme.json",
"sitemapLocation": "sitemap.json" "sitemapLocation": "sitemap.json"
} }
+1
View File
@@ -11,6 +11,7 @@ page {
font-size: 28rpx; font-size: 28rpx;
color: var(--text); color: var(--text);
background-color: var(--bg) !important; background-color: var(--bg) !important;
transition: background-color 0.3s ease, color 0.3s ease;
} }
.container { .container {
+16
View File
@@ -0,0 +1,16 @@
{
"light": {
"navigationBarBackgroundColor": "#FF6B35",
"navigationBarTextStyle": "white",
"backgroundColor": "#F5F5F5",
"backgroundColorTop": "#F5F5F5",
"backgroundColorBottom": "#F5F5F5"
},
"dark": {
"navigationBarBackgroundColor": "#FF6B35",
"navigationBarTextStyle": "white",
"backgroundColor": "#0F0F12",
"backgroundColorTop": "#0F0F12",
"backgroundColorBottom": "#0F0F12"
}
}
+49
View File
@@ -0,0 +1,49 @@
/**
* 系统深色模式监听 — 提供初始值与变更回调
* 旧设备 wx.onThemeChange 失败时退化为只读一次
*/
const STORAGE_KEY = 'dark_mode_pref'
function _readSystemTheme() {
try {
const info = wx.getSystemInfoSync()
return info.theme === 'dark' ? true : false
} catch (e) {
return false
}
}
function getInitialDarkMode() {
const pref = wx.getStorageSync(STORAGE_KEY) || 'system'
if (pref === 'system') return _readSystemTheme()
return pref === 'dark'
}
function getPref() {
return wx.getStorageSync(STORAGE_KEY) || 'system'
}
function setPref(value) {
if (!['system', 'light', 'dark'].includes(value)) return
wx.setStorageSync(STORAGE_KEY, value)
}
function watchDarkMode(onChange) {
if (typeof wx.onThemeChange !== 'function') return
try {
wx.onThemeChange(({ theme }) => {
const pref = getPref()
if (pref === 'system') onChange(theme === 'dark')
})
} catch (e) {
// 旧设备不支持,忽略
}
}
module.exports = {
getInitialDarkMode,
getPref,
setPref,
watchDarkMode
}
+9 -4
View File
@@ -94,19 +94,24 @@ const setTheme = (id) => {
return theme return theme
} }
const getThemeStyle = (theme) => { const getThemeStyle = (theme, isDark = false) => {
const t = theme || getCurrentTheme() const t = theme || getCurrentTheme()
return `${BASE_VARS}--primary:${t.primary};--primary-light:${t.primaryLight};--primary-bg:${t.primaryBg};--primary-rgb:${t.primaryRgb};` const baseVars = isDark
? '--text:#E5E5E7;--text-secondary:#98989F;--bg:#0F0F12;--card-bg:#1C1C1E;--border:#2C2C2E;--success:#30D158;'
: '--text:#333333;--text-secondary:#999999;--bg:#F5F5F5;--card-bg:#FFFFFF;--border:#EEEEEE;--success:#4CAF50;'
return `${baseVars}--primary:${t.primary};--primary-light:${t.primaryLight};--primary-bg:${t.primaryBg};--primary-rgb:${t.primaryRgb};`
} }
const applyThemeToPage = (self) => { const applyThemeToPage = (self) => {
const darkMod = require('./darkMode')
const theme = getCurrentTheme() const theme = getCurrentTheme()
const nextStyle = getThemeStyle(theme) const isDark = darkMod.getInitialDarkMode()
const nextStyle = getThemeStyle(theme, isDark)
// Skip setData if nothing changed — avoid unnecessary re-renders on every onShow // Skip setData if nothing changed — avoid unnecessary re-renders on every onShow
if (self.data && self.data.themeStyle === nextStyle) { if (self.data && self.data.themeStyle === nextStyle) {
return return
} }
self.setData({ theme, themeStyle: nextStyle }) self.setData({ theme, themeStyle: nextStyle, isDark })
_setNavBarColor(theme.primary) _setNavBarColor(theme.primary)
} }