修复 AGC 模板库筛选与卡片状态的表现缺陷
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / AI game creator shell Rust crates (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust smoke (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / AI game creator shell Rust crates (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust smoke (push) Has been cancelled
- 模板库筛选区改用共享筛选条与标签 chip:选中为实心品牌填充 + 反白文字,未选为浅底描边 - 未选中悬停不再借用品牌色(品牌色专属已选中),状态阶梯固定为静止 / 悬停 / 按下 / 选中 - 新增 getPlatformCategoryChipClassName 收敛筛选 chip 类名口径,模板库、资源画布、参考图弹窗与平台 Web 端共用 - PlatformSegmentedTabs 增加 accent 选中口径,与筛选 chip 共用 --platform-chip-* 语义色 - 修复卡片文字区按 grid auto 行排版导致的标题 / 简介 / 标签被裁:行高契约拆为分项常量,文字区固定 174 - 修复忙状态下动作行塞入第三个元素导致的按钮文案换行顶出卡片:忙状态写在触发它的按钮上 - 修复经典滚动条占宽导致的卡片区横向滚动条:按竖滚动条预留列宽后再算列宽行高 - 焦点环由 15% 透明度改为实心色并用 outline 绘制,选中项聚焦不再被状态投影盖掉 - 封面加载失败改为隐藏图片留中性底色,不再出现浏览器裂图图标 - 补充状态对比度、行高契约、滚动条预留、封面兜底与忙状态文案的回归测试 - 同步技术方案、踩坑记录与决策记录的口径
This commit is contained in:
@@ -1,5 +1,15 @@
|
||||
# 决策记录
|
||||
|
||||
## 2026-09-22 筛选控件选中态:类名收敛到 helper,视觉收敛到「实心填充 + 反白文字」
|
||||
|
||||
- 背景:`platform-category-chip` 的类名字符串此前在三个宿主各抄一份(共享筛选条 `PlatformResourceFilterBar`、资源画布筛选浮层 `ResourceFilterPanel`、模板库筛选区),「选中的筛选胶囊长什么样」随时会各自漂移;更严重的是选中态本身只用了 `--platform-cool-*` 这组低透明度暖色,实测选中/未选底色对比只有 1.09:1,用户反馈「选中和没选中的颜色看不出差别」。
|
||||
- 决策:① 类名口径收敛到 `packages/shared/src/components/platformCategoryChipModel.ts` 的 `getPlatformCategoryChipClassName(active)`(从 `@genarrative/shared/components` 导出),三处宿主统一改调它;② 选中态改为**实心品牌填充 + 反白文字**,语义色收在新的 `--platform-chip-idle-fill` / `--platform-chip-active-{fill,border,text,shadow}`(浅色皮肤深暖填充、深色皮肤亮靛蓝填充 + 深文字),`PlatformSegmentedTabs` 新增 `tone="accent"` 与 chip 共用这套色;③ `src/index.css`(平台 Web/平台 H5)里那份重复的 `--active` 规则同步改口径,避免覆盖共享样式把 Web 端打回旧样子。
|
||||
- 状态阶梯(同一份口径,三个状态不许互相冒充):静止 = 浅底 + 中性描边 + 常规文字;悬停 = 中性加描边 + 极淡暖底 + 深色文字(**品牌色只能属于「已选中」**,悬停用品牌色会让未选中的 chip 看起来已选中);按下 = 再压一层;选中 = 实心填充 + 反白文字,是唯一的强状态。运行时分段的 `accent` 未选中悬停同理(淡暖底 + 深文字)。
|
||||
- 焦点态同批收口:`--platform-input-focus-ring` 从 15% 透明度改成实心色(合成后 1.17:1 的环等于没有),筛选 chip / 分段项 / 排序按钮的焦点提示改用 `outline: 2px solid <ring>; outline-offset: 2px`——不再用 `box-shadow` 画环,避免被选中态自己的投影盖掉。
|
||||
- 原因:二元状态必须靠**填充/明度**表达而不是色相微调;颜色只允许在 `packages/shared/src/theme.css` 的语义变量里出现,组件不再自己写颜色字面量。
|
||||
- 影响范围:`packages/shared/src/theme.css`、`packages/shared/src/components/{platformCategoryChipModel.ts,styles.css,PlatformSegmentedTabs.tsx,PlatformResourceFilterBar.tsx,index.ts}`、`src/index.css`、`apps/ai-game-creator-shell/src/view/{project-development/ResourceFilterPanel.tsx,template-library/index.tsx}`。
|
||||
- 验证方式:`apps/ai-game-creator-shell/tests/workbenchThemeContrast.test.ts` 按 WCAG 公式断言两套皮肤都满足「选中文字 ≥ 4.5:1(渐变两端)」且「选中填充 vs 未选底色 ≥ 3:1」;`platformCategoryChipModel.test.ts` 钉住选中类名分支;`PlatformResourceFilterBar.test.tsx` / `resourceFilterPanel.test.tsx` / `src/index.test.ts` 覆盖各宿主。真机 AGC 客户端截图实测两态填充对比 6.0:1、选中文字 4.8–6.0:1。
|
||||
|
||||
## 2026-09-22 退役 AGC 项目对话斜杠命令与终端 swarm chat 入口
|
||||
|
||||
- 背景:AGC 项目对话曾把大量能力挂在「聊天输入 `/<cmd>`」上(`/history`、`/read`、`/help`、`/status`、`/trace`、`/export`、`/preview`、`/remember`、`/brief` 等),无 GUI 的终端 swarm chat 入口 `--swarm-chat` 又自带一套控制命令(`/help`、`/agents`、`/status`、`/history`、`/compact`、`/resume`、`/goal`、`/quit`)。两套入口都没有现役调用方,撤回成本却持续存在:命令字面量散落在前端命令分支、润色绕过、摘要模块、`swarm_cli` 终端输入解析、构建期门禁条目和文档承诺里,任何新对话形态都要额外维护这套死词汇表。
|
||||
|
||||
@@ -5875,3 +5875,43 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
- CI 产物清理:Gitea 1.26.4 的仓库 REST 仅列出 finalized/expired V4 artifact,内置到期清理不回收上传中断的 tmp-upload 分块。缓存上传块须带专属标识,宿主只清理目标仓库已结束且超过 7 天的 master run 中同样过期的自有普通文件,未知文件/符号链接保护,不改数据库或全局 prune。Artifact.workflow_run 仅含 ID/SHA,判断过期产物所属事件和状态须再读 run API,不能当作完整 run 使用。
|
||||
- 自动切换:Gitea 1.26.4 的 disabled 检查与 FetchTask 事务不原子,Runner 客户端超时不能证明服务端回滚,容器暂时为空也不能证明没有已领取任务。网关必须解析实际 Connect Protobuf/gzip,转发 FetchTask 结果前持久化任务 ID,仅在最终日志及执行清理后的最终 UpdateTask 确认后清账;取消响应不能提前释放。暂停新领取、在途为零、账本为零且内层活动容器为空才可切换,无需全局 Runner admin API。未知协议/响应或崩溃遗留标记停止切换;旧网关缺 active_tasks 不能默认零。首次接入与账本升级须空闲窗口。.runner 的 mtime 不证明地址已加载,应核验真实 FetchTask 来源及本次容器启动时间。
|
||||
- 扩展:预热所有 Rust 测试组时保留各自 cwd、profile、features 和锁策略;同一临时 target 的 Cargo fresh 不代表不同 cwd 都已生成缓存键,AGC 提示词契约、分片和 smoke 切换入口前清理预热 target。不要把 workspace 与 spacetime-module 合并成一次编译;Native shell release step 清空双 wrapper,避免将测试缓存扩展成发布缓存。当前 sccache 0.18.0 的 READ_ONLY 在 miss 后仍打包产物并产生 cache write error,不适合用来承诺“未命中无开销”。
|
||||
|
||||
## 2026-09-22 卡片文字用 grid 的 auto 行排版,会被按「一行」裁掉
|
||||
|
||||
- **现象**:AGC 模板库卡片标题看着被切掉、简介只剩一行、标签行缺半截;`TEMPLATE_CARD_TEXT_HEIGHT` 与真实内容相差约 24px,但卡片底部看起来仍「刚好贴住」,很容易误判成没问题。
|
||||
- **原因**:文字区原本是 `grid min-h-0 content-start gap-2 overflow-hidden`,行高由 auto 轨道决定。auto 轨道的 max-content 高度对可换行文本等于**一行**的高度:标题拿到 14px(实际需要 20)、简介 14px(两行需要 32)、标签 14px(需要 19),只有最后一个子项(按钮行)拿到完整高度。真实浏览器实测 `clientHeight`/`scrollHeight` 为 14/20、14/32、14/19。jsdom 不计算布局,单测全绿也照不出来。
|
||||
- **处理(现行口径)**:文字区改 `flex flex-col`,每行写死高度并加 `shrink-0`(标题 `h-5`、元信息 `h-4`、简介 `h-8`、标签 `h-5.5`、按钮行 `h-7`,内边距 `p-3`、行距 `gap-2`),行高契约按同一组分项常量(`TEMPLATE_CARD_*_HEIGHT`)算出文字区 174。卡片行高、`TemplateCard` 类名与这组常量必须同时改。
|
||||
- **写死高度的连带约束**:动作行一旦固定成 `h-7`,那它就**只能放两个按钮**。再往里塞第三段文本(当时的「正在下载模板」)时,最小卡宽 250px 下按钮文案会被挤成两行并顶出卡片(用户看到「使用模 板 / 更 新」叠成一团)。现行口径是忙状态写在触发它的按钮上(`下载中` / `创建中`,按钮就地换图标+文案),按钮一律 `whitespace-nowrap shrink-0`,动作行 `overflow-hidden` 兜底。
|
||||
- **验证**:真实浏览器逐行核对 `clientHeight === scrollHeight`(20/20、16/16、32/32、22/22、28/28);单测钉住分项常量与卡片各行类名(`templateLibraryGrid.test.ts`、`templateLibraryView.test.tsx`)。
|
||||
- **关联**:`apps/ai-game-creator-shell/src/features/template-library/templateLibraryGrid.ts`、`apps/ai-game-creator-shell/src/view/template-library/TemplateCard.tsx`、`docs/technical/【技术方案】AGC模板库与模板建项-2026-09-17.md`(卡片列表虚拟滚动)。
|
||||
|
||||
## 2026-09-22 筛选 chip 的选中态只靠低透明度色相微调,用户看不出选中了什么
|
||||
|
||||
- **现象**:模板库筛选 chip 选中与未选中的底色实测只差 **1.09:1**(选中 `rgba(238,208,183,0.26)` 合成后 ≈ `#f9eee5`,未选 ≈ `#fdf9f5`),选中文字 `#b76038` 在自己底色上只有 3.88:1(低于 AA);运行时分段选中的白底 pill 也和米色页面几乎同色。反馈原话是「选中和没选中的颜色都看不出有差别」。
|
||||
- **原因**:选中态走的是 `--platform-cool-bg/border/text`,这三个变量在浅色皮肤里是同一个暖色调的低透明度版本(bg 26%、border 24% alpha),只够做「淡淡的染色」,不足以表达二元状态;深色皮肤里 `rgba(8,145,178,0.14)` 同样太弱,而深色皮肤里「更深的填充」反而更不可分辨。
|
||||
- **处理(现行口径)**:筛选控件的二元状态统一为**未选 = 浅底描边 + 常规文字,选中 = 实心品牌填充 + 反白文字**(`.platform-category-chip--active` 与 `PlatformSegmentedTabs` 的 `tone="accent"` 共用 `--platform-chip-*` 语义色;深色皮肤用「亮填充 + 深文字」,因为深色下只有更亮才算选中)。改色只改 `packages/shared/src/theme.css` 的语义变量,不要再往组件里写颜色。
|
||||
- **同一坑的第二种表现**:把「悬停」也刷成品牌色(暖色描边 + 暖色文字)后,未选中的 chip 一悬停就像已选中——品牌色一旦被悬停借走,「已选中」这个强状态就没有颜色可用了。现行阶梯是「静止 = 浅底中性描边 / 悬停 = 中性加描边 + 极淡暖底 + 深色文字 / 按下 = 再压一层 / 选中 = 实心填充 + 反白文字」。客户端实测:选中填充 `#b0522e` vs 悬停底 `#f9efe4` = 4.52:1,选中 vs 静止 = 4.97:1,悬停 vs 静止 = 1.10:1(只是提示,不抢选中)。
|
||||
- **验证**:`apps/ai-game-creator-shell/tests/workbenchThemeContrast.test.ts` 按 WCAG 公式断言两套皮肤都满足「选中标签文字 ≥ 4.5:1(渐变两端都要过)」且「选中填充 vs 未选底色 ≥ 3:1」;真实浏览器实测改后两态对比 5.6–6.1:1、选中文字 5.5–6.0:1(改前分别是 1.09:1 与 3.88:1)。
|
||||
- **关联**:`packages/shared/src/theme.css`、`packages/shared/src/components/styles.css`、`packages/shared/src/components/PlatformSegmentedTabs.tsx`、`apps/ai-game-creator-shell/tests/workbenchThemeContrast.test.ts`。
|
||||
|
||||
## 2026-09-22 虚拟网格按「包裹层宽度」算列宽,经典滚动条一出现就多出横向滚动条
|
||||
|
||||
- **现象**:AGC 模板库卡片区底部在客户端里凭空多出一条横向滚动条(外层并没有横向溢出内容);窗口放到没有竖向滚动的尺寸时又不出现。
|
||||
- **原因**:react-window 的内层宽度 = `列数 × 列宽`,而列宽是按**包裹层**宽度算的(`floor(容器宽 / 列数)`)。经典(非 overlay)滚动条会吃掉 grid 外层的 `clientWidth`:Windows / WebView2 上竖向滚动条约 17px,于是内层 1184 比外层可用宽 1167 宽出正好一个滚动条,react-window 就按「横向也要滚」处理。**Playwright 自带的 Chromium 用的是 overlay 滚动条(占宽 0),本地量 `offsetWidth - clientWidth` 是 0,完全复现不出来** —— 这类问题只能在 WebView2 客户端里看,或者按算术推。
|
||||
- **处理(现行口径)**:`computeTemplateGridLayoutWithScrollbar`(`templateLibraryGrid.ts`)在「内容确实会竖向溢出」时先把滚动条宽度从容器宽度里扣掉再算列宽/行高,不竖向溢出时不预留(否则右侧会留一条无意义的白边);滚动条宽度由 `measureVerticalScrollbarWidth()` 量一次(overlay 平台为 0,逻辑自动退化)。同类虚拟列表再出现「莫名其妙的横向滚动条」,先查这里的算术,不要靠 `overflow-x: hidden` 掩盖(那会把最后一列切掉)。
|
||||
- **验证**:`templateLibraryGrid.test.ts` 断言「竖向溢出时 `列数 × 列宽 ≤ 容器宽 - 滚动条`」「不溢出或 overlay 时与不预留完全一致」;真机客户端截图确认横向滚动条消失、右侧只剩竖向滚动条。
|
||||
- **关联**:`apps/ai-game-creator-shell/src/features/template-library/templateLibraryGrid.ts`、`apps/ai-game-creator-shell/src/view/template-library/index.tsx`。
|
||||
|
||||
## 2026-09-22 「15% 透明度的焦点环」等于没有焦点提示;选中态自己的投影还会把焦点环顶掉
|
||||
|
||||
- **现象**:键盘 Tab 走到筛选 chip、开关、卡片按钮上时,屏幕上完全看不出焦点在哪;自动化里更隐蔽——`box-shadow` 计算值非空(一串 `rgba(0,0,0,0) 0 0 0 0` 的 Tailwind ring 占位),只查「有没有 shadow」会全部判过。
|
||||
- **原因**:两个叠加的问题。① `--platform-input-focus-ring` 是 `rgba(204,117,76,0.15)`,合成到页面底色后对底色只有 **1.17:1**,远低于 WCAG 非文本对比要求的 3:1;② 焦点环用 `box-shadow` 画,而**选中态自己也有 `box-shadow`**(实心 chip 的投影),选中的 chip / 分段项聚焦时环被状态投影盖掉,等于没有提示。
|
||||
- **处理(现行口径)**:`--platform-input-focus-ring` 改成实心色(浅色 `#b6623f`,对页面 4.3:1;深色 `#9fb0ff`,对深色底 6.5:1);筛选 chip / 分段项 / 排序按钮的焦点环改用 `outline: 2px solid var(--platform-input-focus-ring); outline-offset: 2px`——`outline` 不参与 `box-shadow` 层叠,不会被选中态投影顶掉,也不撑开布局。
|
||||
- **验证**:`tests/workbenchThemeContrast.test.ts` 断言焦点环对两套皮肤的页面底色 ≥ 3:1;真实浏览器里对页面上**全部 175 个可聚焦控件**做 blur→focus 前后比对,无一例外都能看到焦点变化(改前有 8 个控件聚焦前后完全一致)。查焦点态时必须比较「聚焦前后的计算样式差异」,不能只看属性是否非空。
|
||||
- **关联**:`packages/shared/src/theme.css`、`packages/shared/src/components/styles.css`、`apps/ai-game-creator-shell/tests/workbenchThemeContrast.test.ts`。
|
||||
|
||||
## 2026-09-22 封面图加载失败会画出浏览器的「裂图」图标
|
||||
|
||||
- **现象**:模板清单里的封面 URL 失效(或离线)时,卡片封面上出现浏览器的破碎图片图标,比没有封面更难看。
|
||||
- **处理**:`TemplateCard` 的 `img` 加 `onError` 直接把自身 `visibility` 设为 `hidden`(不进 state,卡片是 memo 的纯展示组件),留下封面容器本身的中性底色;单测用 `fireEvent.error(cover)` 钉住。
|
||||
- **关联**:`apps/ai-game-creator-shell/src/view/template-library/TemplateCard.tsx`、`apps/ai-game-creator-shell/tests/templateLibraryView.test.tsx`。
|
||||
|
||||
Reference in New Issue
Block a user