fix(harmony): 图标按 px→vp 正确缩放 + 底栏四入口 + 卡片 10vp 缩进
图标过小的根因(实图硬证):`Path.commands` 的坐标按 **px** 解释,不是 vp。
- `Shape.viewPort` 只裁剪不缩放(官方样例"缩放成立"是因为它用 Rect/Circle
自带 vp 宽高,不是裸 Path.commands);
- 改动前的 `Path.scale({iconSize/24})` 对 iconSize=24 等于 1.0,同样没缩放。
症状:FAB 内 compose 只画 24px(应 24vp=84px),且偏在盒子左上角。
修法:`scale({vp2px(iconSize)/24})` 把 24 单位路径放大到 iconSize vp;
`scale` 会连带放大描边,故 `strokeWidth = strokeWeight / vp2px(1)` 抵消,
否则 1.8vp 描边会变成 ~7.3vp 的"实心块"(实图已验证)。
用 `this.getUIContext().vp2px()` 而非全局 `vp2px`——后者已废弃,
`harmony-system-api` 判据对全局调用默认判红。
验收(模拟器实图,密度 3.489):
- FAB 内 compose 图标 84px = 24vp ✓(原 24px)
- 底栏图标描边 7-8px ≈ 1.8/24×28vp=7.3px ✓(原为实心块)
- 四个图标均为清晰描边,与 WebUI icons.tsx 同几何
底栏四入口:新增"我的"(person → pages/SettingsPage),对齐 WebUI
通信/日历/联系人/我的;NAV_CONTENT_ITEMS 保持宽屏侧栏三项,
避免宽屏出现重复 person 图标。
卡片缩进:`width('100%') + margin({left:10,right:10})` 在 ArkUI 里不会
缩到 90%——margin 加在宽度外面,卡片顶出父容器(实测左缘只留 ~1px,
列表卡才有正确 10vp)。改为外层容器加 padding。验收:页头卡与邮件卡
左缘同为 x=35(10.0vp)、右缘 x=1219。
推送:reportToken 先申请通知权限再取 token(部分设备权限未开时
getToken 返回空 / 报 1600004),并补两条文件形状判据钉住
client_id 配置与调用顺序。
测试:198 passed / 0 failed。
This commit is contained in:
@ -161,7 +161,13 @@ test('★ 界面不再把"服务端未读数"当成"总封数"显示', () => {
|
||||
!/共 ' \+ this\.total \+ ' 封/.test(pageCode),
|
||||
'页面里还有「共 N 封」—— 服务端 total 是未读数,不是总封数'
|
||||
);
|
||||
assert.match(pageCode, /已加载 ' \+ this\.loaded \+ ' 封/, '应如实说"已加载了多少封"');
|
||||
/*
|
||||
* 页头文案已按 WebUI 的列表头重写为「N 组 · N 封」(parity 那一轮),
|
||||
* 不再是「已加载 N 封」—— 但这条判据的本意没变:显示的必须是**本地数到的东西**
|
||||
* (groups / loaded),不能是服务端那个未读 total。
|
||||
*/
|
||||
assert.match(pageCode, /this\.loaded \+ ' 封'/, '应如实说"本地取到多少封"(而不是服务端 total)');
|
||||
assert.match(pageCode, /this\.groups\.length \+ ' 组/, '列表头要报告本地分组数(WebUI 的「N 组 · N 封」形状)');
|
||||
});
|
||||
|
||||
// ───────────────────────── 预算(与 WebUI BudgetChip 同判据) ─────────────────────────
|
||||
@ -240,7 +246,8 @@ test('底部是 通信 / 日历 / 联系人 三个平级页签,「会话」不
|
||||
const labels = [...navSource.matchAll(/label:\s*'([^']+)'/g)].map(m => m[1]);
|
||||
// 2026-09-14:日历页(P6 第 1 步)落地后入口上架 ⇒ 三项。撤掉「会话」这条判断本身没变:
|
||||
// 它不是第三个地方,而是"同一批数据的另一种看法"(收件箱折叠 + 联系人卡片视图)。
|
||||
assert.deepEqual(labels, ['通信', '日历', '联系人'], `平级项应为 通信/日历/联系人,实际:${labels.join('、')}`);
|
||||
// 2026-09-17:与 WebUI NarrowNav 对齐 ⇒ 四项(前三内容窗格 + 外壳入口「我的」)。
|
||||
assert.deepEqual(labels, ['通信', '日历', '联系人', '我的'], `平级项应为 通信/日历/联系人/我的,实际:${labels.join('、')}`);
|
||||
assert.ok(!/struct\s+SessionsTab/.test(pageCode), 'SessionsTab 已经撤了,不该再留在页面里');
|
||||
assert.ok(!/sessions\(\)/.test(pageCode), '撤了入口就不该再拉 /me/sessions(否则是没人看的请求)');
|
||||
});
|
||||
@ -515,7 +522,8 @@ test('通信页把三栏真的接上了:内部页签 + 徽标 + 悬浮加号 +
|
||||
const navSource2 = code(join(HARMONY_ETS, 'model/NavItems.ts'));
|
||||
const tabLabels = [...navSource2.matchAll(/label:\s*'([^']+)'/g)].map(m => m[1]);
|
||||
// 2026-09-14:日历页(P6 第 1 步)做完后入口上架 —— 三项且顺序固定(通信/日历/联系人)
|
||||
assert.deepEqual(tabLabels, ['通信', '日历', '联系人'], `底部应为通信/日历/联系人三项,实际:${tabLabels.join('、')}`);
|
||||
// 2026-09-17:对齐 WebUI 四入口 —— 前三内容窗格不变,第 4 项「我的」是外壳入口(见 NavItem.route)
|
||||
assert.deepEqual(tabLabels, ['通信', '日历', '联系人', '我的'], `底部应为通信/日历/联系人/我的四项,实际:${tabLabels.join('、')}`);
|
||||
// 通信页现在还要收一个 `bgActive`(背景开着时让出页面底,否则壁纸全被盖住)——
|
||||
// 所以这里钉的是"带参数地渲染通信页",不是光有个名字
|
||||
assert.match(sendCode, /CommPage\(\{ bgActive: this\.bgActive \}\)/, '第一项要渲染通信页(并把背景开关传下去)');
|
||||
@ -525,16 +533,17 @@ test('通信页把三栏真的接上了:内部页签 + 徽标 + 悬浮加号 +
|
||||
assert.match(sendCode, /commTabLabel\(key\)/, '页签文字走同一份标签');
|
||||
assert.match(sendCode, /badgeText\(badgeCount\(key, this\.unreadCount, this\.pendingCount\)\)/, '徽标数字走同一份规则');
|
||||
assert.match(sendCode, /this\.commTab = normalizeCommTab\(key\)/, '点击要过状态机的归一化,不能直接赋值');
|
||||
// 三个 pane 都要真的存在(少一个就是空页签)
|
||||
// 三个 pane 都要真的存在(少一个就是空页签),且都要收到背景开关
|
||||
for (const pane of ['InboxTab', 'SentTab', 'PermissionTab']) {
|
||||
assert.ok(sendCode.includes(`${pane}({ bgActive: this.bgActive })`),
|
||||
`通信页要渲染 ${pane}(并把背景开关传下去)`);
|
||||
const at = sendCode.indexOf(`${pane}({`);
|
||||
assert.ok(at >= 0, `通信页要渲染 ${pane}`);
|
||||
const call = sendCode.slice(at, sendCode.indexOf('})', at) + 2);
|
||||
assert.match(call, /bgActive:\s*this\.bgActive/, `通信页要把 bgActive 传给 ${pane}`);
|
||||
}
|
||||
|
||||
// 悬浮加号在通信页这一层(三个栏都要能新建),形状是圆形
|
||||
// 悬浮加号在通信页这一层(三个栏都要能新建),形状是圆形 + compose 图标(与 WebUI 同几何)
|
||||
const commPage = sendCode.slice(sendCode.indexOf('struct CommPage'), sendCode.indexOf('struct ContactsTab'));
|
||||
assert.match(commPage, /Text\('\+'\)[\s\S]{0,220}?borderRadius\(28\)/, '悬浮加号要是圆形');
|
||||
assert.match(commPage, /AmIcon\(\{[\s\S]{0,80}?iconName: 'compose'[^}]*}\)[\s\S]{0,220}?borderRadius\(28\)/, '悬浮加号要是圆形且用 compose 图标(不是 Text \'+\')');
|
||||
assert.match(commPage, /this\.openCompose\(\)/, '加号要真的能进写信页');
|
||||
|
||||
// 收件箱那一栏必须**先分家再折叠**(否则权限邮件会混进收件箱,正是这条要防的)
|
||||
|
||||
Reference in New Issue
Block a user