This commit is contained in:
tamakyi
2026-10-19 15:23:11 +08:00
parent 86dc8384bc
commit e9fba8b9ed
84 changed files with 34468 additions and 5386 deletions
+87
View File
@@ -298,3 +298,90 @@ home-light / home-dark / explore-light 三页差异均 **0.024%**,bbox 只有
**教训(重要)**:像素测量脚本的扫描范围必须覆盖整幅图,循环上界不能与被测对象边界重合,
否则会把"边界截断"读成"图形特征"。之前 3.77→6.89 那组对比不知是否也受此影响,需复查时再确认。
## P2 补漏部署后复测(12:48)
- `base.css?v=20261019d` 上线,24023 字节与本地逐字节一致。
- 删掉 `fieldTypeLabelClass` 后**无运行期报错**:公开投票页 3 个(200,tb-chip 8/16/4,uk-label 各 1 = 状态)、
结果页 4 个(200,tb-chip 8/2/0/16,彩色 label 全 0,progress 7/0/10/19)、
草稿预览页 2 个(200,tb-chip 2/6)。
- 巡检 `/ /explore /rules /user/questions /user/profile?tab=security /_/admin6 /_/admin3` 全 200 无模板错误。
- `/user/votes/{id}/preview` 对**已发布**投票 302 到 `/vote/{token}` 是设计如此(vote.go:1093),不是回归。
- 截图核对:结果页「1 単選 / 2 多選」已为浅色胶囊,进度条 10px 圆角 6px;参与页字段头同样统一。
## "移动端语言/主题按钮不见了"排查(结论:非缺陷)
实测(线上测试环境,`--force-device-scale-factor=1`):
- 宽 360/390/414/640 → 顶栏 `.tb-nav-utils` = `display:none`,底栏 `#tb-mobile-utils` = `flex`,
rect `0,639,W,46`,语言 `block`、主题按钮 `block`(48×30,SVG 16×16),命中测试落在 `mobile-lang-select`。
- 宽 700/768/980 → 底栏 `none`,顶栏 `flex`,右上角地球 + 月亮都可见(截图 `outputs/t-nav-right.png`)。
- 页面级差异:`/_/admin6` 底栏**只有月亮没有语言下拉** —— `IsUserPage=true` 让语言块整体不渲染(桌面同样没有)。
- 生产 `box.shiroko.one` 仍是旧构建(页面无 `base.css` 引用,底栏是 emoji 月亮),移动端同样正常。
用户确认是忘了「移动端移到固定底栏」这个设计,不是 bug。
留下的真实缺口:**箱主页(最常见的外部入口)完全没有语言切换**,见 MEMORY.md 前端样式条目。
## 修正:箱主页无语言切换是设计,不是缺口
上一节把它记成"真实缺口"是错的。用户明确:**箱主页属箱主个性化,以箱主配置为主**,
语言入口不出现是有意为之(`IsUserPage` 门控)。
MEMORY.md 对应条目已改为"有意设计、别当 bug 修、要动先问"。
## 备份(用户要求)
`../TamaBox-v4-mainline-20261019-1445.tar.gz`(940K,302 条目,排除 .git/.workbuddy/outputs)。
P1 剩余两项(首屏跟随系统深色、首页 Waline 懒加载)用户明确**先不做**。
## 主题系统方案(只出设计,未实现)
用户诉求:箱主在后台选主题、仅对箱主相关页面生效;站点级默认主题在配置里;要一份可复用的主题底稿。
已确认的现状事实(设计依据):
- 设计令牌只有 16 个,集中在 `static/css/base.css` 的 `:root`(亮) + `html[data-theme="dark"]`(暗)。
- `<html lang>` 在 `templates/base/header.html:2`,服务端渲染;主题属性可放在这里(无 FOUC)。
- `question.Pager`(`route/question/page.go:45`)是 `/_/{domain}` 与 `/_/{domain}/{id}` 的共同中间件
→ 打主题标记的唯一合适位置。
- `/user/*` 与 `/_/*` 共用 `IsUserPage`(context.go:241 按 URL 前缀判定),所以「箱主相关页面」
≠ IsUserPage,必须单独区分,否则设置页会被主题化。
- `static/fs.go` 与 `templates/embed.go` 都是显式 embed 清单(新增主题 css 必须手加)。
- 用户模型已有大量个性化字段(usernamecolor/introcolor/background…),主题作为 `users.theme` 同族最自然。
- 分享卡是服务端绘制图片(`route/question/share.go`),不经过 CSS → 主题不覆盖它。
关键结论(写进方案的核心):令牌覆盖必须用
`html[data-theme-style="x"]`(0,1,1,压过 `:root` 的 0,1,0)+
`html[data-theme="dark"][data-theme-style="x"]`(0,2,1,压过 base 的 dark)。
只写浅色块会让深色模式被浅色令牌污染(同特异性 + 主题文件后加载)。
## 主题系统初版(已实现,未部署)
用户拍板:①作用范围跟随箱主配置(即 /_/ 箱主相关页面)②主题只做配色/图案/整页背景,**不涉及布局**
③主题名可本地化 ④分享卡不参与。
实现:
- `internal/theme`:注册表 + 三级回退。`[theme] default/available` → 白名单(slug 正则 + css 是否存在),
`Resolve(用户值)`:`default`→空串(不加载)/命中→该 slug/其余→站点默认。"" 与 "default" 语义不同:
""=跟随站点默认,"default"=箱主明确选基础外观。
设置页色块从主题 css 浅色块里抓 `--tb-bg`/`--tb-primary` 拼渐变(值必须过色值正则,防注入)。
- `users.theme varchar(32) default ''`(AutoMigrate 加列)+ `UpdateTheme` 单列更新。
- `question.Pager` 注入 `Data["ThemeSlug"]`(`/_/{domain}`、单题、密码页、分享卡路由共用这一个中间件);
header.html 在 `<html>` 输出 `data-theme-style` 并条件加载 `themes/<slug>.css`。
- 设置页账号面板末尾新增「主题外观」卡片(独立表单 `POST /user/profile/theme`,不塞进 UpdateProfile,
避免与该面板其它字段互相覆盖);`{{ if .Themes }}` 包裹,未配置主题时不显示。
- 静态版本号统一 `conf.StaticVersion = "20261019e"`(base.css 与主题 css 共用,改样式只改一处)。
- `static/fs.go` 改嵌目录 `css/themes`(以后加主题文件不用再改 embed 清单)。
- 主题文件:`_scaffold.css`(底稿,含 19 令牌说明 + 素材规格 + 特异性规范)、`default.css`(恒等,仅色块预览)、
`sakura.css`(示例,纯 CSS 网点图案 + 粉调)。
- base.css:body 接 `--tb-page-image` / `--tb-page-pattern` / `--tb-page-pattern-size` 两层背景;
**UIkit 主色是编译期常量 #1e87f0**,新增映射块把 a/uk-link、uk-button-primary、checkbox/radio、input:focus、
uk-tab active 接到 `--tb-primary`(基础主题值相同,默认外观零变化)。
实测(无头 Chrome,box 页 data-theme-style=sakura):
- 浅色 primary `#e5678f`/bg `#fff6f8`/pattern 16px 网点命中;深色 `#ff8ab0`/`#241a1f`,卡片表面各自跟随。
- 未选主题的 box 页:无 data 属性、无 themes link、主按钮仍 `rgb(30,135,240)` → 零回归。
踩坑:
1. 第一版 sakura 页「发送提问」还是蓝色 —— UIkit 组件色写死,令牌覆盖不到,必须按组件映射。
2. 预览里 `{{ .StaticVersion }}` 为空(预览夹具没这个键),导致按固定串替换主题 css 失败;改用正则。
3. `writePreview` 用全文搜 `data-theme="dark"` 判断是否已加属性 → 命中内联主题 css 里的选择器,深色预览没生效;
改为只看 `<html ...>` 开标签。
4. 脚本改 form/user.go 时把插入块写在结构体中间,拼出 `} Language ...`;靠 Read 复查发现并重写。
+22
View File
@@ -88,6 +88,13 @@
- 静态文件是**显式 embed 清单**(`static/fs.go`),新增 css/js 必须手动加进 `//go:embed` 那行,否则运行期 404。
- 主题属性在 head 内联脚本里打(cookie `theme`),**不能挪回 body**,否则深色用户白闪。
- 页面级样式尽量用类,不用 `style=`(深色下内联写死色值会露白,`.tb-img-uploader` 踩过)。
- **移动端(≤640px)语言切换与主题按钮不在顶栏**:顶栏 `.tb-nav-utils` 被 `display:none !important` 隐藏,
改由 `#tb-mobile-utils` 固定底栏承载(`position:fixed;bottom:0;z-index:1000`,body 预留 `padding-bottom:56px`)。
顶栏图标只在 >640px 出现。用户曾误以为"按钮不见了",先解释位置再排查。
⚠️ `/_/{domain}` 箱主页把 `IsUserPage` 设为 true(`route/question/page.go:133`),语言切换整块包在
`{{ if not .IsUserPage }}` 里(header.html:272 桌面 / :314 移动),所以**箱主页没有语言切换入口**——
**这是有意设计,不是缺陷**(用户 2026-10-19 明确:箱主页属箱主个性化,以箱主配置为准)。
别把它当 bug 去"修",要动先问。
- ⚠️ **UIkit 3.3.3 有 `.uk-flex::before/::after{display:none}`**:给带 `uk-flex` 的元素加伪元素遮罩必须写
`.tb-cover.uk-flex::after` 这类复合选择器,否则静默失效(不报错)。
- 视觉自检:`TEST_PREVIEW=1 go test ./templates -run TestGenPreview` → `outputs/preview-*.html`;
@@ -99,6 +106,21 @@
(置顶/私密/被举报/已读、投票未开始/进行中/已结束/已参与)。题型配色曾由 Go 的
`fieldTypeLabelClass` 生成(已删),故 grep `uk-label` 搜不到,改前先搜模板函数名。
## 主题系统
- 一套主题 = `static/css/themes/<slug>.css` 一个文件,**只覆盖令牌**(配色/图案/整页背景),不碰布局。
新增主题:复制 `_scaffold.css` → 改名 → 登记到 `[theme] available`;`static/fs.go` 已嵌整个目录,无需改清单。
- 作用域:仅 `/_/*` 箱主相关页面(`question.Pager` 注入 `ThemeSlug`);`/user` 后台与全站其它页面不主题化。
优先级 `users.theme > [theme] default > 基础外观`;`""`=跟随站点默认,`"default"`=箱主明确选基础外观(不加载 css)。
- ⚠️ 主题 css **必须成对写**:`html[data-theme-style="x"]`(0,1,1,压过 `:root` 的 0,1,0)+
`html[data-theme="dark"][data-theme-style="x"]`(0,2,1,压过 base 的 dark)。只写浅色块会让深色模式被浅色令牌污染。
兜底测试 `TestThemeCSSComplete`(检查两个选择器 + 10 个颜色令牌齐全)。
- ⚠️ **UIkit 3.3.3 的主题色是编译期常量 `#1e87f0`**,令牌注入不进去。base.css 里有一段「UIkit 组件跟随主题色」
按组件映射(a/uk-link、uk-button-primary、checkbox/radio、input:focus、uk-tab active)。新增会显示主色的组件时,
先确认它是否已映射,否则换主题后会出现「页面变粉、按钮还蓝」。
- 静态资源版本号统一 `conf.StaticVersion`(base.css 与主题 css 共用),改样式只改这一处;页面通过 `.StaticVersion` 取。
- 整页背景用 `--tb-page-image`(cover)与 `--tb-page-pattern`(平铺,`--tb-page-pattern-size` 控尺寸),图案叠在图片之上。
## 其它约定
- 校验靠 `valid:"required;maxlen:N"` 标签(`internal/form/*.go`),别在 handler 手写。