fix(V0.2): 三轮反馈 5 项 —— 回滚键盘方案 / 列表卡片拖动 / 看板防误触 / 横滑整屏 / 详情页恢复
Docker Build and Push / build-image (push) Successful in 4m9s

1. 回滚键盘遮挡统一方案 (真机测试不通过, 需求搁置): 恢复 TaskDetail/
   UserPicker/CopyTaskPopup/ProjectManage 与 useKeyboardInset 到 9fea1a5^,
   删除 useKeyboardInsetWatcher / .kb-safe / interactive-widget=resizes-content
2. 任务详情页样式随 1 一并恢复提交前状态 (含底部拷贝/删除按钮)
3. 列表视图换列改为卡片拖动: 新 useRowDrag (长按 400ms 行抬起, 左右
   80px/列步进, 行尾徽标显示目标列, 松手落列), 移除长按 ActionSheet
   —— 旧长按与复选框/行点击互相误触, 抬手合成 click 落在控件上触发状态切换
4. 看板拖动防误触: 任务区禁长按文字选择与系统菜单 (输入框除外);
   pointercancel 只放弃不提交; 拖动结束 350ms 内抑制 click 误开详情;
   状态点/⋯/子任务行 pointerdown 不冒泡, 不发起拖动
5. 看板横滑扩展到整屏: .page-transition 补 height:100% 打通
   app-main → page-with-navbar 百分比链, board-wrap 撑满剩余高度

已验证: kb-safe/Watcher/onLongPress 残留引用清零, 逐文件 diff 审阅通过;
本机无 Node 运行时, 未跑 vite build
This commit is contained in:
jif2.zhang
2026-10-24 23:24:31 +08:00
parent 9fea1a5a3a
commit d6ca7573f3
16 changed files with 285 additions and 148 deletions
+27
View File
@@ -0,0 +1,27 @@
import { useEffect, useState } from 'react'
// 键盘弹出时的"插入量": window.innerHeight 与 visualViewport.height 的差
// Android WebView 键盘弹出时 visualViewport 变小; 用它把底部弹层的内容抬到键盘上方,
// 避免输入框(如任务详情里的"添加子任务")被键盘遮挡。
// 阈值 90px 过滤掉地址栏收起之类的轻微抖动; 无 visualViewport 时恒为 0 (iOS 原生键盘通常整体缩放, 无需处理)。
export default function useKeyboardInset() {
const [inset, setInset] = useState(0)
useEffect(() => {
const vv = window.visualViewport
if (!vv) return
const onChange = () => {
const diff = window.innerHeight - vv.height - vv.offsetTop
setInset(diff > 90 ? Math.round(diff) : 0)
}
vv.addEventListener('resize', onChange)
vv.addEventListener('scroll', onChange)
onChange()
return () => {
vv.removeEventListener('resize', onChange)
vv.removeEventListener('scroll', onChange)
}
}, [])
return inset
}
-35
View File
@@ -1,35 +0,0 @@
import { useEffect } from 'react'
// 键盘遮挡统一方案 (重点设计 §7.2):
// 全局唯一监听器, 把键盘插入量写入 CSS 变量 --kb-inset (0 或 px 字符串),
// 任何底部弹层只要挂 .kb-safe 类即可被抬到键盘上方, 组件不再各自接键盘逻辑。
// 信号源 (双保险):
// 1) visualViewport 的 resize/scroll —— Android WebView 键盘弹出时它先变小
// 2) window resize —— 配合 index.html 的 interactive-widget=resizes-content,
// Chromium 系 WebView 会整体收缩布局视口
// 基线: 记录见过的最大视口高 (键盘收起时), 避免"弹出键盘后基线被拉低"的漂移。
export default function useKeyboardInsetWatcher() {
useEffect(() => {
const root = document.documentElement
const vv = window.visualViewport
let maxH = window.innerHeight
const calc = () => {
const h = vv ? vv.height : window.innerHeight
if (h > maxH) maxH = h
const inset = Math.max(0, Math.round(maxH - h - (vv ? vv.offsetTop : 0)))
root.style.setProperty('--kb-inset', inset > 90 ? inset + 'px' : '0px')
}
calc()
window.addEventListener('resize', calc)
vv?.addEventListener('resize', calc)
vv?.addEventListener('scroll', calc)
return () => {
window.removeEventListener('resize', calc)
vv?.removeEventListener('resize', calc)
vv?.removeEventListener('scroll', calc)
root.style.setProperty('--kb-inset', '0px')
}
}, [])
}