feat(ui): 记录页月份联动与多项 UI 美化/修复

- records: 底部列表与月份选择器联动,新增 [本月|最近] 分段控件;标题/空态随模式切换
- leaderboard: 领奖台布局(冠军居中+皇冠)、次数标注于底座且三档水平对齐;头像 cloud:// 批量预解析提速(云函数需重新部署)
- index/timer: 主色底图标改白色变体修复隐形;目标数字按微信字体缩放补偿真机遮挡
- settings: 配色方案横滑渐变色卡;头像上传前压缩至 200px
- theme: 新增 teal 主题;暗黑背景统一对齐
- 圆形头像双保险(image 自身 border-radius)修复月/年榜方图

注: cloudfunctions/leaderboard 改动须在开发者工具重新部署才生效。
This commit is contained in:
2026-07-22 09:36:22 +08:00
parent 70b87d424d
commit 6176f2c341
32 changed files with 924 additions and 197 deletions
+22
View File
@@ -53,6 +53,15 @@ const PATHS = {
rankFill: '<path d="M3.5 18.49l6-6.01 4 4L22 6.92l-1.41-1.41-7.09 7.97-4-4L2 16.99z"/>',
crown: '<path d="M5 16L3 5l5.5 5L12 4l3.5 6L21 5l-2 11H5zm0 2h14v2H5z" fill-rule="evenodd"/>',
crownFill: '<path d="M5 16L3 5l5.5 5L12 4l3.5 6L21 5l-2 11H5zm0 2h14v2H5z"/>',
// Trophy (record celebrations) — Material emoji-events
trophy: '<path d="M19 5h-2V3H7v2H5c-1.1 0-2 .9-2 2v1c0 2.55 1.92 4.63 4.39 4.94.63 1.5 1.98 2.63 3.61 2.96V19H7v2h10v-2h-4v-3.1c1.63-.33 2.98-1.46 3.61-2.96C19.08 12.63 21 10.55 21 8V7c0-1.1-.9-2-2-2zM5 8V7h2v3.82C5.84 10.4 5 9.3 5 8zm14 0c0 1.3-.84 2.4-2 2.82V7h2v1z" fill-rule="evenodd"/>',
trophyFill: '<path d="M19 5h-2V3H7v2H5c-1.1 0-2 .9-2 2v1c0 2.55 1.92 4.63 4.39 4.94.63 1.5 1.98 2.63 3.61 2.96V19H7v2h10v-2h-4v-3.1c1.63-.33 2.98-1.46 3.61-2.96C19.08 12.63 21 10.55 21 8V7c0-1.1-.9-2-2-2zM5 8V7h2v3.82C5.84 10.4 5 9.3 5 8zm14 0c0 1.3-.84 2.4-2 2.82V7h2v1z"/>',
// Party popper (first-time celebrations) — Material celebration
party: '<path d="M2 22l14-5-9-9-5 14zm12.53-9.47l1.41-1.41 2.83 2.83-1.41 1.41-2.83-2.83zm.53-6.53L16.47 4.59l1.41-1.41 1.41 1.41-1.41 1.42zM21 11h-3v-2h3v2zm-5.65-4.35L14.24 5.54 15.65 4.1l1.11 1.11-1.41 1.44zM13 3V0h2v3h-2zM8.35 5.65l-1.41-1.44L8.06 3.1l1.41 1.41 1.12 1.14z" fill-rule="evenodd"/>',
partyFill: '<path d="M2 22l14-5-9-9-5 14zm12.53-9.47l1.41-1.41 2.83 2.83-1.41 1.41-2.83-2.83zm.53-6.53L16.47 4.59l1.41-1.41 1.41 1.41-1.41 1.42zM21 11h-3v-2h3v2zm-5.65-4.35L14.24 5.54 15.65 4.1l1.11 1.11-1.41 1.44zM13 3V0h2v3h-2zM8.35 5.65l-1.41-1.44L8.06 3.1l1.41 1.41 1.12 1.14z"/>',
// Sparkle (generic celebrations + confetti particles)
sparkle: '<path d="M12 2l1.8 5.7L19.5 9l-5.7 1.3L12 16l-1.8-5.7L4.5 9l5.7-1.3L12 2zm7 11l.9 2.8 2.8.9-2.8.9-.9 2.8-.9-2.8-2.8-.9 2.8-.9.9-2.8zM5 14l.7 2.1 2.1.7-2.1.7L5 19.5l-.7-2.1-2.1-.7 2.1-.7L5 14z" fill-rule="evenodd"/>',
sparkleFill: '<path d="M12 2l1.8 5.7L19.5 9l-5.7 1.3L12 16l-1.8-5.7L4.5 9l5.7-1.3L12 2zm7 11l.9 2.8 2.8.9-2.8.9-.9 2.8-.9-2.8-2.8-.9 2.8-.9.9-2.8zM5 14l.7 2.1 2.1.7-2.1.7L5 19.5l-.7-2.1-2.1-.7 2.1-.7L5 14z"/>',
form: '<path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z" fill-rule="evenodd"/>',
formFill: '<path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/>',
// Notification
@@ -132,6 +141,19 @@ const build = (theme) => {
out.deleteInactive = _svg(PATHS.delete, INACTIVE)
out.successFill = _svg(PATHS.roundCheckFill, s)
out.successLine = _svg(PATHS.roundCheck, INACTIVE)
// White variants for icons sitting on the theme-gradient card / disc
// (completion modal, podium accents, the index hero card, etc.) AND for
// icons rendered on the primary (filled) buttons, whose background is the
// same theme color as a *Fill variant — orange-on-orange would vanish.
// Baked-in white is REQUIRED: these are data-URI SVG <image> tags, so CSS
// color / currentColor cannot recolor them; only a white SVG works.
out.trophyWhite = _svg(PATHS.trophyFill, '#FFFFFF')
out.partyWhite = _svg(PATHS.partyFill, '#FFFFFF')
out.hotWhite = _svg(PATHS.hotFill, '#FFFFFF')
out.formWhite = _svg(PATHS.formFill, '#FFFFFF')
out.playWhite = _svg(PATHS.playFill, '#FFFFFF')
out.sparkleWhite = _svg(PATHS.sparkleFill, '#FFFFFF')
out.checkWhite = _svg(PATHS.check, '#FFFFFF')
return out
}