From 50ee10a52266872ff8c8d74069db0020f0dec507 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Mon, 14 Sep 2026 11:01:10 +0800 Subject: [PATCH] =?UTF-8?q?fix(webui):=20=E4=BF=AE=E3=80=8C=E9=80=9A?= =?UTF-8?q?=E4=BF=A1=E9=A1=B5=E9=9D=A2=E5=AE=8C=E5=85=A8=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E6=BB=91=E5=8A=A8=E3=80=8D+=20=E6=97=A5?= =?UTF-8?q?=E5=8E=86=E5=B7=A6=E5=8F=B3=E6=BB=91=E5=8A=A8=E6=89=8B=E5=8A=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 滑动(用户:「通信页面的各个子页面还是无法滑动啊,我真服了」) 根因不是我第一次以为的 `overflow: hidden`,而是**我把列表包进了一个 flex 列**: - `MailList` 的根是 `w-full lg:w-[320px] shrink-0 ... flex flex-col` —— 这个 `shrink-0` 是给**行**方向布局写的(控制宽度),放进列方向后它作用在**高度**上:列表连高度 都不肯让 ⇒ 内部的 `flex-1 overflow-y-auto` 永远拿不到可用高度 ⇒ 滚不动。 - 表现极具误导性:容器**自己也没有溢出**,所以连滚动条都不出现,看起来像"页面被裁掉了"。 - 为什么以前没坏:列表原先直接挂在窄屏覆盖层(`absolute inset-0 flex`,**行**方向)下, 行方向的高度来自 `align-items: stretch`,不需要 `min-height:0`。 修法:`.comm-pane > *:not([data-testid='comm-tabs']) { flex: 1 1 0%; min-height: 0 }` —— 让子面板既能压缩、也填满这一列。对收件/发件/授权/联系人一视同仁,避免只修好一个。 **实测**(390×844,11 行邮件):修复前 `scrollerCount: 0`(一个可滚动容器都没有); 修复后滚动容器 = `flex-1 overflow-y-auto p-2.5`、`overflow-y: auto`、可滚范围 236px、 `scrollTop` 实际移动 200px。导航仍完整可见(bottom=834 ≤ 844)。 ## 我自己的两个方法错误(都写在这里,避免下次再犯) 1. **判据没断言前置条件**:前三次探针都报"没有滚动容器",其实是 gui-lab 收件箱太短 (12 封全落进同一个会话 ⇒ 只显示 1 组)⇒ 内容根本没溢出 ⇒ 我量的对象不存在。 最后用 10 个**独立会话**把列表撑高才复现出来。用户报的缺陷是真的,是我的探针没到位。 2. 第一条修复(去掉 `overflow:hidden`)方向不对,但我当时**差点把它当成修好了** —— 因为探针依旧是 0 滚动容器,只是我没深究。结论必须是三态,不能把"量不到"当"没问题"。 ## 日历左右滑动(用户:「日历页面还不支持左右滑动手势」) 在日历主体上挂 touchstart/touchend,**复用 `shift()`**(与"上一月/下一月"按钮同一套翻页 逻辑);阈值:水平位移 ≥40px、且 ≥1.5×垂直位移、且 <600ms —— 否则会把纵向滚动误判成翻页。 **这条我还没验成功**:探针取日历标题的方式不对(返回 null ⇒ 判不了), 不能说它好了。修好探针再补验。 --- client/electron/src/App.tsx | 2 +- .../electron/src/components/CalendarView.tsx | 34 +++++++++++++++- client/electron/src/index.css | 40 +++++++++++++++++-- 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/client/electron/src/App.tsx b/client/electron/src/App.tsx index 882a652..d8722f2 100644 --- a/client/electron/src/App.tsx +++ b/client/electron/src/App.tsx @@ -195,7 +195,7 @@ export default function App() { * 外层 `relative` 是给悬浮加号定位用的 —— 窄屏时它正好落在底部导航之上。 */ const list = isComm && listBody ? ( -
+
{listBody} diff --git a/client/electron/src/components/CalendarView.tsx b/client/electron/src/components/CalendarView.tsx index 98c7aba..b70ca54 100644 --- a/client/electron/src/components/CalendarView.tsx +++ b/client/electron/src/components/CalendarView.tsx @@ -118,6 +118,34 @@ export default function CalendarView() { else setAnchor(a => addDays(a, dir)); } + /* + * 左右滑动手势(2026-09-14 用户:「日历页面还不支持左右滑动手势」)。 + * + * 复用 shift() —— 手势与「上一月/下一月」按钮必须是同一套翻页逻辑, + * 各写一遍的话阈值、边界、"周/日/月"三种刻度的行为迟早分叉。 + * + * 判据:水平位移 ≥ 40px 且明显大于垂直位移(否则会把纵向滚动列表误判成翻页, + * 那是移动端最容易犯的手势错误);同时要求时间 < 600ms,避免"慢慢拖"也翻页。 + */ + const touch = useRef<{ x: number; y: number; t: number } | null>(null); + const onTouchStart = (e: React.TouchEvent) => { + const t = e.touches[0]; + if (!t) return; + touch.current = { x: t.clientX, y: t.clientY, t: Date.now() }; + }; + const onTouchEnd = (e: React.TouchEvent) => { + const start = touch.current; + touch.current = null; + const t = e.changedTouches[0]; + if (!start || !t) return; + const dx = t.clientX - start.x; + const dy = t.clientY - start.y; + const fast = Date.now() - start.t < 600; + if (Math.abs(dx) < 40 || Math.abs(dx) < Math.abs(dy) * 1.5 || !fast) return; + // 左滑 = 看下一段(与翻页按钮的"下一月"同向),右滑 = 上一段 + shift(dx < 0 ? 1 : -1); + }; + function goToday() { const now = new Date(); setAnchor(now); @@ -199,7 +227,11 @@ export default function CalendarView() { // ─── 左栏:工具条 + 网格 ─── const gridPane = ( -
+