Commit Graph

7 Commits

Author SHA1 Message Date
cac026e9e2 跨端: 上下黑边真的消了 —— 全屏 + 避让是"同一套东西的两半",上次只删了一半
用户第三次报同一条:「你再看看页面底部,那么大的黑色,你看从头到尾都没
修好,你能不能好好看看我给你的示例工程怎么处理上下黑边的」。

## 根因:上一次把"两半"当成了"一件事",删掉一半就以为修好了

`6861934` 的注释白纸黑字写着「★ **刻意不用** `setWindowLayoutFullScreen(true)`」,
理由是「实测过:它确实也消掉黑带,但会连状态栏区域一起吃进布局,于是页签栏
被时钟/电量盖住(截图硬证「07:43」与「收件箱」重叠)」。

那次实测**是真的**,结论**下错了**:被盖住不是"不该全屏",而是
**只做了全屏、没做避让**。示例工程里这两件事本来就是**同一套东西的两半**:

    common/.../util/WindowUtil.ets        → setWindowLayoutFullScreen(true)
                                          + getWindowAvoidArea(TYPE_SYSTEM /
                                            TYPE_NAVIGATION_INDICATOR)
    features/mine/.../view/MineView.ets:251 → .margin({ top: statusBarHeight + …,
                                                        bottom: naviIndicatorHeight })

只做前半 ⇒ 内容跑到状态栏底下没人让(那次退回的原因);
只做后半 ⇒ 黑边照旧(这三次报修的原因)。退回的代价是**黑边留了三天**。

## 实测(模拟器 1256x2760,四页一致)

    修前:顶部纯黑 136px、底部纯黑 60px + 手势条 20px
    修后:四页**纯黑段均为 0**;y=0..135 是壁纸(时钟浮在上面,正是示例工程的效果)
          y=2662+ 壁纸铺到底、底栏浮在手势区之上

## 改了什么

- `entryability/EntryAbility.ets`:拆出 `setupFullScreenWindow()`,
  在 `loadContent` **回调里**调(与示例工程同一位置 —— `px2vp` 要用 `getUIContext()`,
  那要有已加载内容才拿得到)。全屏 + 读两个避让区 + 订 `avoidAreaChange`。
  `setWindowSystemBarEnable(['status'])` 保留(状态栏要看得见),但**不再靠它**消黑边。
- `model/WindowInsets.ts`(新):纯逻辑 `insetsFromAvoidArea()`,不 import SDK ——
  判据才能在 node 里直接喂样本验换算。形参叫 `toVp` 而**不是** `px2vp`:
  后者是 SDK 已废弃的全局函数名,`harmony-system-api` 按名字扫,同名形参会误报。
- `pages/MainPage.ets`:`@StorageLink(KEY_WINDOW_INSETS)` 订阅;状态栏高度当
  **内容层**的 `padding-top`(**不是**根 Stack —— 壁纸必须铺到屏幕四边,根上加
  padding 会把壁纸一起缩进去,黑边只是换个地方出现);底栏与内容末尾让开手势条。
  reserve 收成**一个** `recomputeNavReserve()`,宽度变化与避让变化两个触发点共用
  (转屏只改避让不改宽度,各写一份迟早漏一个)。

## 判据:`test/harmony-window.test.mjs`(8 条)

钉的是"两半必须同时存在"——**只钉一半的话,"退回某一半"照样能全绿通过**,
而那次退回恰恰就是删了一半。纯逻辑 3 条(换算/取不到就是 0 不猜/键名是常量)
+ 接线 4 条(全屏在、避让在、布局真消费了值、纯逻辑模块不许 import SDK)
+ 设备行为 1 条(全屏没把应用搞成白屏)。

**变异自检两个方向都跑过**(这是本轮最该记的一步):
- 删掉 `setWindowLayoutFullScreen`(重演 6861934)⇒ 2 条红 ✓
- 删掉 `getWindowAvoidArea`(只全屏不让位)⇒ 1 条红 ✓

★ 第一版判据**锚错了**:正则直接扫全文,而注释里正好有 `setWindowLayoutFullScreen(true)`
  这个串 —— 把真正的调用删掉后判据**仍然全绿**。锚落在"代码对自己的描述"上了。
  加 `stripped()` 剥注释后,变异才咬得住。这条与仓里那条"判据的锚不能落在
  被守对象的自述上"是同一件事,这次是它的实例。

## 顺带修的两条既有判据(不是放宽,是它们把"当时的字符串"当成了"要守的坑")

- `harmony-nav` ④:留白断言写死了 `bottom: NAV_BAR_BOTTOM` 那个字面串。
  它本来要守的是"留白靠 padding 不靠 margin"(margin 在 ArkUI 里加在宽度外面,
  100% + margin 会顶出父容器)—— 那是另一件事。改成剥注释后验三段在不在、
  离底是否**从** `NAV_BAR_BOTTOM` **起**。变异(padding→margin)仍判红 ✓
- `harmony-widescreen` ④:同上,写死了 `? 0 : NAV_CONTENT_RESERVE`。
  改成"宽屏必为 0、窄屏含 NAV_CONTENT_RESERVE(可再加避让)"。

两处都是"加一个正当的避让"与"真犯那个错"会红得一模一样 —— 那就不再是守坑,
是守字符串。

另:`align-refs` / `build-stamp` / `packaging` 三条 broken 是前端 `99a2d7a`
(另一个人改的 `CalendarView.tsx`)带来的,与本轮无关,留给他。
2026-09-18 09:47:22 +08:00
2e53871a22 fix(harmony): 底栏真正浮起 + 内容穿过 + 加回文字标签
用户(2026-09-17):「底栏不是玻璃质感,滑动内容无法穿过底栏」,
随后「还是在导航栏加上文字吧,没有文字还是不好看」。

── ① 底栏没浮起:`width('100%') + margin` 在 ArkUI 里不缩宽 ──
NavBar 原来是 `Row().width('100%').margin({left:16,right:16,bottom:12})`。
ArkUI 的 margin 加在宽度**外面**:100% 再配左右 margin 不会缩到
「100% − margin」,而是整个顶出父容器、两侧被裁。
实测底栏左缘 x=0、右缘贴满 1256(应各留 16vp=56px)⇒ 看起来是贴边通栏,
不是浮在壁纸上的胶囊。这与收件箱头卡片修过的是同一个坑。
改法:外层 Column 带 padding(与 WebUI `.narrow-nav` 的 margin 同一几何)。
实测修复后左缘 x=56 = **16.1vp**(期望 16)。

── ② 内容穿不过去:让位加错了层 ──
原来把 `NAV_CONTENT_RESERVE` 加在**窗格的 `padding({bottom})`** 上。
那不只"让最后一行滚得出来",还**缩短了窗格本身** ⇒ 内容永远到不了条底下
⇒ 玻璃条背后只剩一张已经被壁纸层模糊过的壁纸 ⇒ 系统材质无东西可糊
⇒ 看起来就是一块普通浅色面板。**这就是"不是玻璃质感"的真正原因**。
改法:窗格满高(内容滑得到条底下,真正穿过),让位改到各滚动容器的
**内容末尾** `contentEndOffset(this.navReserve)`(5 个 List + 日历日程),
与 WebUI 同构(`.narrow-shell` 是 flex-col,列表满高、`.narrow-nav` 叠在上面)。
实测:条内高频细节 0.21 vs 条外正文 6.04 ⇒ **28.8×** 衰减,模糊确实生效。
连带修:FAB / 回复球原来靠窗格 padding 躲开条,现在自己按 navReserve 抬
(否则压在条上),实测 FAB 底距条顶 24.4vp。

── ③ 加回文字:并纠正一处**事实错误** ──
代码注释里写着「WebUI 的底部导航是**纯图标**」,并据此去掉了文字。
那句是**错的**:`NarrowNav.tsx:83-86` 每个导航项是
`flex flex-col items-center justify-center gap-0.5`,里面先 `<Icon />`
再 `<span className="text-3xs leading-none">{short}</span>`
—— WebUI **一直有文字**(通信 / 日历 / 联系人 / 我的)。
那条判据把一个假事实固化成了规则,还反过来挡住了正确做法。
现在按真实契约钉:图标(24vp,与 WebUI 24×24 同几何)+ 文字,
两者过**同一个**选中三元式(只换颜色,不加背景/指示条)。

判据(全部含变异自检):
· ⑤ 重写:两处选中三元式(图标+文字各一)、必须有 Text(item.label)、
  图标 24vp;变异自检覆盖"缺文字 / 文字不换色 / 图标不上色"。
· ④ 改:留白走外层 padding(并反向禁止 margin 做留白);
  让位改为 ≥5 处 `contentEndOffset`,并禁止退回窗格 padding 让位。
· 连带更新 ②/⑤ 与 appearance/logic/widescreen 的组件签名断言
  (组件多接一个 navReserve)。
· 删掉一段会假红的"从内容层 `}` 往后扫"的窗口式断言:它靠数花括号定界,
  而注释里就有大量 `.padding({` 字面量,切片能长到 1700+ 字符,
  一路扫进 `onAreaChange`(那里合法地出现 NAV_CONTENT_RESERVE)——
  正是本仓库反复记的窗口式判据,故改为纯负向断言。

测试:212 passed / 0 failed;`devecocli build` 通过;
模拟器截图与像素测量逐项核对。
2026-09-17 18:44:36 +08:00
ff75339baa 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。
2026-09-17 16:27:27 +08:00
a5f680a147 harmony(ui): 登录页 1:1 对齐 WebUI 卡片规格 + 通信页改用系统 Navigation Auto
登录页(LoginPage.ets):对照 WebUI LoginPage.tsx 同规格重写 build()
- maxWidth 380vp 居中卡片(与 WebUI 380px 同档)
- 14vp 圆角(Theme.glassRadius)
- 48vp 品牌图标(Envelope 浅蓝底 accentSoft)
- 显式字段标签(服务器/用户名/密码/用户密钥)
- 40vp 输入框与登录按钮(WebUI 控件同高)
- 分段式登录方式切换(账号密码 / 用户密钥)
- 窄屏安全边距 16vp + Scroll 可滚

通信页(MainPage.ets CommPage):改用鸿蒙系统 Navigation 组件
- Navigation(navPathStack) 包住列表,navDestination 注册邮件详情目标页
- mode(NavigationMode.Auto):phone 自动 Stack、tablet/2in1 自动 Split
- navBarWidth(320) 对齐 WebUI MailList 320px;navBarWidthRange([280,360])
- minContentWidth(360) 参与 Auto 断点计算
- Inbox/Sent 选中邮件改走 navPathStack.pushPath,不再 router.pushUrl
- 切收件箱/发件箱/授权时清空详情栈避免跨栏残留

详情页(MailDetailPage.ets):抽出可复用 MailDetailView
- 既有详情实现导出为 @Component struct MailDetailView
- 新增 initialMailId/initialAccountId/embedded/onBack 输入
- 无 initialMailId 时才读路由参数(兼容旧 router 入口)
- embedded=true 时返回走 onBack 回调(NavPathStack.pop)
- 薄壳 @Entry MailDetailPage 用 Column 包裹(@Entry 根节点须容器)

module.json5:deviceTypes 扩展为 phone/tablet/2in1 三形态

判据:harmony-widescreen.test.mjs 新增 ⑥ 钉住 Navigation Auto 不许退回手搓分栏

验证:ArkTS 编译通过;harmony-arkts/widescreen/nav/cross-client-theme 35/35 通过
2026-09-17 10:58:31 +08:00
31fdc1a3d8 ke: 宽屏 app-shell 几何落地:padding/gap 10 + 面板圆角 14(WebUI 一比一)
- MainPage 宽屏 Row({ space: Theme.paneGap }) —— gap 10(窄屏无子间距,无害)
- 内容面板 borderRadius(isWide ? glassRadius : 0) + clip(isWide) —— 圆角 14 仅宽屏
- 容器 padding 条件:宽屏 paneGap 10(壁纸从缝隙露出)/ 窄屏 0(贴合全屏)
- Theme.glassRadius=14 / paneGap=10 已在上一提交引入,这里真正用上
- 判据:harmony-widescreen ⑤ 钉 app-shell 几何(令牌值/space/radius/clip/padding 与 WebUI 同值)
2026-09-16 07:58:13 +08:00
fd4b475920 ke: 鸿蒙导航纯图标 + 图标加大 + 玻璃几何令牌
用户反馈:① 图标太小 ② 底部导航栏不允许有文字。

- NavItem(底部导航):去掉 Text(item.label) 纯图标,AmIcon 22→28vp
- WideSidebar(宽屏侧栏):去掉 label 文字(WebUI Sidebar 本就是 60px 纯图标轨),
  导航图标 22→26vp、品牌标 26→30vp;NavItemBuilder 去掉 label 参数
- Theme:新增 glassRadius=14 / paneGap=10(与 WebUI app-shell CSS 变量同值,
  用于宽屏玻璃面板几何;原有 radiusCard 保持系统跟随不动)
- 判据同步:harmony-nav ⑤ 改纯图标(1 处三元式 + 无文字 + 28vp)+ 变异自检三项;
  harmony-widescreen ③ 同样改纯图标(1 处 + 无文字 + 26vp)
2026-09-16 07:54:44 +08:00
cfe7808af4 ke: 鸿蒙 UI 整改:emoji→AmIcon 图标、宽屏侧栏、Md 第三方库、通知可配置项
- common/Icons.ets(生成器产出):43 枚与 WebUI icons.tsx 同几何的 Path 图标
- NavItems.ts:icon(emoji) → iconKey,与 WebUI 导航同图标
- 全页面 emoji 清除(空态改单行灰字,按钮/头像/刷新等换 AmIcon)
- MailDetailPage 接入 @luvi/lv-markdown-in(第三方,替代手写解析器)
- WideSidebar + MainPage isWide(≥768vp):宽屏侧栏 60vp 图标轨、藏底部条、onAreaChange 断点
- 通知=可配置项(默认关):PushService.isEnabled/setEnabled + reportToken 最前 gate (关=不取token/不弹权限/不打网关)+ SettingsPage Toggle + 服务端通道状态提示
- EntryAbility.onCreate 解析 want:冷启点通知也能路由(原来只有 onNewWant)
- 判据:harmony-widescreen(4) + harmony-push-optin(4) 新增;harmony-nav 同步 iconKey/条件 padding
2026-09-16 07:46:52 +08:00