From 6e93fad24285fa43518ff486e0515b5d1435bc86 Mon Sep 17 00:00:00 2001 From: amrit Date: Mon, 11 Aug 2025 23:03:05 +0530 Subject: [PATCH] ui: add cross in the undo email toast, decrease time from 30s to 15s (#1979) ## Summary by cubic Added a close (cross) button to the undo email toast and reduced the undo window from 30 seconds to 15 seconds. - **UI Improvements** - The undo toast now shows a close button for quick dismissal. - The undo option is available for 15 seconds instead of 30. ## Summary by CodeRabbit * **New Features** * Improved Undo experience: separate flows for scheduled vs. immediate sends with clearer toasts. Undoing a scheduled send cancels scheduling; undoing an immediate send restores the draft (including attachments) and reopens the composer. Toasts now last 15 seconds and include a close button. * Default delay before processing a send/schedule reduced from 30 seconds to 15 seconds. * **Bug Fixes** * Prevented negative time remaining, ensuring Undo is reliably available and consistent with the 5-second gating. --- apps/mail/hooks/use-undo-send.ts | 36 ++++++++++++++++++++++------- apps/server/src/trpc/routes/mail.ts | 2 +- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/apps/mail/hooks/use-undo-send.ts b/apps/mail/hooks/use-undo-send.ts index 55182c311..4b7941cb9 100644 --- a/apps/mail/hooks/use-undo-send.ts +++ b/apps/mail/hooks/use-undo-send.ts @@ -68,13 +68,31 @@ export const useUndoSend = () => { if (isSendResult(result) && settings?.settings?.undoSendEnabled) { const { messageId, sendAt } = result; - const timeRemaining = sendAt ? sendAt - Date.now() : 15_000; + const timeRemaining = sendAt ? Math.max(0, sendAt - Date.now()) : 15_000; + const wasUserScheduled = Boolean(emailData?.scheduleAt); if (timeRemaining > 5_000) { - toast.success('Email scheduled', { - action: { - label: 'Undo', - onClick: async () => { + if (wasUserScheduled) { + toast.success('Email scheduled', { + action: { + label: 'Undo', + onClick: async () => { + try { + await unsendEmail({ messageId }); + toast.info('Schedule cancelled'); + } catch { + toast.error('Failed to cancel'); + } + }, + }, + duration: 15_000, + closeButton: true, + }); + } else { + toast.success('Email sent', { + action: { + label: 'Undo', + onClick: async () => { try { await unsendEmail({ messageId }); @@ -98,10 +116,12 @@ export const useUndoSend = () => { } catch { toast.error('Failed to cancel'); } + }, }, - }, - duration: 15_000, - }); + duration: 15_000, + closeButton: true, + }); + } } } }; diff --git a/apps/server/src/trpc/routes/mail.ts b/apps/server/src/trpc/routes/mail.ts index dd419428e..55f5205c7 100644 --- a/apps/server/src/trpc/routes/mail.ts +++ b/apps/server/src/trpc/routes/mail.ts @@ -515,7 +515,7 @@ export const mailRouter = router({ targetTime = parsedTime; } else { - targetTime = Date.now() + 30_000; + targetTime = Date.now() + 15_000; } const rawDelaySeconds = Math.floor((targetTime - Date.now()) / 1000);