From 9aa702b8cc80226bb7d8b52c95140d9e7e5e2518 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Mon, 14 Sep 2026 11:57:41 +0800 Subject: [PATCH] =?UTF-8?q?fix(webui):=20=E5=AF=BC=E8=88=AA=E6=94=B9"?= =?UTF-8?q?=E6=8C=89=E4=B8=BB=E9=A2=98=E7=9A=84=E7=8E=BB=E7=92=83"?= =?UTF-8?q?=EF=BC=88=E6=B5=85=E8=89=B2=E7=99=BD=E7=8E=BB=E7=92=83+?= =?UTF-8?q?=E6=B7=B1=E5=AD=97=EF=BC=89+=20=E5=8E=BB=E6=8E=89=E6=95=B4?= =?UTF-8?q?=E5=B1=8F=E9=97=AA=E7=9A=84=E5=85=A5=E5=9C=BA=E5=8A=A8=E7=94=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户两句话: 「那你为什么不把白字换成黑字或者自动反色或者描边呢?」 「部分动画十分不合理,会导致页面大范围的闪动,且不能让人自然的把注意力集中在 将要出现的页面上」 ## ① 导航:他说得对,我之前是用错误的方式解决对比度 这个应用是**浅色底 + 深字**,导航却是全页唯一一块黑的 —— 那才是"割裂"。我上一轮 为了"白字对比度"把它做成深玻璃,等于**把一块地方永久压黑**来回避问题。 现在导航底色/文字全部走令牌,按主题切换: 浅色:白玻璃 rgb(255 255 255 / .72) + 深字 #475569 → 对比度 7.48:1 深色:深玻璃 rgb(15 23 42 / .72) + 亮字 #94a3b8 → 自动反色 组件侧改成 `.nav-rail` / `.nav-item[data-active]` 令牌类(Sidebar 与 NarrowNav 同一套)。 同时删掉壁纸模式里写死的深玻璃规则 —— 那条正是"为什么还是黑色"。 ## ② 动画:整面板入场删掉 先是从"所有面板一起动"改成"只动主内容区",试下来仍然不对:页面级淡入会把 **已经在那儿的框架**也一起暗一下,观感还是闪。所以这一档整体删掉,只保留局部、 有明确语义的动效(日历翻页、菜单展开)。实测切视图时 `animatedOnSwitch = 0`。 骨架不动,注意力自然落在变化的那块内容上。 ## ③ 一条我自己的误判(值得记下) 深色主题下我量到导航文字对比度只有 2.36,一度以为是变量/级联的问题,还写死了一份 深色字面值。**那是误判**:`.nav-item` 有 `transition: color .15s`,我在切主题后 **立刻**读 computed color,拿到的是过渡的**起点**(浅色值)。决定性证据是连内联 `style.color` 都"改不动"它 —— 级联不可能这样,只可能是还在过渡中。等 400ms 再量就正常。 写死的那份已撤掉,并在 CSS 里留下说明;新判据 `test/manual/nav-contrast-verify.mjs` 用 WCAG 比值量对比度(不是"颜色是不是黑的"),每次读之前等 400ms。 背景套件 32 条全绿(含"导航走令牌 + 两套令牌都在")。 --- client/electron/src/components/MailView.tsx | 11 +- client/electron/src/components/NarrowNav.tsx | 12 +- client/electron/src/components/Sidebar.tsx | 18 +-- client/electron/src/index.css | 117 ++++++++++++++++-- client/electron/test/background.test.mjs | 30 +++-- .../test/manual/nav-contrast-verify.mjs | 89 +++++++++++++ client/electron/test/narrow-layout.test.mjs | 55 +++++++- 7 files changed, 290 insertions(+), 42 deletions(-) create mode 100644 client/electron/test/manual/nav-contrast-verify.mjs diff --git a/client/electron/src/components/MailView.tsx b/client/electron/src/components/MailView.tsx index dac4bee..0299a0e 100644 --- a/client/electron/src/components/MailView.tsx +++ b/client/electron/src/components/MailView.tsx @@ -447,6 +447,7 @@ function Header({ onThread: () => void; }) { const time = new Date(mail.created_at).toLocaleString('zh-CN'); + const narrow = useIsNarrow(); // 发件/收件行显示**各方在这条会话里的完整地址**,人与 Agent 带的段数不同: // @@ -888,6 +889,11 @@ function ReplyBar({ if (!replyTo) return null; + // 判据是「当前登录用户名」而不是字面量 'human':后者是单用户时代的遗留, + // 多用户下登录名可能是 jianf,判据恒为假 → 对端取成自己 → 信发给自己。 + const peer = mailCounterpart(replyTo, me); + const target = overrideTarget || mailReplyTarget(replyTo, me); + // 窄屏收起态:一个悬浮球,点开才出现输入区。 // // 窄屏上「顶部邮件信息 + 底部输入框」同时常驻会把可读区压成一条缝(用户实测反馈)。 @@ -908,11 +914,6 @@ function ReplyBar({ ); } - // 判据是「当前登录用户名」而不是字面量 'human':后者是单用户时代的遗留, - // 多用户下登录名可能是 jianf,判据恒为假 → 对端取成自己 → 信发给自己。 - const peer = mailCounterpart(replyTo, me); - const target = overrideTarget || mailReplyTarget(replyTo, me); - const send = async () => { if (!body.trim()) return; setBusy(true); diff --git a/client/electron/src/components/NarrowNav.tsx b/client/electron/src/components/NarrowNav.tsx index 1b17961..b0db748 100644 --- a/client/electron/src/components/NarrowNav.tsx +++ b/client/electron/src/components/NarrowNav.tsx @@ -79,9 +79,8 @@ export default function NarrowNav() { @@ -98,11 +98,8 @@ export default function Sidebar() { key={short} onClick={() => setViewMode(target || commTab || modes[0])} title={title} - className={`relative w-12 h-12 rounded-lg flex flex-col items-center justify-center gap-0.5 transition-colors ${ - active - ? 'bg-chrome-700 text-white' - : 'text-chrome-400 hover:bg-chrome-800 hover:text-chrome-100' - }`} + data-active={active} + className="nav-item relative w-12 h-12 rounded-lg flex flex-col items-center justify-center gap-0.5" > {short} @@ -135,11 +132,8 @@ export default function Sidebar() {