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.
This commit is contained in:
@@ -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({
|
||||
</ContextMenuSubMenu>
|
||||
)}
|
||||
|
||||
<ContextMenuSeparator />
|
||||
{/* Spam - contextual based on folder; pointless on own outgoing mail */}
|
||||
{spamApplicable && (
|
||||
<>
|
||||
<ContextMenuSeparator />
|
||||
|
||||
{/* Spam - contextual based on folder */}
|
||||
<ContextMenuItem
|
||||
icon={isInJunkFolder ? ShieldCheck : ShieldAlert}
|
||||
label={isInJunkFolder ? t("not_spam") : t("mark_as_spam")}
|
||||
onClick={() =>
|
||||
handleAction(
|
||||
showBatchActions
|
||||
? (isInJunkFolder ? onBatchUndoSpam! : onBatchMarkAsSpam!)
|
||||
: (isInJunkFolder ? onUndoSpam! : onMarkAsSpam!)
|
||||
)
|
||||
}
|
||||
disabled={showBatchActions ? (isInJunkFolder ? !onBatchUndoSpam : !onBatchMarkAsSpam) : (isInJunkFolder ? !onUndoSpam : !onMarkAsSpam)}
|
||||
destructive={!isInJunkFolder}
|
||||
/>
|
||||
<ContextMenuItem
|
||||
icon={isInJunkFolder ? ShieldCheck : ShieldAlert}
|
||||
label={isInJunkFolder ? t("not_spam") : t("mark_as_spam")}
|
||||
onClick={() =>
|
||||
handleAction(
|
||||
showBatchActions
|
||||
? (isInJunkFolder ? onBatchUndoSpam! : onBatchMarkAsSpam!)
|
||||
: (isInJunkFolder ? onUndoSpam! : onMarkAsSpam!)
|
||||
)
|
||||
}
|
||||
disabled={showBatchActions ? (isInJunkFolder ? !onBatchUndoSpam : !onBatchMarkAsSpam) : (isInJunkFolder ? !onUndoSpam : !onMarkAsSpam)}
|
||||
destructive={!isInJunkFolder}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
<ContextMenuSeparator />
|
||||
|
||||
|
||||
@@ -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<HoverAction, {
|
||||
@@ -78,6 +80,7 @@ export function EmailHoverActions({
|
||||
onMarkAsSpam,
|
||||
isInJunk = false,
|
||||
onUndoSpam,
|
||||
spamApplicable = true,
|
||||
}: EmailHoverActionsProps) {
|
||||
const hoverActions = useSettingsStore((state) => 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".
|
||||
|
||||
@@ -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 || '')}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -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({
|
||||
</div>
|
||||
|
||||
{/* Spam */}
|
||||
{(onMarkAsSpam || onUndoSpam) && (
|
||||
{spamApplicable && (onMarkAsSpam || onUndoSpam) && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
@@ -3156,7 +3159,7 @@ export function EmailViewer({
|
||||
</div>
|
||||
)}
|
||||
{/* Overflow: spam */}
|
||||
{(onMarkAsSpam || onUndoSpam) && (
|
||||
{spamApplicable && (onMarkAsSpam || onUndoSpam) && (
|
||||
<button
|
||||
onClick={() => { (isInJunkFolder ? onUndoSpam : onMarkAsSpam)?.(); setMoreMenuOpen(false); setMoreMenuSub(null); }}
|
||||
className={cn("w-full px-3 py-1.5 text-sm text-left hover:bg-muted text-foreground flex items-center gap-2", hiddenPriorities.has(7) ? "" : "sm:hidden")}
|
||||
|
||||
@@ -405,6 +405,7 @@ const SingleEmailItem = React.forwardRef<HTMLDivElement, SingleEmailItemProps>(
|
||||
onMarkAsSpam={onMarkAsSpam}
|
||||
onUndoSpam={onUndoSpam}
|
||||
isInJunk={currentMailboxRole === 'junk'}
|
||||
spamApplicable={!['sent', 'drafts', 'scheduled'].includes(currentMailboxRole || '')}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -875,6 +876,7 @@ export const ThreadListItem = React.forwardRef<HTMLDivElement, ThreadListItemPro
|
||||
onMarkAsSpam={onMarkAsSpam ? () => onMarkAsSpam(latestEmail) : undefined}
|
||||
onUndoSpam={onUndoSpam ? () => onUndoSpam(latestEmail) : undefined}
|
||||
isInJunk={currentMailboxRole === 'junk'}
|
||||
spamApplicable={!['sent', 'drafts', 'scheduled'].includes(currentMailboxRole || '')}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user