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({