fix(V0.2): 拖动可靠性重做 —— 把手入口 + 打卡排序接入实际渲染视图
Docker Build and Push / build-image (push) Successful in 1m1s

问题定位:
- 打卡页实际渲染的是 MergedView (CheckinPage 路由), 上次改的 HabitView
  是未使用的旧组件, 打包时被 tree-shake, 线上自然无任何效果
- 任务列表长按抬起后一动即脱手: touch-action:pan-y 下手指出现纵向分量,
  WebView/渲染器直接把触摸判给滚动并 pointercancel, touchmove preventDefault
  拦不住已决定的滚动 (看板可用只因该模式下页面无纵向可滚祖先)

修复:
- 新增 ⠿ 拖动把手 (touch-action:none): 浏览器按规范完全不接管该触摸,
  按下立即拖动, CDP 触摸仿真验证: 垂直拖动穿过可滚列表正常落点,
  跨组(每天/每周/每月)正确拒绝; 任务行把手拖动换列, 打卡卡片把手组内排序
- useRowDrag/useHabitDrag 抽出 armListeners, 新增 bindHandle 立即激活路径
- MergedView: 组内排序改按 sortOrder (服务端已返回), 拖动落位乐观更新 +
  POST /checkin/habits/reorder, 失败回滚; 打卡点击加拖动余波保护
- 长按路径保留为补充入口 (不可滚场景仍可用)
This commit is contained in:
jif2.zhang
2026-10-25 01:21:42 +08:00
parent b1c1b16e66
commit 2725f00f68
6 changed files with 595 additions and 479 deletions
+19
View File
@@ -678,6 +678,25 @@ body.me-safe-top .app-safe-top { height: 0; }
.habit-card.dragover.after { border-bottom: 3px solid var(--color-primary); }
.habit-card.dragover.before { border-top: 3px solid var(--color-primary); }
/* 拖动把手 (⠿): touch-action:none —— 浏览器完全不接管该触摸,
指针流不会被滚动抢占取消, 是 Android WebView 上唯一可靠的拖动入口 */
.grip {
touch-action: none; -webkit-user-select: none; user-select: none;
color: #c2c7cf; font-size: 14px; line-height: 1; padding: 8px 2px;
cursor: grab; flex-shrink: 0; align-self: center;
}
.grip:active { color: var(--color-primary); }
.task-right .grip { margin-right: 2px; }
/* MergedView 打卡卡拖动排序 */
.mv-view { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.mv-view input, .mv-view textarea { -webkit-user-select: text; user-select: text; }
.mv-card { touch-action: pan-y; }
.mv-card.dragging { opacity: .55; outline: 2px dashed var(--color-primary); outline-offset: 1px; }
.mv-card.dragover { outline: 2px solid var(--color-primary); outline-offset: 1px; }
.mv-card.dragover.after { border-bottom: 3px solid var(--color-primary); }
.mv-card.dragover.before { border-top: 3px solid var(--color-primary); }
/* ----- 日历视图 ----- */
.calendar-view { padding: 0 12px 20px; }
.cal-month-bar { display: flex; align-items: center; gap: 10px; padding: 8px 2px; }