e2186b2502
Bug 1 (critical): setTheme lacked try/catch around wx.setStorageSync.
If storage write throws (full / permission), the theme silently
fails to persist but UI has already changed → on next cold start
getCurrentTheme falls back to orange.
→ Wrap in try/catch; still apply UI change even if storage fails
(better to see the right color now than revert immediately).
Bug 2 (display): settings onShow called applyThemeToPage (updates
'theme' object) but never refreshed 'currentThemeId'. After tab
switching, the radio highlight showed the wrong theme.
→ Add setData({ currentThemeId }) in onShow.
Redundancy: theme now also saved as themeId in user_settings.
getCurrentTheme falls back to user_settings.themeId if app_theme
key is unexpectedly missing, providing a recovery path.
121 lines
3.3 KiB
JavaScript
121 lines
3.3 KiB
JavaScript
const storage = require('../../utils/storage')
|
|
const themeMod = require('../../utils/theme')
|
|
|
|
Page({
|
|
data: {
|
|
theme: { primary: '#FF6B35', primaryLight: '#FF8C5A', primaryBg: '#FFF3ED', primaryRgb: '255,107,53' },
|
|
themeStyle: '',
|
|
themes: themeMod.THEMES,
|
|
currentThemeId: 'orange',
|
|
plans: [
|
|
{ id: 'beginner', name: '初级', desc: '7天计划 · 30秒起步', days: 7 },
|
|
{ id: 'intermediate', name: '中级', desc: '14天计划 · 60秒起步', days: 14 },
|
|
{ id: 'advanced', name: '高级', desc: '30天计划 · 90秒起步', days: 30 }
|
|
],
|
|
currentPlanId: 'beginner',
|
|
dailyReminder: true,
|
|
reminderTime: '08:00',
|
|
voiceGuide: true,
|
|
vibrate: true
|
|
},
|
|
|
|
onLoad() {
|
|
const s = storage.getSettings()
|
|
const theme = themeMod.getCurrentTheme()
|
|
themeMod.applyThemeToPage(this)
|
|
this.setData({
|
|
currentPlanId: s.planId,
|
|
dailyReminder: s.dailyReminder,
|
|
reminderTime: s.reminderTime,
|
|
voiceGuide: s.voiceGuide,
|
|
vibrate: s.vibrate,
|
|
currentThemeId: theme.id
|
|
})
|
|
},
|
|
|
|
onShow() {
|
|
try {
|
|
const tb = this.getTabBar()
|
|
if (tb) tb.setData({ selected: 2 })
|
|
} catch (e) {}
|
|
themeMod.applyThemeToPage(this)
|
|
// sync highlighted theme in case it was changed elsewhere
|
|
this.setData({ currentThemeId: themeMod.getCurrentTheme().id })
|
|
},
|
|
|
|
onSelectTheme(e) {
|
|
const id = e.currentTarget.dataset.id
|
|
const theme = themeMod.setTheme(id)
|
|
this.setData({ currentThemeId: id })
|
|
|
|
try {
|
|
const tb = this.getTabBar()
|
|
if (tb) tb.setData({ themeStyle: themeMod.getThemeStyle(theme) })
|
|
} catch (e) {}
|
|
|
|
themeMod.applyThemeToPage(this)
|
|
},
|
|
|
|
onSelectPlan(e) {
|
|
const planId = e.currentTarget.dataset.id
|
|
const s = storage.getSettings()
|
|
s.planId = planId
|
|
storage.saveSettings(s)
|
|
this.setData({ currentPlanId: planId })
|
|
wx.showToast({ title: '计划已切换', icon: 'success', duration: 1200 })
|
|
},
|
|
|
|
onToggleReminder(e) {
|
|
const s = storage.getSettings()
|
|
s.dailyReminder = e.detail.value
|
|
storage.saveSettings(s)
|
|
this.setData({ dailyReminder: e.detail.value })
|
|
},
|
|
|
|
onReminderTimeChange(e) {
|
|
const s = storage.getSettings()
|
|
s.reminderTime = e.detail.value
|
|
storage.saveSettings(s)
|
|
this.setData({ reminderTime: e.detail.value })
|
|
},
|
|
|
|
onToggleVoice(e) {
|
|
const s = storage.getSettings()
|
|
s.voiceGuide = e.detail.value
|
|
storage.saveSettings(s)
|
|
this.setData({ voiceGuide: e.detail.value })
|
|
},
|
|
|
|
onToggleVibrate(e) {
|
|
const s = storage.getSettings()
|
|
s.vibrate = e.detail.value
|
|
storage.saveSettings(s)
|
|
this.setData({ vibrate: e.detail.value })
|
|
},
|
|
|
|
onCopyWechat() {
|
|
wx.setClipboardData({
|
|
data: '刘承',
|
|
success: () => {
|
|
wx.showToast({ title: '已复制', icon: 'success', duration: 1500 })
|
|
}
|
|
})
|
|
},
|
|
|
|
onClearData() {
|
|
wx.showModal({
|
|
title: '清除数据',
|
|
content: '将删除所有训练记录和连续打卡数据,此操作不可恢复。确定继续吗?',
|
|
confirmText: '确定清除',
|
|
confirmColor: '#E53935',
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
wx.removeStorageSync('training_records')
|
|
wx.removeStorageSync('current_streak')
|
|
wx.showToast({ title: '已清除', icon: 'success', duration: 1500 })
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|