เลือก annotation บนหน้า PDF → sidebar ตามไปเน้นรายการนั้น + สร้างเสร็จเลือกให้ทันที + กัน duplicate ชั่วขณะตอนสร้าง: (1) ส่ง selectedId ให้ AnnotationSidebar — ไฮไลต์แถว (ทั้งลิสต์หลักและผลค้นหา) + scrollIntoView block:nearest + สลับมาแท็บ Annotations ให้เองถ้ากำลังอยู่ Bookmarks (rAF รอแถว render หลังสลับแท็บค่อยเลื่อน) (2) AUTO_SELECT_TYPES — สร้าง DRAW/SHAPE/TEXTBOX/STAMP/HIGHLIGHT/REDACTION เสร็จ = เลือกตัวใหม่ทันทีด้วย saved.id (กรอบ selection + sidebar ตามไปเลย; COMMENT ยกเว้นเพราะ composer/pin ทำหน้าที่นั้นอยู่แล้ว) — แก้ปัญหา "วาดเสร็จคลิกที่เส้น tool ยังเป็นวาด sidebar นิ่ง" (3) กันอาการ row โผล่แล้วหาย (0→2→1): เดิม optimistic row กับ row จาก server คนละ id ทำให้ SSE event มาก่อน action เสร็จ dedupe ไม่ได้ — ตอนนี้ client ส่ง id ของ optimistic row ให้ createAnnotation ใช้ซ้ำ (validate UUID, ไม่ส่ง = สุ่มเองตามเดิมสำหรับ redo path) ทุกชั้น dedupe ด้วย id เดียวกันตั้งแต่แรก — sync PLAN.md §4 + rules/realtime.md ให้ตรงพฤติกรรมใหม่
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
parent
4934b9d0b3
commit
6ddc35d6d5
5 changed files with 67 additions and 12 deletions
|
|
@ -366,6 +366,17 @@ const TOOLS: { key: Tool; label: string; Icon: LucideIcon }[] = [
|
|||
{ key: "stamp", label: "ตรายาง (stamp)", Icon: Stamp },
|
||||
];
|
||||
|
||||
/** ชนิดที่สร้างเสร็จแล้วเลือกรายการใหม่ให้อัตโนมัติ (กรอบ selection + sidebar ไฮไลต์)
|
||||
* ทุกชนิดยกเว้น COMMENT — เปิด composer พิมพ์ก่อนบันทึก และคลิก pin = เลือกอยู่แล้ว */
|
||||
const AUTO_SELECT_TYPES = new Set<AnnotationType>([
|
||||
"DRAW",
|
||||
"SHAPE",
|
||||
"TEXTBOX",
|
||||
"STAMP",
|
||||
"HIGHLIGHT",
|
||||
"REDACTION",
|
||||
]);
|
||||
|
||||
/** cursor รูปยางลบของ tool erase — SVG inline สไตล์ lucide (path เดียวกับ icon บน
|
||||
* แถบ tool) hotspot ที่ปลายยางมุมล่างซ้าย = จุดที่ใช้ลบจริง */
|
||||
const ERASER_CURSOR = `url("data:image/svg+xml,${encodeURIComponent(
|
||||
|
|
@ -1550,6 +1561,7 @@ export default function PDFViewer({
|
|||
applyAnnotation({ kind: "add", row: temp });
|
||||
try {
|
||||
const saved = await createAnnotation({
|
||||
id: temp.id, // ใช้ id เดียวกับ optimistic row — กัน duplicate ชั่วขณะ (row โผล่แล้วหาย)
|
||||
fileId: file.id,
|
||||
pageIndex,
|
||||
userId: user.userId,
|
||||
|
|
@ -1566,6 +1578,12 @@ export default function PDFViewer({
|
|||
setAnnotations((prev) =>
|
||||
prev.some((a) => a.id === saved.id) ? prev : [...prev, saved],
|
||||
);
|
||||
// สร้าง "วัตถุ" เสร็จ = เลือกตัวใหม่ทันที (ใช้ id จาก server — id ชั่วคราวของ
|
||||
// optimistic row ถูกถอดตอน transition จบ เลือก id นั้นไฮไลต์จะหายเอง)
|
||||
if (AUTO_SELECT_TYPES.has(type)) {
|
||||
setSelectedId(saved.id);
|
||||
setPreviewData(null);
|
||||
}
|
||||
// F2: undo ของ create = ลบ id ปัจจุบัน; redo = สร้างใหม่ (id ใหม่) แล้วส่งต่อให้ undo รอบถัดไป
|
||||
let currentId = saved.id;
|
||||
pushHistory({
|
||||
|
|
@ -2400,6 +2418,7 @@ export default function PDFViewer({
|
|||
onUpdateBookmark={(id, patch) => void handleUpdateBookmark(id, patch)}
|
||||
onGoToBookmark={goToBookmark}
|
||||
onGoToAnnotation={goToAnnotation}
|
||||
selectedId={selectedId}
|
||||
/>
|
||||
</aside>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue