Files
wx_pbzc/custom-tab-bar/index.js
T
lc d5121d349f fix(dark): 调亮暗黑色调 + dock 跟随暗黑切换 + 图标文字放大
- theme/app.wxss: 暗黑背景 #0F0F12->#2C2C2E,卡片 #1C1C1E->#3A3A3C,
  bg-soft/border 同步提亮,拉开卡片与背景对比(原太黑看不到卡片)
- custom-tab-bar: dock 注册 wx.onThemeChange,系统切暗黑/明亮实时跟随
  (组件不在 getCurrentPages,app.js watchDarkMode 通知不到)
- custom-tab-bar: 新增 updateTheme,settings 手动切深色时通知 dock
- custom-tab-bar.wxss: dock 图标 44->50rpx,文字 20->23rpx,未激活
  opacity 0.5->0.7(更醒目)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 15:02:17 +08:00

110 lines
5.6 KiB
JavaScript

const themeMod = require('../utils/theme')
// Resolve the active theme synchronously at module load so the first paint
// already has the correct CSS variables — avoids a flash of the default theme.
const _initialTheme = themeMod.getCurrentTheme()
const _initialThemeStyle = themeMod.getThemeStyle(_initialTheme)
// Inactive icon color follows the dark mode: matches --text-secondary in dark
// mode and a softer gray in light mode. Kept in sync with utils/theme.js so
// icons don't sit awkwardly on the dock background in either theme.
const LIGHT_INACTIVE = '#999999'
const DARK_INACTIVE = '#98989F'
const _getInactiveColor = () => {
const darkMod = require('../utils/darkMode')
return darkMod.getInitialDarkMode() ? DARK_INACTIVE : LIGHT_INACTIVE
}
const _initialInactiveColor = _getInactiveColor()
const _svg = (path, fill) =>
'data:image/svg+xml,' + encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="' + fill + '">' +
path + '</svg>'
)
// 24x24 Material-style paths
const PATH_HOME = '<path d="M12 3l9 8h-3v9h-5v-6h-2v6H6v-9H3l9-8z"/>'
const PATH_HOME_LINE = '<path d="M12 5.2L5.5 11H7v8h2v-6h6v6h2v-8h1.5L12 5.2M12 3l9 8h-3v9h-5v-6h-2v6H6v-9H3l9-8z" fill-rule="evenodd"/>'
const PATH_CALENDAR = '<path d="M19 4h-2V2h-2v2H9V2H7v2H5C3.9 4 3 4.9 3 6v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V10h14v10zm0-12H5V6h14v2z"/><path d="M7 12h5v5H7z"/>'
const PATH_CALENDAR_LINE = '<path d="M19 4h-2V2h-2v2H9V2H7v2H5C3.9 4 3 4.9 3 6v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V10h14v10zm0-12H5V6h14v2z" fill-rule="evenodd"/>'
const PATH_RANK = '<path d="M7.5 21H2V9h5.5v12zm7.25-14h-5.5v14h5.5V7zM22 11h-5.5v10H22V11z"/>'
const PATH_RANK_LINE = '<path d="M7.5 21H2V9h5.5v12zm7.25-14h-5.5v14h5.5V7zM22 11h-5.5v10H22V11z" fill-rule="evenodd"/>'
const PATH_SETTINGS = '<path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58a.49.49 0 00.12-.61l-1.92-3.32a.49.49 0 00-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54a.484.484 0 00-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96a.49.49 0 00-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58a.49.49 0 00-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/>'
const PATH_SETTINGS_LINE = '<path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58a.49.49 0 00-.12-.61l-1.92-3.32a.49.49 0 00-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54a.484.484 0 00-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96a.49.49 0 00-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.07.62-.07.94s.02.64.07.94l-2.03 1.58a.49.49 0 00-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z" fill-rule="evenodd"/>'
const _buildIcons = (activeHex, inactiveHex) => {
const a = activeHex
return {
home: _svg(PATH_HOME_LINE, inactiveHex),
homeFill: _svg(PATH_HOME, a),
calendar: _svg(PATH_CALENDAR_LINE, inactiveHex),
calendarFill: _svg(PATH_CALENDAR, a),
rank: _svg(PATH_RANK_LINE, inactiveHex),
rankFill: _svg(PATH_RANK, a),
settings: _svg(PATH_SETTINGS_LINE, inactiveHex),
settingsFill: _svg(PATH_SETTINGS, a)
}
}
Component({
data: {
selected: 0,
theme: _initialTheme,
themeStyle: _initialThemeStyle,
svgIcons: _buildIcons(_initialTheme.primary, _initialInactiveColor)
},
lifetimes: {
attached() {
themeMod.applyThemeToPage(this)
// Rebuild icons in case the user changed theme/dark mode since module load
const theme = themeMod.getCurrentTheme()
this.setData({ svgIcons: _buildIcons(theme.primary, _getInactiveColor()) })
// The custom tabBar isn't in getCurrentPages(), so app.js's
// watchDarkMode (which notifies pages) never reaches it. Listen for
// system theme changes ourselves so the dock flips dark/light live,
// not just on the next tab switch.
if (!this._themeChangeBound && typeof wx.onThemeChange === 'function') {
this._onThemeChange = () => {
themeMod.applyThemeToPage(this)
this.setData({ svgIcons: _buildIcons(themeMod.getCurrentTheme().primary, _getInactiveColor()) })
}
try {
wx.onThemeChange(this._onThemeChange)
this._themeChangeBound = true
} catch (e) {}
}
}
},
pageLifetimes: {
show() {
themeMod.applyThemeToPage(this)
const theme = themeMod.getCurrentTheme()
this.setData({ svgIcons: _buildIcons(theme.primary, _getInactiveColor()) })
}
},
methods: {
switchTab(e) {
const index = e.currentTarget.dataset.index
const pages = [
'/pages/index/index',
'/pages/records/records',
'/pages/leaderboard/leaderboard',
'/pages/settings/settings'
]
if (index === this.data.selected) return
wx.switchTab({ url: pages[index] })
},
// Called by settings.onSelectDarkMode - the dock isn't in
// getCurrentPages() so the page-loop there misses it.
updateTheme() {
themeMod.applyThemeToPage(this)
this.setData({ svgIcons: _buildIcons(themeMod.getCurrentTheme().primary, _getInactiveColor()) })
}
}
})