ไฮไลต์เสร็จแล้ว popup ซ้อนกันอีก 2 รูปแบบ (tooltip ทับแผงบน desktop + เมนู tool ค้างเปิดบน iOS) + งาน TEMP-DEBUG ของปัญหา pencil ลากไม่ติดบน iPad:
All checks were successful
Deploy eCourt Note Web to Server / Validate Database Schema (Drizzle) (push) Successful in 3s
Deploy eCourt Note Web to Server / Build Web Docker Image (push) Successful in 44s
Deploy eCourt Note Web to Server / Deploy eCourt Note Web to Server (push) Successful in 13s
Deploy eCourt Note Web to Server / Notify Deployment Status (push) Successful in 0s

ส่วนที่ 1 — แก้ popup ซ้อนตอนสร้างไฮไลต์ (bug report: กด tool highlight → ไป highlight → เสร็จแล้วมี popup ของแก้ไขแสดงอีกอัน):
(1) Tooltip hover (N1) ซ่อนเมื่อรายการที่ชี้ = selectedId — เดิมลากคลุมจบแล้วเคอร์เซอร์ยังอยู่บนไฮไลต์ใหม่พอดี auto-select เปิดแผง selection แล้ว tooltip ยังโผล่ซ้อนอีกกล่องบนตำแหน่งเดียวกัน; ชี้รายการอื่นที่ไม่ได้เลือก tooltip ยังทำงานตามเดิม
(2) handleCreateAnnotation ตรง branch AUTO_SELECT_TYPES ปิดเมนู dropdown ทั้ง 5 + popup bookmark ก่อนแผงโผล่ — บน iOS การลาก (คลุมข้อความ/วาดเส้น) ไม่ยิง compat mousedown ให้ outside-click ปิดเมนูเอง (Android/desktop ปิดตั้งแต่เริ่มกดแล้ว) ไม่ปิดตรงนี้ = เมนูค้างเปิดซ้อนแผงบนจอสัมผัส
- sync rules/pdf-viewer.md: กติกา popup ทีละชุดเพิ่มกรณี auto-select ปิดเมนู + เงื่อนไขซ่อน tooltip เมื่อ hovered = selectedId
- verify: tsc ผ่าน + Playwright 6/6 — desktop: ไฮไลต์เสร็จแผงโผล่/ไม่มี tooltip ซ้อน/ชี้รายการอื่น tooltip กลับมา; เลียน iOS (dispatch touch PointerEvent ล้วนไม่มี compat mousedown): ลากคลุม commit จริง + แผงโผล่ + เมนูที่เคยเปิดค้างถูกปิด

ส่วนที่ 2 — TEMP-DEBUG ปัญหา pencil ลากแล้วบางทีไม่ commit บน iPad (ทำคู่กันระหว่าง debug จริงเครื่อง ยังไม่ถึงเวลาเก็บกวาด):
- components/DebugConsole.tsx (ใหม่): เปิด Eruda จาก CDN เมื่อ URL มี ?debug — อ่าน console บนจอ iPad จริงโดยไม่ต้องต่อ Safari Web Inspector (โหลดพลาดมีแบนเนอร์แจ้ง) + mount ใน app/annotate/[id]/page.tsx — ทั้งคู่ mark TEMP-DEBUG ไว้ลบพร้อมกัน
- hooks/useCustomSelection.ts: log [debug] ตำแหน่งสำคัญของ gesture (pointerdown / move แรกของ pointerId นั้นหลัง down — กัน log 60-120Hz ท่วม console จนเปลี่ยนพฤติกรรมที่ดูอยู่เอง / แยก pointerup vs pointercancel / นิ้วที่สองถูกเมิน) + เก็บความเห็นใหม่ว่า guard นิ้วที่สองครอบคลุม touch ปลอมจาก palm rejection (มือพักบนจอระหว่างลากด้วย pen)
- components/UploadFileForm.tsx: ปุ่มอัปโหลด ml-auto ชิดขวา (เดิมติด input ไปฝั่งซ้าย)

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2026-09-15 15:10:27 +07:00
parent 9cc38835f0
commit 5c8e52bd62
6 changed files with 92 additions and 7 deletions

View file

@ -524,8 +524,26 @@ export function useCustomSelection({
scrollRafRef.current = requestAnimationFrame(step);
};
/** TEMP-DEBUG: เก็บ pointerId ที่เคย log move แรกแล้ว — ทำลายทุก pointerdown
* ใหม่ (กัน hover ของ pencil กินสล็อต "move แรก" ก่อนปากกาแตะจอ) */
const seenMovePointerIds = new Set<number>();
const onPointerDown = (e: PointerEvent) => {
if (dragRef.current) return; // นิ้วที่สองระหว่างลาก — ไม่สน
console.warn("[debug] pointerdown", {
pointerType: e.pointerType,
clientX: e.clientX,
clientY: e.clientY,
}); // TEMP-DEBUG
seenMovePointerIds.clear(); // TEMP-DEBUG
if (dragRef.current) {
// นิ้วที่สองระหว่างลาก — ไม่สน รวมถึง touch ปลอมจาก palm rejection (มือ
// ที่พักบนจอระหว่างลากด้วย pen) — ห้ามให้ pointer ตัวใหม่แทนที่ drag เดิม
console.warn("[debug] ignored second pointer", {
activeType: dragRef.current.pointerType,
newType: e.pointerType,
}); // TEMP-DEBUG
return;
}
// เริ่ม selection ได้เฉพาะที่เริ่มบน textLayer (แตะ pin/ปุ่ม/กล่องข้อความ = งานของมัน)
if (
!(e.target instanceof Element) ||
@ -581,6 +599,17 @@ export function useCustomSelection({
};
const onPointerMove = (e: PointerEvent) => {
// TEMP-DEBUG: log เฉพาะ move แรกของ pointer หลัง pointerdown ล่าสุด —
// pen/touch ยิง 60–120Hz ถ้า log ทุก event จะท่วม console และหน่วงเครื่อง
// จนเปลี่ยนพฤติกรรมที่กำลังวินิจฉัยอยู่เอง
if (!seenMovePointerIds.has(e.pointerId)) {
seenMovePointerIds.add(e.pointerId);
console.warn("[debug] pointermove (แรกของ pointer นี้หลัง down)", {
pointerType: e.pointerType,
pointerId: e.pointerId,
hasActiveDrag: !!dragRef.current,
}); // TEMP-DEBUG
}
const d = dragRef.current;
if (!d || e.pointerId !== d.pointerId) return;
d.curPt = { x: e.clientX, y: e.clientY };
@ -605,6 +634,12 @@ export function useCustomSelection({
/** เคลียร์ state ทุกทาง — commit เฉพาะตอน pointerup ที่มี range ไม่ collapsed
* (pointercancel จาก gesture ของระบบ = ทิ้ง selection ไม่ commit) */
const finish = (e: PointerEvent, commit: boolean) => {
// TEMP-DEBUG: แยก pointerup กับ pointercancel — cancel = ระบบยึด gesture ไป
// (คู่สมมติฐานหลักของ "ลากไม่ติด" บน pencil นอกเหนือจาก move ไม่มาถึง)
console.warn(`[debug] ${commit ? "pointerup" : "pointercancel"}`, {
pointerType: e.pointerType,
pointerId: e.pointerId,
}); // TEMP-DEBUG
const d = dragRef.current;
if (!d || e.pointerId !== d.pointerId) return;
stopAutoScroll();