diff --git a/src/components/EmailListPanel.tsx b/src/components/EmailListPanel.tsx index ef54476..0679442 100644 --- a/src/components/EmailListPanel.tsx +++ b/src/components/EmailListPanel.tsx @@ -20,6 +20,7 @@ import { useToast } from "@/components/ToastProvider"; import { useUnreadCount } from "@/components/UnreadCountProvider"; import UnreadCountBadge from "@/components/UnreadCountBadge"; import ThreadCountBadge from "@/components/ThreadCountBadge"; +import { useConfirmNavigation } from "@/components/NavigationGuardProvider"; import { usePathname, useRouter, useSearchParams } from "next/navigation"; import { Email } from "@/lib/types"; import { @@ -183,6 +184,7 @@ export default function EmailListPanel({ const pathname = usePathname(); const router = useRouter(); const searchParams = useSearchParams(); + const confirmNavigation = useConfirmNavigation(); const showToast = useToast(); const selectedThreadId = pathname.startsWith("/thread/") ? pathname.slice("/thread/".length) @@ -350,6 +352,14 @@ export default function EmailListPanel({ threadId: string, emailIds: string[], ) { + // Pointer capture is only needed for touch/pen swipe gestures. Capturing a + // mouse pointer can retarget the completed click to this wrapper instead + // of the nested conversation link, leaving desktop rows unopenable. + if (event.pointerType === "mouse") { + cancelLongPress(); + swipeGesture.current = null; + return; + } event.currentTarget.setPointerCapture(event.pointerId); swipeGesture.current = { threadId, @@ -1265,6 +1275,7 @@ export default function EmailListPanel({
finishRowPointer(thread, isUnread)} onPointerCancel={() => cancelRowPointer(thread.threadId)} + onClick={(event) => { + if (longPressActive.current) { + longPressActive.current = false; + return; + } + if ( + suppressLinkClick.current === thread.threadId + ) { + suppressLinkClick.current = null; + return; + } + if (selectionMode) return; + + const target = event.target; + if ( + target instanceof Element && + target.closest( + "a, button, [data-thread-selection-control]", + ) + ) { + return; + } + + if (!confirmNavigation()) return; + setKeyboardThreadId(thread.threadId); + router.push(threadHref); + }} > {/* Unread / pin indicator */}
@@ -1303,6 +1341,7 @@ export default function EmailListPanel({ {/* Avatar — morphs to checkbox on hover / in selection mode */}
{ if (!selectionMode) setSelectionMode(true); // Toggle all emails in this thread