From d7a64fd9d6dbd6ee8fb5b9a04b0fde1534925c40 Mon Sep 17 00:00:00 2001 From: dealerweb Date: Mon, 6 Jul 2026 10:43:16 +0200 Subject: [PATCH] Fix: hide the spam action in Sent, Drafts and Scheduled Marking your own outgoing mail as spam makes no sense, but the action was offered in every non-junk folder: context menu, hover quick-actions, viewer toolbar and its overflow menu, plus the "!" shortcut. All surfaces now skip the action when the folder role is sent, drafts or scheduled, and the shortcut is a no-op there. Scheduled messages were already covered per-email via isScheduled; the role check additionally covers the server-side Scheduled folder before that annotation loads. The hover quick-actions bar gets a spamApplicable prop for this, since it renders its buttons without knowing the folder. --- app/(main)/[locale]/page.tsx | 4 +++ components/email/email-context-menu.tsx | 37 ++++++++++++++---------- components/email/email-hover-actions.tsx | 4 +++ components/email/email-list-item.tsx | 1 + components/email/email-viewer.tsx | 7 +++-- components/email/thread-list-item.tsx | 2 ++ 6 files changed, 38 insertions(+), 17 deletions(-) diff --git a/app/(main)/[locale]/page.tsx b/app/(main)/[locale]/page.tsx index 67699187..04d78eba 100644 --- a/app/(main)/[locale]/page.tsx +++ b/app/(main)/[locale]/page.tsx @@ -621,6 +621,10 @@ export default function Home() { onToggleSpam: async () => { if (isScheduledView) return; const currentMailbox = mailboxes.find(m => m.id === selectedMailbox); + // Marking your own outgoing mail as spam makes no sense - the toolbar + // and menus hide the action in Sent/Drafts/Scheduled, so the shortcut + // is a no-op there too. + if (['sent', 'drafts', 'scheduled'].includes(currentMailbox?.role || '')) return; const isInJunk = currentMailbox?.role === 'junk'; if (selectedEmailIds.size > 0 && client) { const ids = Array.from(selectedEmailIds); diff --git a/components/email/email-context-menu.tsx b/components/email/email-context-menu.tsx index 83a4b4de..53ae2eac 100644 --- a/components/email/email-context-menu.tsx +++ b/components/email/email-context-menu.tsx @@ -153,6 +153,9 @@ export function EmailContextMenu({ const currentColors = getCurrentColors(email.keywords); const showBatchActions = isMultiSelect && selectedCount > 1; const isInJunkFolder = currentMailboxRole === 'junk'; + // Marking your own outgoing mail as spam makes no sense - hide the action + // in Sent, Drafts and Scheduled. + const spamApplicable = !['sent', 'drafts', 'scheduled'].includes(currentMailboxRole || ''); const isScheduled = email.isScheduled === true; const canCancelScheduled = isScheduled && email.scheduledUndoStatus === 'pending'; @@ -385,22 +388,26 @@ export function EmailContextMenu({ )} - + {/* Spam - contextual based on folder; pointless on own outgoing mail */} + {spamApplicable && ( + <> + - {/* Spam - contextual based on folder */} - - handleAction( - showBatchActions - ? (isInJunkFolder ? onBatchUndoSpam! : onBatchMarkAsSpam!) - : (isInJunkFolder ? onUndoSpam! : onMarkAsSpam!) - ) - } - disabled={showBatchActions ? (isInJunkFolder ? !onBatchUndoSpam : !onBatchMarkAsSpam) : (isInJunkFolder ? !onUndoSpam : !onMarkAsSpam)} - destructive={!isInJunkFolder} - /> + + handleAction( + showBatchActions + ? (isInJunkFolder ? onBatchUndoSpam! : onBatchMarkAsSpam!) + : (isInJunkFolder ? onUndoSpam! : onMarkAsSpam!) + ) + } + disabled={showBatchActions ? (isInJunkFolder ? !onBatchUndoSpam : !onBatchMarkAsSpam) : (isInJunkFolder ? !onUndoSpam : !onMarkAsSpam)} + destructive={!isInJunkFolder} + /> + + )} diff --git a/components/email/email-hover-actions.tsx b/components/email/email-hover-actions.tsx index 4e465fe7..7bb4a734 100644 --- a/components/email/email-hover-actions.tsx +++ b/components/email/email-hover-actions.tsx @@ -21,6 +21,8 @@ interface EmailHoverActionsProps { // the spam quick-action flips to "not spam". isInJunk?: boolean; onUndoSpam?: () => void; + // Hidden where marking spam is meaningless for self-authored mail (Drafts, Sent). + spamApplicable?: boolean; } const ACTION_CONFIG: Record state.hoverActions); const hoverActionsMode = useSettingsStore((state) => state.hoverActionsMode); @@ -121,6 +124,7 @@ export function EmailHoverActions({ const actionButtons = hoverActions.map((actionId) => { const config = ACTION_CONFIG[actionId]; if (!config) return null; + if (actionId === "spam" && !spamApplicable) return null; const Icon = config.icon; // In a junk context the spam action becomes "not spam". diff --git a/components/email/email-list-item.tsx b/components/email/email-list-item.tsx index 27fb5c64..faabb6a2 100644 --- a/components/email/email-list-item.tsx +++ b/components/email/email-list-item.tsx @@ -338,6 +338,7 @@ export function EmailListItem({ email, selected, onClick, onDoubleClick, onConte onMarkAsSpam={onMarkAsSpam} onUndoSpam={onUndoSpam} isInJunk={currentMailboxRole === 'junk'} + spamApplicable={!['sent', 'drafts', 'scheduled'].includes(currentMailboxRole || '')} /> ); diff --git a/components/email/email-viewer.tsx b/components/email/email-viewer.tsx index 31f5d982..76ec3c50 100644 --- a/components/email/email-viewer.tsx +++ b/components/email/email-viewer.tsx @@ -693,6 +693,9 @@ export function EmailViewer({ // Detect if current mailbox is Junk folder const isInJunkFolder = currentMailboxRole === 'junk'; + // Marking your own outgoing mail as spam makes no sense - hide the action + // in Sent, Drafts and Scheduled. + const spamApplicable = !['sent', 'drafts', 'scheduled'].includes(currentMailboxRole || ''); // Detect if the email is a draft const isDraft = email?.keywords?.['$draft'] === true; @@ -2922,7 +2925,7 @@ export function EmailViewer({ {/* Spam */} - {(onMarkAsSpam || onUndoSpam) && ( + {spamApplicable && (onMarkAsSpam || onUndoSpam) && (