fix(V0.2): 二轮评审 6 项 —— BUILD_ID 格式 / 菜单与详情精简 / 拖动重做 / 键盘统一方案
Docker Build and Push / build-image (push) Successful in 4m5s
Docker Build and Push / build-image (push) Successful in 4m5s
1. BUILD_ID 改为 yyyyMMddHHmmss (去掉中间点), 仍 UTC+8
2. 任务 ⋯ 菜单去掉顶部任务名标题
3. 任务详情去掉底部「拷贝到其他项目」「删除任务」按钮 (⋯ 菜单已有)
4+6. 键盘遮挡统一方案 (重点设计 §7.2):
- index.html 加 interactive-widget=resizes-content
- App 级 useKeyboardInsetWatcher 写 --kb-inset (visualViewport+window 双源)
- 底部弹层统一 .kb-safe 类 (安全区+20px+键盘插入量, dvh 收缩+内部滚动)
- TaskDetail/UserPicker/CopyTaskPopup/信息块弹层全部迁移, 删除 per-component hook
- 信息块 textarea 补 focus scrollIntoView 兜底
5. 拖动方案重做 (重点设计 §7.1):
- 新 useColumnDrag: Pointer Events + setPointerCapture, 长按400ms原位抬起,
elementFromPoint 高亮目标列, 边缘 rAF 自动横滚; 移除手指跟随浮层(任务名)
- 列表行长按 500ms → 「移动到列」ActionSheet (不做自由拖动)
- 移除「拖到卡片转子任务」误触路径, 统一走详情页层级区
- 删除旧 useLongPressDrag
已验证: 99 文件语法 0 错误、导入 0 缺失
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
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')
|
||||
}
|
||||
}, [])
|
||||
}
|
||||
Reference in New Issue
Block a user