feat(ui): 记录页月份联动与多项 UI 美化/修复
- records: 底部列表与月份选择器联动,新增 [本月|最近] 分段控件;标题/空态随模式切换 - leaderboard: 领奖台布局(冠军居中+皇冠)、次数标注于底座且三档水平对齐;头像 cloud:// 批量预解析提速(云函数需重新部署) - index/timer: 主色底图标改白色变体修复隐形;目标数字按微信字体缩放补偿真机遮挡 - settings: 配色方案横滑渐变色卡;头像上传前压缩至 200px - theme: 新增 teal 主题;暗黑背景统一对齐 - 圆形头像双保险(image 自身 border-radius)修复月/年榜方图 注: cloudfunctions/leaderboard 改动须在开发者工具重新部署才生效。
This commit is contained in:
+54
-3
@@ -14,6 +14,13 @@ Page({
|
||||
todayDone: false,
|
||||
todayDuration: 0,
|
||||
todayTargetText: '',
|
||||
// Ring number font size in rpx. WeChat auto-scales text by the user's
|
||||
// font-size setting (fontSizeScaleFactor) but does NOT scale rpx box
|
||||
// dimensions — so on a real device with enlarged system font the 84rpx
|
||||
// number grows past the fixed-size circular ring and gets clipped. We
|
||||
// cancel that scale here so the number renders at a constant visual size
|
||||
// (matching the devtools/simulator) on every device. See _readFontScale().
|
||||
targetTimeFontSize: 84,
|
||||
streakCount: 0,
|
||||
planName: '',
|
||||
planDay: 1,
|
||||
@@ -28,9 +35,50 @@ Page({
|
||||
|
||||
onLoad() {
|
||||
themeMod.applyThemeToPage(this)
|
||||
this._readFontScale()
|
||||
this._firstShow = true
|
||||
},
|
||||
|
||||
/**
|
||||
* Read the device's WeChat font-size scale and compensate the ring number
|
||||
* so it never overflows the fixed circular clip on real devices.
|
||||
*
|
||||
* WeChat auto-applies `fontSizeScaleFactor` to ALL text (including rpx font
|
||||
* sizes) but leaves rpx box dimensions untouched. A user who bumps up the
|
||||
* system font therefore sees enlarged text inside a non-enlarged ring.
|
||||
*
|
||||
* CRITICAL asymmetry: the DevTools simulator reports the SAME
|
||||
* `fontSizeScaleFactor` as a real device (the user's actual WeChat setting)
|
||||
* but does NOT actually scale rendered text. So if we compensate there, the
|
||||
* number ends up too small in the simulator. We therefore SKIP the
|
||||
* compensation under DevTools (host.env === 'devtools') and keep the design
|
||||
* size — matching what the simulator renders literally.
|
||||
*
|
||||
* On real devices, dividing our design size by the factor cancels the
|
||||
* auto-scale, keeping the number a constant 84rpx-equivalent everywhere.
|
||||
* Bounded so a bad reading can only ever make the number smaller (safe),
|
||||
* never larger (overflow).
|
||||
*/
|
||||
_readFontScale() {
|
||||
let factor = 1
|
||||
try {
|
||||
const info = wx.getAppBaseInfo ? wx.getAppBaseInfo() : wx.getSystemInfoSync()
|
||||
const isDevtools = info.host && info.host.env === 'devtools'
|
||||
if (!isDevtools) {
|
||||
if (typeof info.fontSizeScaleFactor === 'number' && info.fontSizeScaleFactor > 0) {
|
||||
factor = info.fontSizeScaleFactor
|
||||
} else if (typeof info.fontSizeSetting === 'number' && info.fontSizeSetting > 0) {
|
||||
// fontSizeScaleFactor == currentFontSize / standardFontSize(17px)
|
||||
factor = info.fontSizeSetting / 17
|
||||
}
|
||||
}
|
||||
} catch (e) {}
|
||||
const DESIGN = 84
|
||||
let size = Math.round(DESIGN / factor)
|
||||
size = Math.max(48, Math.min(96, size))
|
||||
this.setData({ targetTimeFontSize: size })
|
||||
},
|
||||
|
||||
onShow() {
|
||||
themeMod.applyThemeToPage(this)
|
||||
try {
|
||||
@@ -86,9 +134,12 @@ Page({
|
||||
const customPlans = storage.getCustomPlans()
|
||||
const plan = planMod.getPlan(settings.planId, customPlans)
|
||||
const planDay = planMod.getPlanDay(settings.planId, allRecords, settings.planStartDate, customPlans)
|
||||
const target = planMod.getTodayTarget(settings.planId, Math.min(planDay, plan.totalDays))
|
||||
const clampedDay = Math.min(planDay, plan.totalDays)
|
||||
const target = planMod.getTodayTarget(settings.planId, clampedDay)
|
||||
|
||||
const theme = themeMod.getCurrentTheme()
|
||||
// 防御:totalDays 为 0(极端数据损坏)时避免除以 0 得到 NaN
|
||||
const planProgress = plan.totalDays > 0 ? Math.round((clampedDay / plan.totalDays) * 100) : 0
|
||||
this.setData({
|
||||
theme,
|
||||
icons: iconsMod.build(theme),
|
||||
@@ -98,9 +149,9 @@ Page({
|
||||
todayTargetText: util.formatTime(target),
|
||||
streakCount: streak.count,
|
||||
planName: plan.name,
|
||||
planDay: Math.min(planDay, plan.totalDays),
|
||||
planDay: clampedDay,
|
||||
planTotal: plan.totalDays,
|
||||
planProgress: Math.round((Math.min(planDay, plan.totalDays) / plan.totalDays) * 100)
|
||||
planProgress
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user