跨端: 导航条材质选 (a) 固定档(推翻我的 (b))—— 并修掉"注释说 (a)、代码是 (b)"的自相矛盾
pi 2026-09-15 裁定:**推翻 (b),选 (a)**。我原先给 (b) 的理由不成立,他逐条驳了:
1. **WebUI 的导航条根本不读 `--bg-blur`**:`index.css:1114` 的 `.narrow-nav` 是硬编码
`backdrop-filter: blur(18px) saturate(1.5)`。我引这条支持"两个量不同",
而同一条也说明**它不由用户偏好驱动**。
2. **WebUI 那个滑杆的语义是"背景"**:`BackgroundPicker.tsx:183` —— `label="模糊"`、
`hint="虚化细节,避免背景与正文抢注意力"`、`min=0 max=24`,只作用在
`.app-backdrop{filter:blur(var(--bg-blur))}` 上。
3. WebUI 自己留了**分开的**令牌 `--bg-blur-panel`(`index.css:267`,注释写明
"与壁纸自身的 `--bg-blur` 分开")—— 它的词汇表本身就拒绝把两者等同。
4. **★ 我给 (b) 的理由不成立**:我写"(a) 会让那个滑杆在导航条上变成死控件",
可那个滑杆**已经**被壁纸消费了(`MainPage.ets` 壁纸层的 `.blur(bgPlan.blurPx)`)——
它从来**不是**导航条的控件。(a) 之下它照样是活的。
5. §7.12 的「材质(玻璃)」行原本写的就是固定档 ⇒ (a) 是**回到**已登记契约。
产品向还有一条:**导航条是 chrome,材质应当稳定**,不该因为用户换张壁纸而变厚变薄。
## 最该记的是:我的注释和代码**互相矛盾**
`MainPage.ets` 里那段注释论证的是 (a)、并明确写着"跟随是错的,pi 抓出来了",
而它下面那一行代码是 (b)。**下一个读者会照注释把代码改回去,并引我那句话当权威。**
这是这一路反复在消的形状(说的与做的不一致、而判据看不见),这次落在**注释**上 ——
而注释正是"理由要写清"那条纪律的证据源。已整段重写为真实的 (a) 版本,并把
"(a) 会让滑杆变死控件"这个**错的理由**连同它为什么错一起留在注释里。
## 做掉的东西
- `MainPage.ets`:导航条回到 `.backgroundBlurStyle(Theme.navMaterial)`;
删掉 `NAV_MATERIAL_OF` 表与 `navMaterialFor` 的 import((a) 之下都是孤儿)。
- `model/Appearance.ts`:删 `navMaterialFor`(它存在的唯一理由就是方案 (b))。
`blurStyleFor` 现在**没有任何调用点** —— 如实登记在它的文档注释里
("有测试"不等于"有人用",上一轮我刚因同形状被抓过),不假装它活着。
- **五处"整条字面表达式"断言改成语义断言**(pi §四):`cross-client-theme`、`harmony-appearance`、
`harmony-nav`(3 处)此前都在钉
`/\.backgroundBlurStyle\(NAV_MATERIAL_OF\[navMaterialFor\(…\)\] \?\? Theme\.navMaterial\)/`
—— 字面换字面,正是 `CRITERIA.md` 不许的"对源码形状的匹配"。
现在判:① 那一处的材质**来自 `Theme.navMaterial` 这个系统令牌**;
② **不许跟随** `bg_blur`(NavBar 真代码里不许出现 `blurPx`/`blurStyleFor`);
③ 令牌是 `BlurStyle` 枚举值、不是 `NONE`、且**成员名真实存在于 SDK 枚举**。
- "可达性"那条判据**随契约作废**(它守的是方案 (b)):换成判 (a) 的契约。
**判据随契约走,不随实现走。**
- `harmony-appearance`:原先判"页面里那张表的键必须是 SDK 成员"。表删了,
改成**枚举 `blurStyleFor` 的整个值域**(0..40 + 界外 + NaN),逐个核 SDK 成员 ——
比原来只核表里那三行**更严**。
## 判据自己先错了一次,记下来
新判据第一版**没剥注释**就断言"NavBar 里不许出现 `blurPx`",当场红了 ——
而红的原因不是代码错,是 `NavBar` 的**文档注释**里正好写着
"我一度把档位接过用户偏好(`navMaterialFor(this.bgPlan.blurPx)`)"这句历史说明。
**注释说明禁令 ≠ 违反禁令**;不剥注释,这条判据就会变成"逼人删掉解释",
恰好与本仓库"理由要写清"的纪律相反。改成 `stripComments(bar)` 后再判,并加了一条
"注释里确实留着那处说明"的自检前提。
## 变异体:45 个全部被抓(含 3 个新判据的专属变异)
方案 (b) 落地时配的 13 个变异体**整体作废**(它们锚的代码被删了),标注 `retired`
并写清理由 —— 不是"没跑成"。另有 5 个锚点漂移(我在注释里逐字引用了被锚的那句代码,
污染了通用正则)的**重锚**到真代码;注释里那句逐字引用也一并去掉了
(**注释里逐字抄代码**正是让"按字面锚定"的变异体反复失效的根因)。
新增 3 个针对 (a) 契约的变异体(绕过令牌 / 又跟随 `bg_blur` / 令牌变 `NONE`),全部被抓。
## 未验
- **真机观感仍未验**:三档材质在真机上能不能看出差别、滑杆手感、管理页布局,
只有真机能答。本机模拟器已起(`hdc list targets` 有目标),但
`run-all.mjs` 的**设备闸已经到期**(8 个静态判据的前提成立)⇒ 套件现在会挡在
那道闸上、不打 `RESULT`。**这不是本笔引入的**(前提是环境变了),已单独报给 pi。
- Go 侧 `debt_registry_test.go` 仍未在本机跑(无 Go 模块缓存);pi 已在别处跑过,绿。
This commit is contained in:
@ -162,28 +162,33 @@ export function localOnly(local: AppearanceSnapshot): AppearanceSync {
|
||||
}
|
||||
|
||||
/**
|
||||
* 壁纸模糊档 → **系统材质档次**(不是像素半径)。
|
||||
* 壁纸模糊档 → **系统材质档次名**(不是像素半径)。
|
||||
*
|
||||
* 服务端存的是 WebUI 的 `bg_blur`(0~40 的模糊像素),而鸿蒙这边"模糊"由系统材质提供
|
||||
* (`BlurStyle`)—— 这是"用系统方案"的直接结果:同一个数字在两边含义不同,
|
||||
* 所以要**显式映射**,而不是把 40 当半径塞进某个 API。映射关系写在这里,
|
||||
* 判据可以直接跑它(哪个数字落到哪一档,是行为不是注释)。
|
||||
* 所以要**显式映射**,而不是把 40 当半径塞进某个 API。
|
||||
*
|
||||
* ── 为什么返回的是**档位名**(字符串)而不是 SDK 的枚举数值 ──
|
||||
* 返回**档位名**(字符串)而不是 SDK 枚举数值:这一层是**纯逻辑**(零 `@ohos` 依赖
|
||||
* ⇒ 判据能用 node 直接跑它),而 `BlurStyle` 只有 `.ets` 里在作用域内。
|
||||
* 判据把返回值与 SDK 的 `declare enum BlurStyle` 成员名比对
|
||||
* ("档次必须来自系统枚举,写成自造名字会编译不过/不生效")。
|
||||
*
|
||||
* 与同一个文件里的 `colorModeFor`(`'COLOR_MODE_DARK' | …`)**同一种形状**:
|
||||
* 这一层是**纯逻辑**(零 `@ohos` 依赖 ⇒ 判据能用 node 直接跑它),
|
||||
* 而 `BlurStyle` 是 SDK 的枚举、只有 `.ets` 里才在作用域内。
|
||||
* 返回档位名 ⇒ 映射的**分档判断**留在这层可判,`名字 → BlurStyle` 那一步在页面里
|
||||
* 用一张**四行长**的表做掉(`MainPage.ets` 的 `BLUR_STYLE_OF`)。
|
||||
* ── ★ 现在**没有任何调用点**(如实登记,别把它读成活的)──
|
||||
*
|
||||
* ★ 我一度把它改成"直接返回 SDK 数值(0/9/10/11)"想省掉那张表 —— **被判据挡回来了**,
|
||||
* 而且挡得对:`harmony-appearance.test.mjs` 有一条判据把**返回值拿去和 SDK 的
|
||||
* `declare enum BlurStyle` 成员名比对**("档次必须来自系统枚举,写成自造名字会
|
||||
* 编译不过/不生效")。返回数值就永远对不上成员名,那条判据会一直红 ——
|
||||
* 它保护的正是"别自己发明档位"这件事。
|
||||
* ⇒ 回到档位名。那张四行的表不是负担,它是"哪个名字对应哪个枚举"的**唯一**落点,
|
||||
* 而且页面里能对着 SDK 写(纯逻辑层看不到 BlurStyle)。
|
||||
* 它的读者曾经有两个,两个都不在了:
|
||||
* ① `MainPage.ets` 里那张 `名字 → BlurStyle` 的表,随"导航条改回固定档"删了;
|
||||
* ② 文件名一度是 `navMaterialFor` 的**有下限**入口(导航条专用),
|
||||
* 它存在的唯一理由是"导航条档位跟随 `bg_blur`"这个方案 —— 而 pi 2026-09-15
|
||||
* **推翻了那个方案**(导航条是 chrome,材质固定;见 `MainPage.ets` 的 `NavBar` 注释),
|
||||
* 所以它连同"下限"一起删了。
|
||||
*
|
||||
* 于是本函数成了**孤岛**:判据还在、行为还对,但页面里没人调它。
|
||||
* 这是**故意留着**的(它是目录里那套分档语义的唯一落点,且判据在跑),
|
||||
* 不是"以为有人在用"。**如果你要用它,请先想清楚是不是又在重造方案 (b)。**
|
||||
*
|
||||
* ⚠️ 试金石:**"有测试"不等于"有人用"**。上一轮我刚因为同形状的事被抓过一次
|
||||
* (`Theme.navMaterial` 的"外部引用"落在一个不可达的 `??` 兜底分支上,
|
||||
* 而死令牌判据照样绿)。函数名这里没有等价判据 —— 只有这段文字,所以更要写实。
|
||||
*/
|
||||
export function blurStyleFor(bgBlur: number): string {
|
||||
const b: number = clampNumber(bgBlur, 0, 40, 4);
|
||||
@ -199,32 +204,6 @@ export function blurStyleFor(bgBlur: number): string {
|
||||
return 'COMPONENT_THICK';
|
||||
}
|
||||
|
||||
/**
|
||||
* **导航条专用**的材质档:与 `blurStyleFor` 同一张分档表,但**有下限**。
|
||||
*
|
||||
* ── 为什么必须分成两个入口(这不是过度设计,是一次真实缺陷的产物)──
|
||||
*
|
||||
* 导航条的档位一度**直接**接 `blurStyleFor(bgBlur)`,于是 `bg_blur = 0`(用户把壁纸
|
||||
* 调清晰)时 `blurStyleFor` 返回 `'NONE'` ⇒ **导航条一点材质都没有**。
|
||||
* 而"导航条是玻璃"是设计不变量(WebUI 的 `.narrow-nav` 是硬编码 `blur(18px)`,
|
||||
* **不看** `--bg-blur`),用户要的是"壁纸清晰",不是"导航条变透明"。
|
||||
*
|
||||
* 两个量、两个输入、**两个下限**:
|
||||
* · 壁纸模糊(`bg_blur`):**允许 0**(不模糊是合法选择)⇒ `blurStyleFor` 保留 `'NONE'`;
|
||||
* · 导航条材质:**不许没有**(玻璃是它的身份)⇒ 本函数把下限抬到最薄档。
|
||||
*
|
||||
* 判据在 `harmony-nav.test.mjs`:在**可达输入**上(滑杆 0..40 的每个整数 + 界外值)
|
||||
* 本函数都不返回 `'NONE'`;且导航条那一处必须**经本函数**、不许直接用 `blurStyleFor`。
|
||||
*/
|
||||
export function navMaterialFor(bgBlur: number): string {
|
||||
const tier: string = blurStyleFor(bgBlur);
|
||||
if (tier === 'NONE') {
|
||||
// 壁纸可以清晰,导航条仍然要有玻璃
|
||||
return 'COMPONENT_THIN';
|
||||
}
|
||||
return tier;
|
||||
}
|
||||
|
||||
/**
|
||||
* 主题偏好 → 系统色彩模式。
|
||||
*
|
||||
|
||||
@ -14,7 +14,7 @@ import { SseService, SseEvent } from '../api/SseService';
|
||||
import { AppearanceStore } from '../common/AppearanceStore';
|
||||
import { Configuration, ConfigurationConstant, EnvironmentCallback } from '@kit.AbilityKit';
|
||||
import { image } from '@kit.ImageKit';
|
||||
import { AppearanceSnapshot, isDarkMode, scrimOpacity, navMaterialFor } from '../model/Appearance';
|
||||
import { AppearanceSnapshot, isDarkMode, scrimOpacity } from '../model/Appearance';
|
||||
import { BackgroundPlan, PresetLayer, TRANSPARENT, resolveBackground } from '../model/Wallpaper';
|
||||
import { MailSummary, Contact, PermissionRequest, DecideResponse, SentResponse, PendingResponse } from '../model/Models';
|
||||
import {
|
||||
@ -49,23 +49,21 @@ import {
|
||||
emptyHint
|
||||
} from '../model/CommTabs';
|
||||
import { MailDetailParams, ComposeParams } from '../model/RouteParams';
|
||||
|
||||
/**
|
||||
* `navMaterialFor` 给的**档位名** → SDK 的 `BlurStyle` 枚举(导航空专用)。
|
||||
/*
|
||||
* ⚠️ **`import` 必须在这一行的位置**:ArkTS 要求所有 import 都在**任何其它语句之前**
|
||||
* (`arkts-no-misplaced-imports`),与它们之间隔的是常量、表还是别的语句无关。
|
||||
*
|
||||
* 与 `blurStyleFor` 的关系:同一个分档表,但 `navMaterialFor` **有下限**(永不 NONE),
|
||||
* 因为"导航条是玻璃"是不变量,而壁纸可以不模糊(见 `model/Appearance.ts` 的说明)。
|
||||
* 这一笔我犯过:`7647c24` 里我把一张常量表(`NAV_MATERIAL_OF`)插在了这两组 import
|
||||
* **之前**,于是 `hvigorw assembleHap` 直接报错(`f31bc02`/`7647c24` 上都红)。
|
||||
* **归属说明**:那条错是我造成的,`git show 7647c24:…/MainPage.ets` 可复核
|
||||
* (最后一条 import 在第 80 行,而第 63 行已是 `const NAV_MATERIAL_OF`)。
|
||||
* 此处原先写的是"由 pi 实测" —— 那句话不准确:是本机**某个** pi 会话/别人测的,
|
||||
* 我无法独立复核"是谁",这类**归属断言**和"锚短哈希"同族(复核方没法复现"谁做的"),
|
||||
* 所以改成只陈述**可复核的事实**:错误存在、在哪个提交、怎么复核。
|
||||
*
|
||||
* ★ 表留在页面里:`BlurStyle` 是 SDK 枚举,只有 `.ets` 里在作用域内;而
|
||||
* `model/Appearance.ts` 是**纯逻辑、零 `@ohos` 依赖**,判据要靠 node 直接跑它。
|
||||
* 分工:**分档判断**在纯逻辑层(可判),**名字 → 枚举**这一步在这里(对着 SDK 写)。
|
||||
* 那张表和它的 import 后来都随"导航条改回固定档"一起删了(见下面 `NavBar` 的注释);
|
||||
* 这条注释留在 **import 区**而不是跟着表走,因为要守的是"import 在最前"这个位置本身。
|
||||
*/
|
||||
const NAV_MATERIAL_OF: Record<string, BlurStyle> = {
|
||||
'COMPONENT_THIN': BlurStyle.COMPONENT_THIN,
|
||||
'COMPONENT_REGULAR': BlurStyle.COMPONENT_REGULAR,
|
||||
'COMPONENT_THICK': BlurStyle.COMPONENT_THICK
|
||||
};
|
||||
|
||||
import { CalendarPage } from './CalendarPage';
|
||||
import {
|
||||
NAV_BAR_BOTTOM,
|
||||
@ -1711,7 +1709,7 @@ struct MainPage {
|
||||
* ★ 半径直接用服务端给的那个 px 值:WebUI 就是 `blur(var(--bg-blur))`,
|
||||
* 两边**同一个物理量、同一个数** ⇒ 这一处不需要映射表,也不该有。
|
||||
* (`blurStyleFor` 那张表服务的是**材质档**,与这里的 px 半径不是一回事;
|
||||
* 它的调用点在导航条那条链上 —— 经 `navMaterialFor` 复用,见 `NavBar`。)
|
||||
* 它是**纯逻辑层**的可判依据;页面侧的面板材质走 `Theme.navMaterial`,见 `NavBar`。)
|
||||
*/
|
||||
.blur(this.bgPlan.blurPx)
|
||||
// 压暗用**系统遮罩色** + 服务端给的浓度:换向(浅色洗白/深色压黑)由系统负责
|
||||
@ -1793,23 +1791,32 @@ struct MainPage {
|
||||
* 深浅两套颜色与模糊半径都由系统按主题给。
|
||||
*/
|
||||
/*
|
||||
* 导航条的**面板材质**:**固定系统档**(`Theme.navMaterial`),**不跟随 `bg_blur`**。
|
||||
* 导航条的**面板材质**:**固定系统档**(`Theme.navMaterial` = `COMPONENT_THICK`),
|
||||
* **不跟随 `bg_blur`**。
|
||||
*
|
||||
* ★ 我一度把它接过用户偏好(`blurStyleFor(blurPx)`),**是错的**,pi 抓出来了。
|
||||
* 两条依据:
|
||||
* ① WebUI 侧导航条的糊度**不由 `--bg-blur` 驱动** ——
|
||||
* `index.css:1114` 的 `.narrow-nav` 是硬编码 `backdrop-filter: blur(18px) saturate(1.5)`
|
||||
* (`html[data-bg='on']` 作用域内),壁纸糊到 0,导航条照样是玻璃。
|
||||
* 跟随用户偏好是**新增差异**,不是对齐。
|
||||
* ② 更根本的:我上一笔刚把"**图片内容模糊**"与"**面板材质**"论证成两个不同的物理量
|
||||
* (见壁纸层那段注释与 `harmony-appearance.test.mjs`),转头却把**面板材质**的档位
|
||||
* 接到了**壁纸模糊**这个输入上 —— 自己打自己。两个量、两个输入。
|
||||
* ⇒ 用户把模糊滑杆拖到 0(要壁纸清晰)时,导航条**仍然**是玻璃。
|
||||
* 这曾是真实缺陷:滑杆 `min: 0` 可达,`blurStyleFor(0) === 'NONE'`,
|
||||
* 于是导航条一点材质都没有(本文件里那句「NONE 等于没有材质,"玻璃"就名存实亡」
|
||||
* 说的正是这件事)。判据 `harmony-nav.test.mjs` 现在钉"可达输入上该档**非 NONE**"。
|
||||
* ── 这里曾经"说的和做的不一致",记下来(pi 2026-09-15 抓到的)──
|
||||
* 我一度把档位接过用户偏好(`navMaterialFor(this.bgPlan.blurPx)` 查表),
|
||||
* 但**注释留在了更早那一版**:那段注释论证的是"固定档"、还写着"跟随是错的"。
|
||||
* 于是**注释说 (a)、代码是 (b)** —— 下一个读者会照注释把代码改回去,
|
||||
* 而且他会引我那句"pi 抓出来了"当权威。**说的与做的不一致、而判据看不见**,
|
||||
* 正是这一路反复在消的形状,这次落在注释上(而注释正是"理由要写清"那条纪律的证据源)。
|
||||
*
|
||||
* ── 为什么最终是固定档(pi 的裁定,五条依据,我原先的理由被推翻)──
|
||||
* ① WebUI 的 `.narrow-nav`(`index.css:1114`)是**硬编码** `backdrop-filter: blur(18px)`,
|
||||
* **不读** `--bg-blur`;
|
||||
* ② WebUI 那个滑杆的语义是"**背景**"(`BackgroundPicker.tsx:183`:`label="模糊"`、
|
||||
* `hint="虚化细节,避免背景与正文抢注意力"`,`min=0 max=24`),只作用在
|
||||
* `.app-backdrop{filter:blur(var(--bg-blur))}` 上;
|
||||
* ③ WebUI 自己留了**分开的**令牌 `--bg-blur-panel`(`index.css:267`,注释写明
|
||||
* "与壁纸自身的 `--bg-blur` 分开:那层给照片打底,这层给面板")——
|
||||
* 它的词汇表本身就把两者分开;
|
||||
* ④ **我原先的理由不成立**:我说"(a) 会让那个滑杆在导航条上变成死控件",
|
||||
* 可那个滑杆**已经**被壁纸消费了(本文件下面的壁纸层把 `bgPlan.blurPx` 交给 `.blur(...)`)——
|
||||
* 它从来**不是**导航条的控件,(a) 之下它照样是活的;
|
||||
* ⑤ §7.12 的「材质(玻璃)」行原本写的就是固定档 ⇒ (a) 是**回到**已登记契约。
|
||||
* 产品向还有一条:**导航条是 chrome,材质应当稳定**,不该因为用户换了一张壁纸而变厚变薄。
|
||||
*/
|
||||
.backgroundBlurStyle(NAV_MATERIAL_OF[navMaterialFor(this.bgPlan.blurPx)] ?? Theme.navMaterial)
|
||||
.backgroundBlurStyle(Theme.navMaterial)
|
||||
}
|
||||
|
||||
build() {
|
||||
|
||||
Reference in New Issue
Block a user