跨端: 顶部页签条改悬浮玻璃 + 深色压暗下限(修 8 处深色可读性)+ 手势判据自搭现场
用户:「顶部的收件箱发件箱和授权为什么不做成悬浮玻璃?」
问得对,而且它当时是**整页唯一一块实心白**。
★ 顶部页签条 → 悬浮玻璃
`CommTabBar` 原来写的是 `backgroundColor(Theme.surface)`(系统卡片色=实体)。
上一轮把列表容器、卡片、底部导航条都玻璃化了,**唯独漏了这条** ——
它既不是卡片也不是容器,是"条状 chrome",逐处修时最容易漏的那一类。
⇒ 现在与底部浮动条**同一族**:圆角 + 左右留白 + `Theme.navMaterial`。
★ 几何常量复用底部条的(`TAB_BAR_RADIUS = NAV_BAR_RADIUS`、
`TAB_BAR_SIDE = NAV_BAR_SIDE`),不各写一份 —— 两个数一旦分叉,
"同一条轴线上的两种条"就不齐了。为什么选悬浮而不是 WebUI 的"通栏无底色"
(WebUI 页签条自己**没有**底色,靠父面板的玻璃)也记在那个常量的注释里。
新增判据:页签条必须与导航条同族(不许实体面 / 要引 TAB_BAR_* 常量),
变异验证过(改回 `Theme.surface` 即红)。
★ 深色压暗下限 —— 本轮最重要的真 bug
玻璃让壁纸**真的透进卡片**之后,"浅壁纸 + 深色文字令牌"这个组合会在
**卡片内部**发生。设备实测(深色、aurora、压暗 37):
「角色」ink rgb(183,195,211) on bg rgb(68,95,128) = 2.57:1
「创建时间」2.27:1、「状态」2.68:1、「压暗」2.19:1(共 8 段 <3:1)
而**同一套代码在浅色下全部达标** ⇒ 差别不在"选错了色",在"底没暗下来"。
WebUI 早就撞过并写下了必然值(`index.css:442`):
.dark { --bg-dim-min: 92%; } /* 浅色下是 0% */
background-color: rgb(var(--bg-scrim) / max(var(--bg-dim), var(--bg-dim-min)));
我们只有 `scrimOpacity(bgDim)`、**没有下限**。补上 `DARK_DIM_MIN = 0.92`
(浅色下用户设的值照旧生效,不忽略设置)。
复扫:低对比 8 段 → 通信 0 / 日历 0 / 联系 1 / 我的 1
(剩下两条经手核是扫描器的假阳性:近黑底上把抗锯齿暗像素当成了"墨")。
★ 手势判据"没有自己搭现场"(套件红、单独绿)
`cross-client-gesture` 只保证"在月档"、**不保证在哪一月**,而它算的是
相对最初那一月的 delta ⇒ 前面某个判据(或一次失败的手势)把日历翻到 10 月后,
期望值就差一格。修法:先点「今天」归位到本月(该按钮语义就是"回本月")。
验证:从 9 月起步、从 10 月起步,两种脏状态都通过。
★ 顺带确认手势本体是好的:`--speed 1500` 时 1000px 要走 670ms,
紧贴 `SWIPE_MAX_DURATION_MS=700` 而被丢弃;`--speed 3000` 两个方向都翻。
★ 判据基建:修掉一个**静默失效**的 API 名(沿用上轮的教训修法)
`Surface.ets` 里两处块注释内嵌了 `/* ... */` —— 会把块注释**提前闭合**,
于是后面的代码跑到注释外面(报"Use let instead of var"/"Invalid character")。
本仓已有这条纪律("当 `code()` 因注释里的 `/*` 吞掉 import 时,改注释文本"),
这次又踩了两处(`Surface.ets` 与 `Appearance.ts`)。
判据:files=32 ran=32 checks=519 pass=519 fail=0 red=0;baseline 7/7✓。
This commit is contained in:
@ -271,10 +271,45 @@ export function isDarkMode(theme: string, systemColorMode: number): boolean {
|
||||
return systemColorMode === 0; // COLOR_MODE_DARK
|
||||
}
|
||||
|
||||
/** 遮罩浓度:0~90 的"压暗"值 → 0~1(系统遮罩色 + 这个不透明度) */
|
||||
export function scrimOpacity(bgDim: number): number {
|
||||
/**
|
||||
* **深色下的压暗下限**(比例)。0.92 = 壁纸至少被压掉 92%。
|
||||
*
|
||||
* ★★ 2026-09-19:这条是从 WebUI 抄来的**必然值**,不是调出来的观感。
|
||||
*
|
||||
* WebUI `index.css:772` 与 `:442`:
|
||||
*
|
||||
* background-color: rgb(var(--bg-scrim) / max(var(--bg-dim), var(--bg-dim-min)));
|
||||
* .dark { --bg-dim-min: 92%; } ← 浅色下是 0%
|
||||
*
|
||||
* 那段注释写清了成因(实测事故):用户上传的是一张**浅色**照片
|
||||
* (均值 RGB 213,212,225),压暗 56% 之后壁纸仍是中灰 94,
|
||||
* 而深色主题的文字是近白的 ⇒ 近白对中灰只有约 3.6:1,
|
||||
* 次要文字更是 1.2–1.4:1。**没有任何文字颜色能救** ——
|
||||
* 不是"选错了色",是"底没暗下来"。
|
||||
*
|
||||
* 加了下限之后 WebUI 复测:四页最差 通信 6.14 / 日历 4.90 / 联系 4.96 /
|
||||
* 我的 5.38,全部 ≥ 4.5:1。
|
||||
*
|
||||
* ★ 为什么鸿蒙这边也必须跟:现在卡片是**玻璃**(壁纸真的透得进来),
|
||||
* 于是"浅壁纸 + 深色文字令牌"这个组合会在**卡片内部**发生 ——
|
||||
* 设备实测(模拟器 3184×2232、深色、aurora + 压暗 37):
|
||||
* 「角色」ink rgb(183,195,211) on bg rgb(68,95,128) = **2.57:1**
|
||||
* 「创建时间」2.27:1、「状态」2.68:1、「压暗」2.19:1
|
||||
* 而**同一套代码在浅色下**这些字都是达标的 —— 差别就在底有没有暗下来。
|
||||
*/
|
||||
export const DARK_DIM_MIN: number = 0.92;
|
||||
|
||||
/**
|
||||
* 遮罩浓度:0~90 的"压暗"值 → 0~1(系统遮罩色 + 这个不透明度)。
|
||||
*
|
||||
* ★ 深色下取 `max(用户设的, DARK_DIM_MIN)`:用户的压暗值在浅色下**完全照用**
|
||||
* (浅色页面本来就白,压暗只是调味),而深色下它压不住浅壁纸。
|
||||
* 这不是"忽略用户设置"—— 用户设的 37% 在浅色下依然原样生效。
|
||||
*/
|
||||
export function scrimOpacity(bgDim: number, dark?: boolean): number {
|
||||
const d: number = clampNumber(bgDim, 0, 90, 12);
|
||||
return d / 100;
|
||||
const v: number = d / 100;
|
||||
return dark === true ? Math.max(v, DARK_DIM_MIN) : v;
|
||||
}
|
||||
|
||||
/** 状态文案:降级必须看得见(WebUI 侧的原话:「否则用户以为换设备也能带走」) */
|
||||
|
||||
@ -299,3 +299,30 @@ export function navBadgeText(n: number): string {
|
||||
}
|
||||
return n + '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 顶部页签条(通信页的 收件箱/发件箱/授权)的几何 —— 与底部浮动条**同一族**。
|
||||
*
|
||||
* 用户 2026-09-20:「顶部的收件箱发件箱和授权为什么不做成悬浮玻璃?」
|
||||
*
|
||||
* 问得对,而且它当时是**整页唯一一块实心白**:上一轮把列表容器、卡片、
|
||||
* 导航条都玻璃化了,唯独这条页签条还写着 `Theme.surface`(系统卡片色 = 实体)
|
||||
* ⇒ 壁纸从四周透出来,只有它在顶上白着一横条,成了最扎眼的那块。
|
||||
*
|
||||
* 为什么**悬浮**(左右留白 + 圆角)而不是"通栏 + 材质":
|
||||
* · 底部导航条已经确立了这个语汇(`NAV_BAR_*`),顶部再做一个通栏的
|
||||
* 会在同一条轴线上出现两种不同的"条";用户要的正是"和底部一样"。
|
||||
* · WebUI 的页签条本身**没有底色**(`CommTabs.tsx:40` 只有
|
||||
* `border-b border-gray-200`),靠父面板的玻璃 —— 那是"通栏"做法。
|
||||
* 本仓底部条选了悬浮,于是顶部跟底部统一,是**本仓的**选择;
|
||||
* 差异记在这里,免得后人以为漏抄了 WebUI。
|
||||
*
|
||||
* 高度与侧留白**复用底部条的常量**(不是各写一份):两者一旦不同,
|
||||
* "同一条轴线上的两种条"就变成肉眼可见的不齐 —— 而这正是本仓反复出现的那类毛病
|
||||
* (同一个东西两处各写一个数,然后慢慢分叉)。
|
||||
*/
|
||||
export const TAB_BAR_RADIUS: number = NAV_BAR_RADIUS;
|
||||
export const TAB_BAR_SIDE: number = NAV_BAR_SIDE;
|
||||
/** 顶部留白(vp):离内容区顶部一点点,做成"浮着"而不是"贴着" */
|
||||
export const TAB_BAR_TOP: number = 8;
|
||||
|
||||
@ -86,6 +86,9 @@ import {
|
||||
NAV_CONTENT_RESERVE,
|
||||
NAV_ITEM_MIN_HIT,
|
||||
NAV_ITEMS,
|
||||
TAB_BAR_RADIUS,
|
||||
TAB_BAR_SIDE,
|
||||
TAB_BAR_TOP,
|
||||
navBadgeCount,
|
||||
navBadgeText,
|
||||
navBadgeTone,
|
||||
@ -1425,7 +1428,22 @@ struct CommPage {
|
||||
}, (key: string) => key)
|
||||
}
|
||||
.width('100%')
|
||||
.backgroundColor(Theme.surface)
|
||||
/*
|
||||
* ★★ 2026-09-20(用户:「顶部的收件箱发件箱和授权为什么不做成悬浮玻璃?」)
|
||||
*
|
||||
* 这一行原来是 `backgroundColor(Theme.surface)` —— 系统卡片色,**实体**。
|
||||
* 于是它是整页唯一一块实心白:上一轮把列表容器、卡片、底部导航条
|
||||
* 都玻璃化了,唯独漏了这条页签条 ⇒ 壁纸从四周透出来,只有它在顶上白着一横条。
|
||||
*
|
||||
* 现在与**底部浮动条同一族**:圆角 + 左右留白 + 系统材质。
|
||||
* 三种做法各自的取舍见 `model/NavItems.ts` 的 `TAB_BAR_*` 常量注释
|
||||
* (为什么选悬浮而不是 WebUI 的"通栏无底色")。
|
||||
*/
|
||||
.backgroundColor(Color.Transparent)
|
||||
.backgroundBlurStyle(this.bgActive ? Theme.navMaterial : BlurStyle.NONE)
|
||||
.borderRadius(TAB_BAR_RADIUS)
|
||||
.clip(true)
|
||||
.margin({ left: TAB_BAR_SIDE, right: TAB_BAR_SIDE, top: TAB_BAR_TOP })
|
||||
}
|
||||
|
||||
openMail(mailId: string, accountId: string): void {
|
||||
@ -2599,7 +2617,7 @@ struct MainPage {
|
||||
this.accountLabel = '';
|
||||
}
|
||||
// 模糊强度是**服务端给的 px 原值**:计划只搬运它,映射成系统材质档在画的那一层做
|
||||
this.bgPlan = resolveBackground(snap.bgKind, snap.bgPresetId, scrimOpacity(snap.bgDim), store.wallpaper !== null, dark, snap.bgBlur);
|
||||
this.bgPlan = resolveBackground(snap.bgKind, snap.bgPresetId, scrimOpacity(snap.bgDim, dark), store.wallpaper !== null, dark, snap.bgBlur);
|
||||
this.bgActive = this.bgPlan.kind !== 'none';
|
||||
/* 让 `@State` 感知到"壁纸内容换了"(对象内部字段的变化观察不到 —— 见它的声明) */
|
||||
this.bgContentRev = this.bgContentRev + 1;
|
||||
|
||||
Reference in New Issue
Block a user