From bbf724d9e1e2eff8d4a3c7fbff8e6af22129afa2 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Thu, 2 Apr 2026 22:50:04 +0200 Subject: [PATCH] fix: correct logic for marking email as read in EmailViewer component --- components/email/email-hover-actions.tsx | 2 +- components/email/email-viewer.tsx | 23 +++++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/components/email/email-hover-actions.tsx b/components/email/email-hover-actions.tsx index 7c17334d..00423f6b 100644 --- a/components/email/email-hover-actions.tsx +++ b/components/email/email-hover-actions.tsx @@ -94,7 +94,7 @@ export function EmailHoverActions({ onToggleStar?.(); break; case "markRead": - onMarkAsRead?.(!isUnread); + onMarkAsRead?.(isUnread); break; case "archive": onArchive?.(); diff --git a/components/email/email-viewer.tsx b/components/email/email-viewer.tsx index 4e72a70f..fff3ed9a 100644 --- a/components/email/email-viewer.tsx +++ b/components/email/email-viewer.tsx @@ -1152,9 +1152,27 @@ export function EmailViewer({ } ); + const autoMarkedEmailRef = useRef(null); + + // Reset auto-mark tracking when email changes + useEffect(() => { + autoMarkedEmailRef.current = null; + }, [email?.id]); + useEffect(() => { // Mark as read when email is viewed, respecting the delay setting - if (!email || email.keywords?.$seen || !onMarkAsRead) { + if (!email || !onMarkAsRead) { + return; + } + + // Already read — record that so manual unread toggle won't re-trigger auto-mark + if (email.keywords?.$seen) { + autoMarkedEmailRef.current = email.id; + return; + } + + // Don't re-trigger if we already auto-marked this email (user may have toggled it back to unread) + if (autoMarkedEmailRef.current === email.id) { return; } @@ -1167,17 +1185,18 @@ export function EmailViewer({ // Instant mark if (markAsReadDelay === 0) { + autoMarkedEmailRef.current = email.id; onMarkAsRead(email.id, true); return; } // Delayed mark const timeout = setTimeout(() => { + autoMarkedEmailRef.current = email.id; onMarkAsRead(email.id, true); }, markAsReadDelay); return () => clearTimeout(timeout); - // eslint-disable-next-line react-hooks/exhaustive-deps -- email?.id changes when email changes, which is the intended trigger }, [email?.id, email?.keywords?.$seen, onMarkAsRead]); // Reset external content permission and quick reply when email changes