跨端: 预设档补遮罩(WebUI 的 --bg-dim 不分档位)+ 主题变化时重算"我们自己算的值";缓存键差异记入表
pi 读 WebUI 源码后发现两处两边不一致,都处理了。这一提交同时改 harmony 与 electron,故自报家门。
## 1 预设档遮罩:**补上**(选"与 WebUI 一致",因为那服务的是可读性)
pi 的证据:WebUI 的 `applyBackground()` **无条件**写 `--bg-dim`(默认 24),
`.app-backdrop::after` 是 `rgb(var(--bg-scrim) / var(--bg-dim))` —— **遮罩不区分档位**;
它的注释写着目的「背景越花,正文越需要一层遮罩才读得动」。
而鸿蒙当时只在 image 档压(`resolveBackground` 里那行注释还写着"preset 档不用"),
且我们已经让出了页面底 → 正文直接压在原色渐变上,**比 WebUI 更艳更亮、更不好读**。
现在两档用**同一个浓度**(同一个服务端字段),页面在预设分支的渐变之上加一层
系统遮罩色 × 浓度(浅色由系统洗白、深色压黑,不自己写 alpha)。
判据:旧断言"preset 档不压暗"**反过来**(留着理由),另加一条钉"两档同一浓度"+
"两处遮盖层都在"+"WebUI 确实无条件写 --bg-dim"(这条差异有据可查)。
变异:预设档不压 → 红 2 条;页面预设分支的遮盖层被删 → 红。
## 2 多账号缓存键:**鸿蒙是对的,不许退回**(pi 点名)
WebUI 的键是全局常量 `agentmail.background`,后果是切到服务端没有记录的账号时
`saved=false` 分支会把**上一个账号的外观** push 上去(新账号"继承"了外观,还写进了服务端)。
这条差异进 §7.12「有意差异」表,**明确写"鸿蒙是对的"**,
判据防的就是"将来有人为了两边一致把它改回去":取键函数的**正文**里必须拼账号 id
(按块取,不是看调用点出现过 `accountId` 就当数 —— "判结构要配对/解析"那条对我自己也适用),
且不许出现 WebUI 那个全局键。变异:`prefKey` 去掉账号 → 红 2 条。
## 3 "未做" → 按 pi 的三档口径改成**已知不一致**,并把系统侧的接法做掉
pi 指出这不是"没做":色板确实按主题算了,只是没接环境变化事件 ——
现象是运行期切系统深浅色时"系统语义色/材质立刻跟随、我们自己算的色板不重算"的**撕裂**。
他给的规则我记成了通用规则(会咬到 P5/P6):**系统自动跟随的东西不会顺带把
"我们自己计算/缓存的值"一起更新** —— 凡随主题变化的自算值都要挂在**同一个主题变化事件**上。
照做:`applicationContext.on('environment')` → `onConfigurationUpdated` 里
**只在 `colorMode` 真换向时**重算(`applyAppearance()`),页面销毁 `off` 退订。
状态 = **未验**(只有真机/模拟器能验:切一次系统深浅色看预设是否跟着换)。
SDK 锚点与两个编译错都记进 §7.17b:`EnvironmentCallback.onConfigurationUpdated(config: Configuration)`
(`Configuration` 从 `@kit.AbilityKit` 取,**不在** `common` 命名空间下)、
`Configuration.colorMode` 是**枚举 | undefined**(字段写成 `number` 直接编译失败)、
`on('environment')` 返回 **number 型 callbackId**。变异:不订阅 → 红。
## 4 文档
- §7.12 加两行:缓存键(含 WebUI 侧开项)、遮罩浓度默认值那两套(`24/8` vs `12/4`,
按 `clamp` 的 12/4 对齐,因为服务端缺字段时落地的是它)。
- §四 验收纪律改成**四档口径**:没做 / 未验 / 已知不一致(要写触发条件与现象)/
机制上确定不同(必须判),并把 pi 那条"自算值必须挂主题事件"的可复用规则写进去。
## 验证
`hvigorw assembleHap` BUILD SUCCESSFUL;`npm test` 退出码 0
(12 个判据文件全绿 + vitest 258/258;harmony-appearance 20 → 23 条)。
This commit is contained in:
@ -89,10 +89,18 @@ WebUI 侧踩过这个坑,见 `gateway/handler/permission.go` 的 Note 传递
|
||||
漏掉了"侧栏点了不翻页")。
|
||||
2. 判据不许只看截图:要量几何/对比度/命中区。
|
||||
3. 无法验证的要**如实标注**(例如"编译通过、视觉未验"),不能写成"已完成")。
|
||||
⚠️ 两条口径(这轮各踩过一次,pi 复核时点名):
|
||||
- **"未验"只能用于"步骤做过、结果没看"**;功能不存在必须写"**没做**"
|
||||
(把"没做"写成"没验"会让人以为只剩观感风险,实际那里什么都没有);
|
||||
- **"机制上确定不同"要判,不许记成"未验"**(深色档预设那次就是)。
|
||||
⚠️ **四档口径**(pi 2026-09-14 定,这轮每一条都踩过):
|
||||
- **没做** —— 功能不存在。不许写成"未验"(那会让人以为只剩观感风险,实际那里什么都没有);
|
||||
- **未验** —— 做过、没看结果(例如"编译通过、视觉未验");
|
||||
- **已知不一致** —— 做了,但**某条件下会露出破绽**:必须写清**触发条件与现象**
|
||||
(例:"运行期切系统深浅色时,系统语义色/材质立刻跟随,而我们自己算的预设色板不重算
|
||||
→ 那一刻一部分跟随、一部分不跟随")。这一档最容易被误写成"没做",
|
||||
而两者的风险读法完全不同;
|
||||
- **机制上确定不同** —— 可判的差异,**必须判**、不许记成"未验"(深色档预设那次就是)。
|
||||
|
||||
**可复用规则**(会咬到 P5/P6):**系统自动跟随的东西(语义色、材质)不会顺带把
|
||||
"我们自己算出来的值"一起更新** —— 凡是我们计算/缓存且随主题变化的值,
|
||||
都必须挂在**同一个主题变化事件**上重算,否则它迟早是那唯一一处不跟随的。
|
||||
4. **判据怎么写**:见 `client/electron/test/CRITERIA.md` —— 那份规范管**两个客户端**的判据
|
||||
(判结构与行为、不判字面与邻接;清单与 allow-list 的形状;变异要红在预期位置;
|
||||
"判据自己不会跑"那个家族的六种宿主)。**写在 electron 的测试目录下只是因为
|
||||
@ -508,6 +516,8 @@ deb 也不必从 targets 里摘。已写进 `client/electron/BUILD.md`(含排
|
||||
| 动效 | 自定义 transition/时长 | `animateTo` + 系统 `curves` | 动效曲线应跟随系统设置(含"减弱动效") |
|
||||
| 遮罩 | 自声明 `--bg-scrim` + `--bg-dim` 两段式 | 系统 `sys.color.ohos_id_color_mask_regular` | 遮罩要随主题换向(浅色洗白/深色压黑),这件事系统已经做了 |
|
||||
| **品牌色** | `--c-blue-600: 37 99 235` | `Theme.accent = '#2563EB'` | **不允许差异** —— 两个客户端是同一个产品 |
|
||||
| **本地外观缓存的键** | 全局常量 `agentmail.background` | **按账号**:`appearance.<accountId>` | **鸿蒙是对的,不许为"对齐"退回全局键** —— 全局键的后果是切到服务端没有记录的账号时,`saved=false` 分支会把**上一个账号的外观** push 上去(新账号"继承"了外观,而且写进了服务端)。pi 2026-09-14 确认这条记在 WebUI 侧为开项(换键,或至少在把继承来的值当"本地的"推给从未有记录的账号前停一下) |
|
||||
| **遮罩浓度的默认值** | 两套:store 的 `dim=24/blur=8` 与 `lib/appearance.ts` 的 `clamp(...,12,4)` | 12 / 4(只有一套) | 服务端**缺字段**时真正落地的是 `clamp` 的默认值,所以按 12/4 对齐;WebUI 那两套值迟早要统一(pi 记在他那边) |
|
||||
|
||||
**关于 `overlayColor` / `overlayAlpha` 消失**(pi 要求把删除理由记在这里,否则下一个人会当成漏改补回来):
|
||||
鸿蒙这边的模态走**系统弹窗**(`bindSheet` / 自绘 `Stack` 只做位置,遮罩本身用系统遮罩色),
|
||||
@ -696,6 +706,9 @@ pi 的原话:「WebUI 的背景有**预设渐变**,服务端存的是 preset
|
||||
**网格档**(CSS 的 `repeating-linear-gradient`)系统没有对应原语 → 用系统 `Canvas` 画线
|
||||
(线色/间隔照抄 CSS:gray-200 / 0.55 / 28),理由写在模块里;
|
||||
- 图片档:`Image(pixelMap)` + 系统遮罩色按服务端浓度压暗;
|
||||
预设档**同样压**(pi 2026-09-14 指出两边不一致:WebUI 的 `--bg-dim` **不区分档位**,
|
||||
它的注释写着目的「背景越花,正文越需要一层遮罩才读得动」——遮罩服务的是可读性;
|
||||
而这边已经让出页面底,不压的话正文直接压在原色渐变上,比 WebUI 更艳更亮);
|
||||
- `image` 档但图没取回来 → **什么都不画**(画一块空白会被当成"壁纸坏了")。
|
||||
|
||||
**判据**(`harmony-appearance` 11 → 17 条):预设 id/顺序/标签与 WebUI `PRESETS` 逐字一致;
|
||||
@ -797,9 +810,21 @@ pi 指出"邻接不是结构"这条已经在同一个仓库露头**三次**(
|
||||
- 判据:两套值与 `index.css` 的 `:root` / `.dark` 段**逐个相等**;每个预设的深浅两套
|
||||
**必须真的不同**(否则"两套"是抄了两遍);网格线色也要跟着换;`isDarkMode` 五种输入。
|
||||
|
||||
**已知边界(未做)**:用户在应用**运行期间**改系统深浅色,这边不会自动重算
|
||||
(要重进页面/重进应用)。系统侧的正确做法是订阅 `applicationContext.on('environment', …)`
|
||||
的配置变化回调 —— 记在这里,没做。
|
||||
**运行期切深浅色(原记"未做",现按 pi 的三档口径改)**:这**不是"没做"** ——
|
||||
色板确实按主题算了,只是当时没接环境变化事件,于是运行期切系统深浅色会出现
|
||||
"系统语义色/材质立刻跟随、我们自己算的色板不重算"的**撕裂**(这正是**已知不一致**那一档:
|
||||
触发条件 = 运行期切系统深浅色;现象 = 一部分跟随、一部分不跟随)。
|
||||
|
||||
现在按 pi 的规则接上了:`applicationContext.on('environment')` 的 `onConfigurationUpdated`
|
||||
里,**只在 `colorMode` 真的换向时**重算我们自己的那部分(`applyAppearance()`),
|
||||
页面销毁时 `off` 退订。**状态 = 未验**(这条只有真机/模拟器能验:切一次系统深浅色,
|
||||
看预设是否跟着换)。
|
||||
|
||||
SDK 锚点(免得后人凭记忆写):回调接口是 `@ohos.app.ability.EnvironmentCallback`
|
||||
的 `onConfigurationUpdated(config: Configuration): void` 与 `onMemoryLevel(level)`;
|
||||
`Configuration` 类型从 `@kit.AbilityKit` 取(不在 `common` 命名空间下)。
|
||||
踩过两个编译错:`Configuration.colorMode` 是**枚举 | undefined**,字段写成 `number` 直接报错;
|
||||
`ApplicationContext.on('environment')` 返回的是 **number 型 callbackId**(不是 void)。
|
||||
|
||||
### 7.17c 手写色清册升级成**跨文件按类扫**(pi 建议)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user