Files
tamabox/.workbuddy/memory/2026-09-04.md
T
tamakyi e3e59e7c69 chore: baseline snapshot before moderation-strictness feature
Repo .git was damaged (refs/ missing, index truncated, object store near-empty).
Repaired via git init (rebuilt refs), stale index preserved as .git/index.corrupt-20260910.bak,
then full worktree committed as a rollback baseline.
2026-09-10 10:56:27 +08:00

100 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-09-04
- 调研并输出 /user/profile 页面(account 面板)UI 优化评审与改造方案(等待用户批准后实施)。
- 关键结论:
- 密码强制登出:`users.password_version` + 会话 `pwd_ver` 机制已存在(internal/context/auth.go authenticatedUser),改密后旧会话下次请求即失效;但 UpdateProfile 改密后仍重定向 /user/profile,被 Toggle 以「请先登录」错误文案弹回 /login,成功 flash 被吞。改造方向:改密成功 → Session.Flush() + success flash(复用 auth.errPasswordChanged)→ 直接跳 /login。
- 头像/背景裁剪:项目无任何 crop 库;第三方库全部自托管于 R2(r2.337845818.best/tamabox/cdn)。候选方案:Cropper.js 内嵌 static/(需扩 static/fs.go embed 规则)。当前 avatarPlaceholder 文案自嘲"非1:1会扁"但无强制。
- 复用点:profile-tabs 面板、Pickr 颜色选择、easy.qrcode 预览、UIkit modal/accordion、imagecheck 像素校验、storage.UploadPictureToS3(自动转 WebP、宽>1920 缩放)。
- i18n 四语言字典 key 全等校验(i18n_test.go TestDictionaryComplete),新增词条须同步 4 个 dict 文件。
## 下午:profile account 面板改造已实施(用户已批准方案)
- 决策:Cropper.js 走自有 R2 CDN(`lib/cropperjs/1.6.2/`,用户自行上传);改密立即登出跳登录页;卡片分区+折叠(中等重构);前后端双比例校验。
- 改动清单:
- `route/user/profile.go`:avatar→storage.UploadAvatarToS3、background→storage.UploadBackgroundToS3(新增),改密成功(passwordChanged 标志)→ Session.Flush + flash(profile.flash.passwordChanged) → /login;比例不符 flash 提示(profile.err.avatarRatio / backgroundRatio)。
- `internal/imagecheck/imagecheck.go`:新增 ErrBadAspectRatio + CheckAspectRatio + DefaultAspectTolerance(0.01);`imagecheck_test.go` 新增 4 个用例。
- `internal/storage/s3.go`:抽 uploadPictureToS3 内部分管线(aspect 可选),UploadAvatarToS3=1:1、UploadBackgroundToS3=16:9,魔数后、像素总量前校验;原有 UploadPictureToS3 兼容签名(其他调用方不变)。
- `internal/i18n/dict_*.go`(4 语):新增 15 词条(card.* 4、cropHint 2、cropTitle/cropConfirm、pwdNote、pickAvatar/pickBackground、err.avatarRatio/backgroundRatio/cropLibUnavailable、flash.passwordChanged)。
- `templates/user/profile.html`:account 面板重构为 8 张卡片(基础资料/头像与背景[预览+裁剪]/二维码样式折叠/社交折叠/修改密码[随主表单]/标签/页面密码/账号操作);头像 96px 圆、背景 16:9 预览;Cropper 弹窗+写回 file input 逻辑;accordion 展开时重绘二维码预览;新增 .tb-pcard 等样式与暗色适配、移动端单列。
- 验证:go build ./...(用 dev/webpstub overlay 方式,Windows 无 libwebp)通过;go test internal/i18n + internal/imagecheck 通过;dev/checktpl 全模板语法 OK;HTML 标签开闭平衡校验通过。
- 待办:R2 上传 cropper.min.{js,css} 到 r2.337845818.best/tamabox/cdn/lib/cropperjs/1.6.2/ 后即可端到端生效;未做浏览器实测(需本地 DB/Redis)。
## 晚间:修复部署环境 `UIkit is not defined`(Rocket Loader 时序)
- 现象:VM234:42 Uncaught ReferenceError: UIkit is not defined;更换头像/背景按钮点击无效果。
- 根因:裁剪脚本(templates/user/profile.html 末尾)IIFE 解析期即执行 `var modalObj = UIkit.modal(modalEl)`;UIkit 在 base/header.html 是 defer 加载,Cloudflare Rocket Loader 把该内联脚本激活在 UIkit 执行前 → 抛错中断整个脚本 → `[data-pick-image]` 监听(其后)从未绑定。
- 修复(templates/user/profile.html,4 处):
1. `modalObj` 改为 null 懒创建(startCrop 内、依赖就绪后 `UIkit.modal(modalEl)`);
2. 新增 `notify()`:UIkit 可用→UIkit.modal.alert,否则回退原生 window.alert;
3. 新增 `whenReady(cb)`:轮询等待 window.UIkit && window.Cropper,超时 3s → notify(MSG_NO_CROPPER);文件大小校验前置(不依赖库);
4. 脚本标签加 `data-cfasync="false"`,按钮监听尽早同步绑定。
- 经验:模板内联脚本**禁止在解析期触碰 defer/外部库全局对象**(UIkit/Pickr 等),一律在用户事件回调内或依赖就绪后使用——Rocket Loader 会打乱执行序;全站内联脚本仅裁剪脚本踩中此坑。
- 验证:node --check 通过(模板占位符替换后);R2 上 cropper 文件此前 curl 仍不可达(HTTP 000),用户需先上传,否则选图后 3s 提示「裁剪组件暂不可用」——需提醒用户。
## 晚间(二):图像保存 UX + 同行居中 + console 噪音排查
- 用户反馈:图像上传/裁剪已可用;但「保存修改」按钮在「修改密码」卡片里,改图后要去那里点击才生效,不直观;且头像修改显示在左上角别扭。
- 改动(templates/user/profile.html):
1. 头像与背景卡片内新增本地保存按钮(type=submit,label 新 i18n key `profile.saveMedia`,随主表单提交,裁剪写回的文件域一并上传);CSS `.tb-media-save`(居中条)。
2. `.tb-media-row` 改 `justify-content:center`、子项 `flex:0 1 auto` + column 居中、`tb-frame-bg` 固定 320px(max-width:100%);移动端 ≤640 子项 `flex-basis:100%` 上下堆叠居中、背景图全宽、保存按钮全宽。
3. 4 语字典新增 `profile.saveMedia`(zh-CN 保存头像与背景 / zh-TW 儲存頭像與背景 / en Save avatar & background / ja アイコンと背景を保存)。
- console 噪音排查结论:`inspector.js` AbortError/Request timeout/responseType arraybuffer 报错**非项目代码**(全仓库 grep 无 inspector/fetch 包装);是浏览器 XHR 监控类扩展包装 fetch/XHR + Rocket Loader 激进异步调度(arraybuffer 脚本请求被中止)造成的误报。建议无痕窗口验证 + 或 Cloudflare 关闭 Rocket Loader。
- 验证:gofmt -w 4 个 dict;go test ./internal/i18n/ 通过;go run ./dev/checktpl 全模板语法 OK。
## 晚间(三):二维码/社交默认展开 + 头像背景组件等宽 + 每卡片独立保存按钮
- 用户要求:①二维码、社交两块默认展开;②更换头像/更换背景组件大小一致(原头像 96 圆 vs 背景 320 宽预览悬殊);③为 account 面板每块加独立保存按钮(仿头像背景卡样式)。
- 改动(templates/user/profile.html):
1. 卡片3/4 的 uk-accordion `<li>` 加 `uk-open` 默认展开(仍可折叠,multiple:true)。
2. `.tb-media-item` 固定等宽列 320px(flex:0 0 320 + max-width:100%),头像预览 96→120px、背景帧 width:100%(列内满宽 16:9);`.tb-media-actions .uk-button` min-width:150px 令两个更换按钮同宽。移动端:头像 80→96px、item 全宽堆叠、按钮全宽。
3. 保存按钮:基础资料(profile.saveBasic)/头像背景(已有 saveMedia)/二维码(profile.saveQR)/社交(profile.saveSocial)/改密(原 admin.saveProfile 改 profile.savePassword「确认修改密码」)——均为同表单 type=submit(提交整表),复用居中类 `.tb-card-save`(与 .tb-media-save 同规则)。
4. 二维码预览:默认展开后从其它 tab(?tab=question 等)切回 account 面板时不会再触发 accordion 'shown' → showPanel 里 account 时调 `window.__tbRefreshAccountPreview`(IIFE 内暴露的 debouncedUpdatePreview)重绘。
- i18n 4 语新增 saveBasic/savePassword/saveQR/saveSocial;admin.saveProfile key 保留未删(四语仍在,仅模板不再引用)。
- 验证:go test ./internal/i18n/ 通过;go run ./dev/checktpl OK。
## 晚间(四):头像/背景框等高 + 按钮统一居中 + 页面纵向压缩
- 用户反馈:①头像框偏小,希望与背景框显示高度一致;②按钮有的居中有的居左,要求统一并压缩空间。
- 改动(templates/user/profile.html,纯 CSS/结构):
1. 预览框等高:头像 120→150px 圆;背景框 267×150(16:9,与头像等高);媒体列 320→280 等宽;行间隙 20/40→14/32;移动端头像 96→120px。
2. 按钮统一居中:账号操作卡片(登出/导出/停用)`text-align:center` + 行距 12→9px;卡片6 标签、卡片7 页面密码按钮 `div.uk-margin`→`div.tb-card-save`;提问面板 updateHarassment/updateAskPassword、私聊面板 updateChat 三个按钮同改居中。
3. 压缩:`.tb-pcard` padding 16/16/10→13/14/8、margin-bottom 16→12、标题 margin 12→10;新增 `.profile-panel .uk-margin { margin-bottom: 12px }`(全面板字段间距 20→12)。
- 范围说明:global-blockwords / feature-control-form 两个 partial 模板(三面板共用)内按钮未改(避免影响其它页面),如需统一再单独处理。
- 验证:go run ./dev/checktpl OK。
## 晚间(五):账号操作按钮分组同行 + partial 内按钮居中
- 用户要求:①导出数据/导出全部数据按钮同一行;②退出登录/停用我的账号同一行;③屏蔽词设置、计数设置也居中。
- 改动:
1. `templates/user/profile.html`:账号操作卡重构为 `.tb-account-pair`(flex 居中,两按钮同行):导出组(默认按钮×2,target=_blank 表单)+ 说明行 `.tb-account-note`;登出组(danger 按钮+停用链接)+ 说明行。旧的 `.tb-account-action` 行式堆叠 CSS 删除,暗色规则改 `.tb-account-note`。
2. `.feat-quota-line` 加 text-align:center;`.feat-actions` 加 justify-content:center(保存/重置计数按钮居中)——覆盖 feature-control-form(提问/私聊/投票共用)。
3. `templates/user/global-blockwords.html`:提交按钮行 `.uk-margin` → `.tb-card-save`(居中);该 partial 仅 profile.html 引用,无外溢。
4. 说明文字合并保留:exportHint+exportJSONHint 合并一行小字,deactivateHint(含 <b>)保留在其按钮组下方(deactivate 确认页另有完整警告文案)。
- 验证:go run ./dev/checktpl OK。
## 晚间(六):修复导出按钮点击后永久「提交中」转圈
- 现象:导出数据/导出全部数据(target=_blank 下载表单)文件能下,但按钮永久转圈禁用。
- 根因:`templates/base/footer.html` 全局 submit 反馈(P0 防重复提交)把触发按钮置「转圈+提交中」并禁用;复位仅靠整页导航/bfcache pageshow。`target="_blank"` 下载表单当前页不导航 → 无复位机会 → 永久卡死。
- 修复(双保险):
1. `templates/user/profile.html`:两个导出 form 加 `data-tb-skip-submit-feedback="1"`(footer 既有跳过通道,每次 submit 读到即跳并移除)。
2. `templates/base/footer.html`:submit 监听里对 `form.getAttribute('target')==='_blank'` 一律 return 跳过反馈——防御未来任何下载/新窗口表单踩同一坑(全站现存 target=_blank 表单仅 profile 这两处,行为从“卡死 bug”变“无反馈”=纯修复)。
- 经验:全站提交反馈的复位依赖导航,凡不触发本页导航的提交(target=_blank / 下载 / iframe)都必须显式跳过。
- 验证:go run ./dev/checktpl OK。
## 晚间(七):私聊面板 chat 专属功能聚合单卡
- 用户要求:`?tab=chat` 面板里「私聊块」(功能开关/收集窗口 feature-control-form)与「私聊设置」(update-chat-settings 消息上限)聚合为一张卡;全局屏蔽词为三面板共享、保持独立。
- 改动(templates/user/profile.html):
1. chat 面板改两段结构:私聊专属 = `<section class="tb-pcard chat-zone">` 内含 FeatureChat partial + `<hr>` + update-chat-settings 表单(原外层 `div.uk-margin` 移除);全局屏蔽词维持原 `hr` + partial 独立区。
2. CSS `.chat-zone`:内部 `.feat-card` 去边框透明(padding:0; border:0; background:transparent),避免卡中卡;`hr` margin 14px;内部 `legend`(admin.chat)从 uk-legend 大标题降级为 1.05rem 小节标题。
- 提问/投票面板未动(结构同前)。
- 验证:go run ./dev/checktpl OK。
## 晚间(八):功能控制卡按钮尺寸统一为常规按钮
- 用户要求:「保存该功能设置」按钮样式/大小改成与「更新私聊设置」一致;「重置计数」同调。
- 改动(templates/user/feature-control-form.html,三面板共享 partial):feat-actions 内两按钮去掉 `uk-button-small` —— 保存改 `uk-button uk-button-primary`、重置改 `uk-button uk-button-default`(常规尺寸,与全站其它表单主按钮一致)。提问/私聊/投票同步生效。
- 验证:go run ./dev/checktpl OK。