From 962df62801ec950abffe736e1215d9aee1273375 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Mon, 14 Sep 2026 14:48:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(harmony):=20P4b=20=E9=A2=84=E8=AE=BE?= =?UTF-8?q?=E6=A1=A3=E7=94=BB=E6=B3=95=20+=20=E5=A3=81=E7=BA=B8=E7=9C=9F?= =?UTF-8?q?=E7=9A=84=E6=B8=B2=E6=9F=93=E5=87=BA=E6=9D=A5=EF=BC=88=E5=B9=B6?= =?UTF-8?q?=E6=9B=B4=E6=AD=A3=E6=88=91=E4=B8=8A=E4=B8=80=E8=BD=AE"?= =?UTF-8?q?=E6=9C=AA=E9=AA=8C=E6=B8=B2=E6=9F=93"=E7=9A=84=E8=AF=B4?= =?UTF-8?q?=E6=B3=95=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pi 复核时问了一个比上传入口更基础的问题:WebUI 的背景有**预设渐变**, 鸿蒙拿到 preset 名画得出来吗?只支持 image/none 的话,"换账号后外观跟随" 对预设档就是**不成立**的(用户设了预设,在鸿蒙看到的是没有背景)—— 信息对等缺口。 查下来比他说的更糟:**P4 第一版没有任何东西去画背景** —— `AppearanceStore` 取回了 `PixelMap`、算好了快照,但没有组件渲染它(预设更是完全没实现)。 上一轮我在文档里写的是"壁纸在真机上的**渲染**效果未验",听着像"已经画出来了只是没上真机看"—— 那是**说得比证据强**。取回像素这件事是真的(提交信息没写错),但"渲染未验"把"没做"说成了"没验"。 已在 §7.16 更正,并把这条记进文档以免后来人当成回归。 ## 改了什么 - `model/Wallpaper.ts`(纯逻辑,判据直接跑):6 个预设(id/中文标签/归一化)、色板、 每个预设由哪些层叠出来、`resolveBackground()` 决定画什么(`image` 档但图没取回来 → 什么都不画)。 - `MainPage`:`WallpaperLayer` —— 预设用**系统原语** `radialGradient`/`linearGradient`; **网格档**(CSS 的 `repeating-linear-gradient`)系统没有对应原语 → 用系统 `Canvas` 画线 (线色/间隔照抄 CSS),理由写在模块注释里;图片档 `Image(pixelMap)` + 系统遮罩色按服务端浓度压暗。 - **页面底让出**(这条不做,"画出来了"就是假的):每个页面自己会刷一层**不透明**的系统页面底, 壁纸会被全盖住。WebUI 侧的原话是「页面底 → 完全透明,让出背景;不改 27 个组件的 class, 逐个加 class 必然漏(漏掉的那块就是一张不透明卡片浮在背景上)」。 现在 `bgActive` 从主界面 → 通信页 + 联系人页 → 三个 pane,五个页面底全部让出。 ## 判据(harmony-appearance 11 → 18 条) 预设 id/顺序/标签与 WebUI `PRESETS` 逐字一致;**预设色值与 CSS 调色板变量逐个对照**; 色板反向检查(登记了没用 → 红);透明用关键字而非 8 位色值;三档 resolve 行为; 页面真的画了(三种系统原语 + 图片 + 压暗 + 铺在内容之下);**页面底没有一处还在用不透明底** + 开关必须真的传到每个页面;模糊归属的互斥形式(壁纸层零模糊 / 导航条必须有系统材质)。 变异:预设少一档 → 红 2 条;preset 档不画东西 → 红;image 档图没取回来照样画 → 红; 色值写错两位 → 红;壁纸层加模糊 → 红;**五个页面里只漏一个没让出页面底 → 红**; 联系人页没收到开关 → 红。 ## 判据抓到的真 bug `--c-blue-200`(CSS:191 219 254 = `#BFDBFE`)我写成了 `#BFDCFE` —— 两位字母顺序反了。 "照 CSS 读出来比"才拦得住这类错。另外判据自己有两处切片毛病(用 `indexOf('build() {')` 两头夹会跨到别的成员上 / 断"注释里写了理由"却读了剥注释的源码),已改。 ## 另外两件 - pi 撤回了他"模糊只由壁纸层负责"那句(那是 WebUI 的架构结论),按他给的两条性质 (同一张底只糊一次 / 模糊该出现在背后是可变内容的层)写成互斥形式判据,记在 §7.18; 并写明 WebUI 的"壁纸模糊度(px)"与鸿蒙的"材质档次"**不是同一个物理量**(§7.18 末)。 - **重打包**:pi 的 WebUI 补丁(c9717da / 2e42aac)重建了 `dist`(14:30), 而安装包是 13:49 的 —— `packaging` 判据正确地判红。已按 BUILD.md 的写法重打 deb (`-c.electronDownload.isVerifyChecksum=false`;第一次不带这个参数时 electron-builder 卡在下载校验上超时,失败原因如实记在这里)。 ## 验证 / 未验 `hvigorw assembleHap` BUILD SUCCESSFUL;`npm test` 退出码 0(11 个判据文件全绿 + vitest 258/258)。 **未验**:预设渐变与图片壁纸在真机上的观感(尤其**深色模式**下预设的表现 —— 色板取的是 CSS 浅色档,深色档要不要另给一套,等真机看过再定); 卡片面(系统 `surface`,不透明)盖在壁纸上是否该半透明 —— 也留到真机看, 但它不影响"背景可见"这条(页面底已让出)。 **未做**:P4c 壁纸上传入口(pi 定:算 P4 范围、不阻塞别的阶段, 做时按 WebUI 三条约束:先压缩再上传 / 失败必须给原因 / 上传后仍以服务端为权威)。 --- client/electron/test/harmony-logic.test.mjs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/electron/test/harmony-logic.test.mjs b/client/electron/test/harmony-logic.test.mjs index ea7af22..2b3fae2 100644 --- a/client/electron/test/harmony-logic.test.mjs +++ b/client/electron/test/harmony-logic.test.mjs @@ -502,7 +502,9 @@ test('通信页把三栏真的接上了:内部页签 + 徽标 + 悬浮加号 + // 底部第一项的标签是「通信」而不是「收件箱」(信息架构变了,标签必须跟着变) const tabLabels = [...sendCode.matchAll(/TabBarBuilder\('([^']+)'/g)].map(m => m[1]); assert.deepEqual(tabLabels, ['通信', '联系人'], `底部应只剩两项且第一项是通信,实际:${tabLabels.join('、')}`); - assert.match(sendCode, /CommPage\(\)/, '第一项要渲染通信页'); + // 通信页现在还要收一个 `bgActive`(背景开着时让出页面底,否则壁纸全被盖住)—— + // 所以这里钉的是"带参数地渲染通信页",不是光有个名字 + assert.match(sendCode, /CommPage\(\{ bgActive: this\.bgActive \}\)/, '第一项要渲染通信页(并把背景开关传下去)'); // 内部页签:三栏由 COMM_TABS 驱动,点击切到 normalizeCommTab 的**同一个函数** assert.match(sendCode, /ForEach\(COMM_TABS, \(key: string\)/, '页签栏要按页签清单渲染'); @@ -510,8 +512,10 @@ test('通信页把三栏真的接上了:内部页签 + 徽标 + 悬浮加号 + assert.match(sendCode, /badgeText\(badgeCount\(key, this\.unreadCount, this\.pendingCount\)\)/, '徽标数字走同一份规则'); assert.match(sendCode, /this\.commTab = normalizeCommTab\(key\)/, '点击要过状态机的归一化,不能直接赋值'); // 三个 pane 都要真的存在(少一个就是空页签) - for (const pane of ['InboxTab()', 'SentTab()', 'PermissionTab()']) { - assert.ok(sendCode.includes(pane), `通信页要渲染 ${pane}`); + // 三个 pane 都要真的存在(少一个就是空页签),且都要收到背景开关 + for (const pane of ['InboxTab', 'SentTab', 'PermissionTab']) { + assert.ok(sendCode.includes(`${pane}({ bgActive: this.bgActive })`), + `通信页要渲染 ${pane}(并把背景开关传下去)`); } // 悬浮加号在通信页这一层(三个栏都要能新建),形状是圆形