From 2535b4ae5eb23bcb81224761b94fc3268c36af11 Mon Sep 17 00:00:00 2001 From: AnnaXWang <6621137+AnnaXWang@users.noreply.github.com> Date: Wed, 8 Jul 2026 22:47:56 +0000 Subject: [PATCH] Keep comment thread open when drag-selecting its text Clicking a comment card toggles the thread open/closed, but a click that ended a drag-to-highlight (selecting the comment body to copy) also fired the toggle and closed the thread. Distinguish a real click from a drag: skip the toggle when the pointer moved past a small threshold or text ended up selected within the card. Co-Authored-By: Claude Opus 4.8 --- app/d/[slug]/CommentsShell.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/d/[slug]/CommentsShell.tsx b/app/d/[slug]/CommentsShell.tsx index 89a542a..2ea8c16 100644 --- a/app/d/[slug]/CommentsShell.tsx +++ b/app/d/[slug]/CommentsShell.tsx @@ -1014,6 +1014,10 @@ const Card = forwardRef< ) { const [replyText, setReplyText] = useState(""); const [showEmoji, setShowEmoji] = useState(false); + // Pointer-down position, to tell a real click (toggle the thread) from a click + // that ended a drag-to-highlight (selecting the comment text to copy) — the + // latter must leave the thread open. See onClick below. + const downRef = useRef<{ x: number; y: number } | null>(null); const border = t.orphaned ? "1px dashed var(--jh-card-orphan-border, #d99)" @@ -1028,8 +1032,18 @@ const Card = forwardRef< ref={ref} onMouseEnter={onHoverIn} onMouseLeave={onHoverOut} + onMouseDown={(e) => { + downRef.current = { x: e.clientX, y: e.clientY }; + }} onClick={(e) => { if ((e.target as HTMLElement).closest("[data-no-pin]")) return; + // A click that ended a drag-to-highlight (e.g. selecting the comment body + // to copy) must not toggle the thread — it stays open until explicitly + // closed. A drag moves the pointer between press and release; a plain + // click doesn't, so pointer movement is what distinguishes the two. + const down = downRef.current; + downRef.current = null; + if (down && Math.hypot(e.clientX - down.x, e.clientY - down.y) > 4) return; onPin(); }} style={{