From f7adbf1efe5bb2a4f419349789e277791648e83c Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Wed, 28 Oct 2026 04:05:12 +0100 Subject: [PATCH] feat: add Cancel send for scheduled messages, which puts them back into Drafts, and show their actions once --- .../__tests__/email-context-menu.test.tsx | 16 +++++++ .../__tests__/viewer-send-failures.test.tsx | 22 ++++++++++ components/email/email-context-menu.tsx | 13 ++++++ components/email/email-list.tsx | 4 ++ components/email/email-viewer.tsx | 44 +++++++++---------- components/mail/mail-app.tsx | 21 ++++++++- locales/ar/common.json | 4 +- locales/ca/common.json | 4 +- locales/cs/common.json | 4 +- locales/da/common.json | 4 +- locales/de/common.json | 4 +- locales/en/common.json | 4 +- locales/es/common.json | 4 +- locales/et/common.json | 4 +- locales/fa/common.json | 4 +- locales/fr/common.json | 4 +- locales/he/common.json | 4 +- locales/hu/common.json | 4 +- locales/it/common.json | 4 +- locales/ja/common.json | 4 +- locales/ko/common.json | 4 +- locales/lv/common.json | 4 +- locales/mn/common.json | 4 +- locales/nb/common.json | 4 +- locales/nl/common.json | 4 +- locales/pl/common.json | 4 +- locales/pt/common.json | 4 +- locales/ro/common.json | 4 +- locales/ru/common.json | 4 +- locales/sk/common.json | 4 +- locales/th/common.json | 4 +- locales/tr/common.json | 4 +- locales/uk/common.json | 4 +- locales/zh-TW/common.json | 4 +- locales/zh/common.json | 4 +- 35 files changed, 153 insertions(+), 83 deletions(-) diff --git a/components/email/__tests__/email-context-menu.test.tsx b/components/email/__tests__/email-context-menu.test.tsx index fcf3555a4..44ec665d2 100644 --- a/components/email/__tests__/email-context-menu.test.tsx +++ b/components/email/__tests__/email-context-menu.test.tsx @@ -99,3 +99,19 @@ describe('EmailContextMenu batch forward as attachment', () => { expect((screen.getByTestId('ctx-batch-forward-as-attachment') as HTMLButtonElement).disabled).toBe(true); }); }); + +describe('EmailContextMenu on a scheduled message', () => { + const scheduled = { ...email, isScheduled: true, scheduledUndoStatus: 'pending' } as unknown as Email; + + it('offers Cancel send', () => { + const onCancelScheduledSend = vi.fn(); + renderMenu({ email: scheduled, onCancelScheduledSend, onCancelScheduledForEdit: vi.fn(), onRescheduleScheduled: vi.fn() }); + fireEvent.click(screen.getByTestId('ctx-cancel-scheduled-send')); + expect(onCancelScheduledSend).toHaveBeenCalledTimes(1); + }); + + it('leaves it out for an encrypted message, which cannot go back to Drafts', () => { + renderMenu({ email: { ...scheduled, isSmimeScheduled: true } as Email, onCancelScheduledSend: vi.fn(), onCancelScheduledForEdit: vi.fn() }); + expect(screen.queryByTestId('ctx-cancel-scheduled-send')).toBeNull(); + }); +}); diff --git a/components/email/__tests__/viewer-send-failures.test.tsx b/components/email/__tests__/viewer-send-failures.test.tsx index d0489653f..af294f81c 100644 --- a/components/email/__tests__/viewer-send-failures.test.tsx +++ b/components/email/__tests__/viewer-send-failures.test.tsx @@ -138,6 +138,28 @@ describe('viewer send failures', () => { expect(onRescheduleScheduled).toHaveBeenCalledTimes(1); }); + it('offers Cancel send, and shows one set of scheduled actions and no draft bar', () => { + const onCancelScheduledSend = vi.fn(); + render( + , + ); + + fireEvent.click(screen.getByTestId('cancel-scheduled-send')); + expect(onCancelScheduledSend).toHaveBeenCalledTimes(1); + // The banner's buttons are for the phone only, where the toolbar has none. + const bannerReschedule = screen.getAllByText('reschedule_send').map(el => el.closest('div.flex-wrap')).find(Boolean); + expect(bannerReschedule?.className).toContain('sm:hidden'); + expect(screen.getAllByText('send_now')).toHaveLength(1); + expect(screen.queryByText('draft_banner')).toBeNull(); + }); + it('reschedules through the schedule dialog, not a browser prompt', async () => { const prompt = vi.spyOn(window, 'prompt'); const onRescheduleScheduled = vi.fn().mockResolvedValue(undefined); diff --git a/components/email/email-context-menu.tsx b/components/email/email-context-menu.tsx index 0050253c4..866131191 100644 --- a/components/email/email-context-menu.tsx +++ b/components/email/email-context-menu.tsx @@ -36,6 +36,7 @@ import { ShieldCheck, EditIcon, CalendarClock, + CalendarX, Paperclip, Link as LinkIcon, MessagesSquare, @@ -106,6 +107,7 @@ interface EmailContextMenuProps { onUndoSpam?: () => void; onEditDraft?: () => void; onCancelScheduledForEdit?: () => void; + onCancelScheduledSend?: () => void; onRescheduleScheduled?: () => void; // Batch actions onBatchMarkAsRead?: (read: boolean) => void; @@ -190,6 +192,7 @@ export function EmailContextMenu({ onBatchForwardAsAttachment, onEditDraft, onCancelScheduledForEdit, + onCancelScheduledSend, onRescheduleScheduled, copyTargets, onCopyToAccount, @@ -575,6 +578,16 @@ export function EmailContextMenu({ onClick={() => handleAction(onCancelScheduledForEdit!)} disabled={!onCancelScheduledForEdit} /> + {/* Back into Drafts. An S/MIME message can't go back (it is + encrypted), so it only offers "Cancel and compose again". */} + {onCancelScheduledSend && !email.isSmimeScheduled && ( + handleAction(onCancelScheduledSend)} + /> + )} )} diff --git a/components/email/email-list.tsx b/components/email/email-list.tsx index 34d9e9acd..f950a5358 100644 --- a/components/email/email-list.tsx +++ b/components/email/email-list.tsx @@ -85,6 +85,8 @@ interface EmailListProps { isScheduledView?: boolean; onLoadMoreScheduled?: () => void; onCancelScheduledForEdit?: (email: Email) => void | Promise; + /** Stop a scheduled message from going out; it goes back to Drafts. */ + onCancelScheduledSend?: (email: Email) => void | Promise; onRescheduleScheduled?: (email: Email) => void | Promise; /** * Mountain View folds the batch verbs into the single toolbar above the @@ -164,6 +166,7 @@ export function EmailList({ hideBatchToolbar = false, onLoadMoreScheduled, onCancelScheduledForEdit, + onCancelScheduledSend, onRescheduleScheduled, }: EmailListProps) { const t = useTranslations('email_list'); @@ -1204,6 +1207,7 @@ export function EmailList({ onUndoSpam={() => onUndoSpam?.(contextMenuEmail!)} onEditDraft={() => onEditDraft?.(contextMenuEmail!)} onCancelScheduledForEdit={onCancelScheduledForEdit ? () => onCancelScheduledForEdit(contextMenuEmail!) : undefined} + onCancelScheduledSend={onCancelScheduledSend ? () => void onCancelScheduledSend(contextMenuEmail!) : undefined} onRescheduleScheduled={onRescheduleScheduled ? () => onRescheduleScheduled(contextMenuEmail!) : undefined} copyTargets={copyTargets} onCopyToAccount={async (accountId, mailboxId) => { diff --git a/components/email/email-viewer.tsx b/components/email/email-viewer.tsx index 8d9bc4ab3..fdbdfe1ed 100644 --- a/components/email/email-viewer.tsx +++ b/components/email/email-viewer.tsx @@ -93,6 +93,7 @@ import { PlayCircle, PenSquare, CalendarClock, + CalendarX, Link as LinkIcon, Maximize2, Minimize2, @@ -214,6 +215,8 @@ interface EmailViewerProps { onShowShortcuts?: () => void; onEditDraft?: () => void; onCancelScheduledForEdit?: () => void; + /** Stop a scheduled message from going out; it goes back to Drafts. */ + onCancelScheduledSend?: () => void; onRescheduleScheduled?: (delayedUntil: string) => void | Promise; onCompose?: () => void; /** @@ -1064,6 +1067,7 @@ export function EmailViewer({ onShowShortcuts, onEditDraft, onCancelScheduledForEdit, + onCancelScheduledSend, onRescheduleScheduled, onCompose, onToggleFullscreen, @@ -3864,6 +3868,12 @@ export function EmailViewer({ {showToolbarLabels && {email.isSmimeScheduled ? t('cancel_and_compose_again') : t('cancel_and_edit')}} + {onCancelScheduledSend && !email.isSmimeScheduled && ( + + )} )} {!isScheduled && isDraft && onEditDraft && ( @@ -5746,18 +5756,10 @@ export function EmailViewer({ {t('scheduled_banner', { date: email.scheduledSendAt ? formatScheduledSendAt(email.scheduledSendAt, timeFormat) : '' })} -
+ {/* The toolbar has these from sm up; on the phone it has no room. */} +
{canCancelScheduled && ( <> - + {onCancelScheduledSend && !email.isSmimeScheduled && ( + + )} )}
@@ -5780,26 +5788,14 @@ export function EmailViewer({
)} - {/* Draft Banner */} - {isDraft && ( + {/* Draft Banner: a scheduled message has its own. */} + {isDraft && !isScheduled && (
{t('draft_banner')}
- {/* The toolbar already has Edit, except for a scheduled message. */} - {onEditDraft && isScheduled && ( - - )}
)} diff --git a/components/mail/mail-app.tsx b/components/mail/mail-app.tsx index 69e230ab0..d4fca7719 100644 --- a/components/mail/mail-app.tsx +++ b/components/mail/mail-app.tsx @@ -932,7 +932,11 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) { } } : undefined, onDelete: async () => { - if (isScheduledView) return; + // Delete on a scheduled message cancels the send, back into Drafts. + if (isScheduledView) { + if (selectedEmail) await handleCancelScheduledSend(selectedEmail); + return; + } if (shortcutsTargetSelection && client) { const currentMailbox = mailboxes.find(m => m.id === selectedMailbox); const permanent = bulkDeleteIsPermanent(currentMailbox); @@ -2436,6 +2440,19 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) { } }; + // "Cancel send": nothing goes out, and the message is back in Drafts. An + // S/MIME message can't go back (it is encrypted) and only offers "Cancel + // and compose again". + const handleCancelScheduledSend = async (email: Email) => { + if (email.isSmimeScheduled || email.scheduledUndoStatus !== 'pending') return; + const restored = await cancelScheduledForEdit(email); + if (restored === undefined) return; + toast.success( + tViewer('send_cancelled'), + t('notifications.moved_to_mailbox', { mailbox: t('sidebar.mailboxes.drafts') }), + ); + }; + useEffect(() => { if (!pendingUndoSend || !client) return; if (lastUndoToastSubmissionRef.current === pendingUndoSend.submissionId) return; @@ -5158,6 +5175,7 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) { if (isMobile) setActiveView('viewer'); }} onRescheduleScheduled={(email) => setRescheduleTarget(email)} + onCancelScheduledSend={handleCancelScheduledSend} onEmailSelect={handleEmailSelect} onOpenSearchResult={handleEmailSelect} onEmailPrefetch={handleEmailPrefetch} @@ -5468,6 +5486,7 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) { // Restored through the active login's client (see the list's Cancel and edit). if (restored) await handleEditDraft(restored, { accountId: selectedEmail.scheduledAccountId, localAccountId: activeAccountId ?? undefined }).catch(reportDraftOpenFailure); }} + onCancelScheduledSend={() => { if (selectedEmail) void handleCancelScheduledSend(selectedEmail); }} onRescheduleScheduled={async (delayedUntil) => { if (client && selectedEmail?.emailSubmissionId && selectedEmail.scheduledIdentityId) { const result = await rescheduleScheduledEmail(client, selectedEmail.emailSubmissionId, selectedEmail.id, selectedEmail.scheduledIdentityId, delayedUntil, selectedEmail.scheduledAccountId); diff --git a/locales/ar/common.json b/locales/ar/common.json index 53fcac85e..74b10108b 100644 --- a/locales/ar/common.json +++ b/locales/ar/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "إلغاء الإرسال", "reschedule_send": "إعادة الجدولة", "cancel_and_edit": "إلغاء والتعديل", - "cancel_and_compose_again": "إلغاء وإعادة الكتابة", - "reschedule_prompt": "أدخل تاريخًا/وقتًا جديدًا، مثل 2026-05-04T15:30" + "cancel_and_compose_again": "إلغاء وإعادة الكتابة" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "أُلغي الإرسال، لكن تعذّرت إعادة الرسالة إلى المسودات. لا تزال في المرسل.", "send_cancelled_remove_failed": "أُلغي الإرسال، لكن تعذّرت إزالة الرسالة غير المرسلة من المرسل.", "cancel_scheduled_failed": "تعذّر إلغاء الإرسال المجدول", + "send_cancelled": "أُلغي الإرسال", "still_scheduled_at": "لا تزال الرسالة مجدولة للإرسال في {date}.", "still_scheduled": "لا تزال الرسالة مجدولة.", "already_sent": "أُرسلت هذه الرسالة بالفعل.", diff --git a/locales/ca/common.json b/locales/ca/common.json index fc5d01b12..ce2785bbf 100644 --- a/locales/ca/common.json +++ b/locales/ca/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Cancel·la l'enviament", "reschedule_send": "Reprograma", "cancel_and_edit": "Cancel·la i edita", - "cancel_and_compose_again": "Cancel·la i torna a redactar", - "reschedule_prompt": "Introduïu una data i hora noves, p. ex. 2026-05-04T15:30" + "cancel_and_compose_again": "Cancel·la i torna a redactar" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "S'ha cancel·lat l'enviament, però el missatge no s'ha pogut tornar a Esborranys. Encara és a Enviats.", "send_cancelled_remove_failed": "S'ha cancel·lat l'enviament, però el missatge no enviat no s'ha pogut treure d'Enviats.", "cancel_scheduled_failed": "No s'ha pogut cancel·lar l'enviament programat", + "send_cancelled": "S'ha cancel·lat l'enviament", "still_scheduled_at": "El missatge encara està programat per al {date}.", "still_scheduled": "El missatge encara està programat.", "already_sent": "Aquest missatge ja s'ha enviat.", diff --git a/locales/cs/common.json b/locales/cs/common.json index c7fcff2e0..8dd99674c 100644 --- a/locales/cs/common.json +++ b/locales/cs/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Zrušit odeslání", "reschedule_send": "Přeplánovat", "cancel_and_edit": "Zrušit a upravit", - "cancel_and_compose_again": "Zrušit a napsat znovu", - "reschedule_prompt": "Zadejte nové datum/čas, např. 2026-05-04T15:30" + "cancel_and_compose_again": "Zrušit a napsat znovu" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Odeslání bylo zrušeno, ale zprávu se nepodařilo vrátit do Konceptů. Je stále v Odeslaných.", "send_cancelled_remove_failed": "Odeslání bylo zrušeno, ale neodeslanou zprávu se nepodařilo odstranit z Odeslaných.", "cancel_scheduled_failed": "Naplánované odeslání se nepodařilo zrušit", + "send_cancelled": "Odeslání zrušeno", "still_scheduled_at": "Zpráva je stále naplánována na {date}.", "still_scheduled": "Zpráva je stále naplánována.", "already_sent": "Tato zpráva již byla odeslána.", diff --git a/locales/da/common.json b/locales/da/common.json index 507623461..d1ca35ce9 100644 --- a/locales/da/common.json +++ b/locales/da/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Annuller afsendelse", "reschedule_send": "Planlæg om", "cancel_and_edit": "Annuller og redigér", - "cancel_and_compose_again": "Annuller og skriv igen", - "reschedule_prompt": "Indtast en ny dato/tid, f.eks. 2026-05-04T15:30" + "cancel_and_compose_again": "Annuller og skriv igen" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Afsendelsen blev annulleret, men beskeden kunne ikke lægges tilbage i Kladder. Den ligger stadig i Sendt.", "send_cancelled_remove_failed": "Afsendelsen blev annulleret, men den ikke-sendte besked kunne ikke fjernes fra Sendt.", "cancel_scheduled_failed": "Den planlagte afsendelse kunne ikke annulleres", + "send_cancelled": "Afsendelse annulleret", "still_scheduled_at": "Beskeden er stadig planlagt til {date}.", "still_scheduled": "Beskeden er stadig planlagt.", "already_sent": "Denne besked er allerede sendt.", diff --git a/locales/de/common.json b/locales/de/common.json index 8ee5c74e6..71399e384 100644 --- a/locales/de/common.json +++ b/locales/de/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Senden abbrechen", "reschedule_send": "Neu planen", "cancel_and_edit": "Abbrechen und bearbeiten", - "cancel_and_compose_again": "Abbrechen und neu verfassen", - "reschedule_prompt": "Neues Datum/Uhrzeit eingeben, z. B. 2026-05-04T15:30" + "cancel_and_compose_again": "Abbrechen und neu verfassen" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Das Senden wurde abgebrochen, aber die Nachricht konnte nicht zurück in die Entwürfe gelegt werden. Sie liegt noch im Ordner „Gesendet“.", "send_cancelled_remove_failed": "Das Senden wurde abgebrochen, aber die nicht gesendete Nachricht konnte nicht aus dem Ordner „Gesendet“ entfernt werden.", "cancel_scheduled_failed": "Das geplante Senden konnte nicht abgebrochen werden", + "send_cancelled": "Senden abgebrochen", "still_scheduled_at": "Die Nachricht ist weiterhin für {date} geplant.", "still_scheduled": "Die Nachricht ist weiterhin geplant.", "already_sent": "Diese Nachricht wurde bereits gesendet.", diff --git a/locales/en/common.json b/locales/en/common.json index f37e5c032..b4915c827 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Cancel send", "reschedule_send": "Reschedule", "cancel_and_edit": "Cancel and edit", - "cancel_and_compose_again": "Cancel and compose again", - "reschedule_prompt": "Enter a new date/time, e.g. 2026-05-04T15:30" + "cancel_and_compose_again": "Cancel and compose again" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Sending was cancelled, but the message could not be put back in Drafts. It is still in Sent.", "send_cancelled_remove_failed": "Sending was cancelled, but the unsent message could not be removed from Sent.", "cancel_scheduled_failed": "Couldn't cancel the scheduled send", + "send_cancelled": "Sending cancelled", "still_scheduled_at": "The message is still scheduled for {date}.", "still_scheduled": "The message is still scheduled.", "already_sent": "This message was already sent.", diff --git a/locales/es/common.json b/locales/es/common.json index 5b013efb9..b4095604b 100644 --- a/locales/es/common.json +++ b/locales/es/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Cancelar envío", "reschedule_send": "Reprogramar", "cancel_and_edit": "Cancelar y editar", - "cancel_and_compose_again": "Cancelar y redactar de nuevo", - "reschedule_prompt": "Introduce una nueva fecha/hora, p. ej. 2026-05-04T15:30" + "cancel_and_compose_again": "Cancelar y redactar de nuevo" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Se canceló el envío, pero el mensaje no se pudo devolver a Borradores. Sigue en Enviados.", "send_cancelled_remove_failed": "Se canceló el envío, pero el mensaje no enviado no se pudo quitar de Enviados.", "cancel_scheduled_failed": "No se pudo cancelar el envío programado", + "send_cancelled": "Envío cancelado", "still_scheduled_at": "El mensaje sigue programado para el {date}.", "still_scheduled": "El mensaje sigue programado.", "already_sent": "Este mensaje ya se envió.", diff --git a/locales/et/common.json b/locales/et/common.json index f7106bb6c..e94c5f86a 100644 --- a/locales/et/common.json +++ b/locales/et/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Tühista saatmine", "reschedule_send": "Ajasta uuesti", "cancel_and_edit": "Tühista ja muuda", - "cancel_and_compose_again": "Tühista ja koosta uuesti", - "reschedule_prompt": "Sisesta uus kuupäev/kellaaeg, nt 2026-05-04T15:30" + "cancel_and_compose_again": "Tühista ja koosta uuesti" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Saatmine tühistati, kuid kirja ei õnnestunud mustanditesse tagasi panna. See on endiselt kaustas Saadetud.", "send_cancelled_remove_failed": "Saatmine tühistati, kuid saatmata kirja ei õnnestunud kaustast Saadetud eemaldada.", "cancel_scheduled_failed": "Ajastatud saatmist ei õnnestunud tühistada", + "send_cancelled": "Saatmine tühistatud", "still_scheduled_at": "Kiri on endiselt ajastatud ajale {date}.", "still_scheduled": "Kiri on endiselt ajastatud.", "already_sent": "See kiri on juba saadetud.", diff --git a/locales/fa/common.json b/locales/fa/common.json index daf91361b..cbe80568b 100644 --- a/locales/fa/common.json +++ b/locales/fa/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "لغو ارسال", "reschedule_send": "باززمان‌بندی", "cancel_and_edit": "لغو و ویرایش", - "cancel_and_compose_again": "لغو و نوشتن مجدد", - "reschedule_prompt": "تاریخ/زمان جدید را وارد کنید" + "cancel_and_compose_again": "لغو و نوشتن مجدد" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "ارسال لغو شد، اما پیام به پیش‌نویس‌ها بازگردانده نشد. هنوز در ارسال شده است.", "send_cancelled_remove_failed": "ارسال لغو شد، اما پیام ارسال‌نشده از ارسال شده حذف نشد.", "cancel_scheduled_failed": "لغو ارسال زمان‌بندی‌شده ممکن نشد", + "send_cancelled": "ارسال لغو شد", "still_scheduled_at": "پیام همچنان برای {date} زمان‌بندی شده است.", "still_scheduled": "پیام همچنان زمان‌بندی شده است.", "already_sent": "این پیام قبلاً ارسال شده است.", diff --git a/locales/fr/common.json b/locales/fr/common.json index a6ef755d5..78947a5e7 100644 --- a/locales/fr/common.json +++ b/locales/fr/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Annuler l’envoi", "reschedule_send": "Replanifier", "cancel_and_edit": "Annuler et modifier", - "cancel_and_compose_again": "Annuler et rédiger à nouveau", - "reschedule_prompt": "Saisissez une nouvelle date/heure, p. ex. 2026-05-04T15:30" + "cancel_and_compose_again": "Annuler et rédiger à nouveau" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "L’envoi a été annulé, mais le message n’a pas pu être remis dans Brouillons. Il est toujours dans Envoyés.", "send_cancelled_remove_failed": "L’envoi a été annulé, mais le message non envoyé n’a pas pu être retiré d’Envoyés.", "cancel_scheduled_failed": "Impossible d’annuler l’envoi planifié", + "send_cancelled": "Envoi annulé", "still_scheduled_at": "Le message reste planifié pour le {date}.", "still_scheduled": "Le message reste planifié.", "already_sent": "Ce message a déjà été envoyé.", diff --git a/locales/he/common.json b/locales/he/common.json index 15c3c0f3f..bd2a46c87 100644 --- a/locales/he/common.json +++ b/locales/he/common.json @@ -276,8 +276,7 @@ "cancel_scheduled_send": "ביטול שליחה", "reschedule_send": "תזמן מחדש", "cancel_and_edit": "בטל וערוך", - "cancel_and_compose_again": "בטל והרכיב שוב", - "reschedule_prompt": "הזן תאריך/שעה חדש, למשל 2026-05-04T15:30" + "cancel_and_compose_again": "בטל והרכיב שוב" }, "email_viewer": { "no_email_selected": "לא נבחר אימייל", @@ -593,6 +592,7 @@ "send_cancelled_restore_failed": "השליחה בוטלה, אך לא ניתן היה להחזיר את ההודעה לטיוטות. היא עדיין בנשלח.", "send_cancelled_remove_failed": "השליחה בוטלה, אך לא ניתן היה להסיר את ההודעה שלא נשלחה מנשלח.", "cancel_scheduled_failed": "לא ניתן היה לבטל את השליחה המתוזמנת", + "send_cancelled": "השליחה בוטלה", "still_scheduled_at": "ההודעה עדיין מתוזמנת ל־{date}.", "still_scheduled": "ההודעה עדיין מתוזמנת.", "already_sent": "ההודעה הזו כבר נשלחה.", diff --git a/locales/hu/common.json b/locales/hu/common.json index 040a656dd..da5efdbe6 100644 --- a/locales/hu/common.json +++ b/locales/hu/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Küldés megszakítása", "reschedule_send": "Átütemezés", "cancel_and_edit": "Mégse és szerkesztés", - "cancel_and_compose_again": "Mégse és újraírás", - "reschedule_prompt": "Adj meg egy új dátumot/időpontot, pl. 2026-05-04T15:30" + "cancel_and_compose_again": "Mégse és újraírás" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "A küldés megszakadt, de az üzenetet nem sikerült visszatenni a Piszkozatok közé. Még az Elküldött mappában van.", "send_cancelled_remove_failed": "A küldés megszakadt, de az el nem küldött üzenetet nem sikerült eltávolítani az Elküldött mappából.", "cancel_scheduled_failed": "Az ütemezett küldést nem sikerült megszakítani", + "send_cancelled": "Küldés megszakítva", "still_scheduled_at": "Az üzenet továbbra is ütemezve van: {date}.", "still_scheduled": "Az üzenet továbbra is ütemezve van.", "already_sent": "Ez az üzenet már el lett küldve.", diff --git a/locales/it/common.json b/locales/it/common.json index bf627b71e..6a6dd47ed 100644 --- a/locales/it/common.json +++ b/locales/it/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Annulla invio", "reschedule_send": "Riprogramma", "cancel_and_edit": "Annulla e modifica", - "cancel_and_compose_again": "Annulla e componi di nuovo", - "reschedule_prompt": "Inserisci una nuova data/ora, ad es. 2026-05-04T15:30" + "cancel_and_compose_again": "Annulla e componi di nuovo" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "L'invio è stato annullato, ma non è stato possibile riportare il messaggio in Bozze. Si trova ancora in Inviati.", "send_cancelled_remove_failed": "L'invio è stato annullato, ma non è stato possibile rimuovere il messaggio non inviato da Inviati.", "cancel_scheduled_failed": "Impossibile annullare l'invio programmato", + "send_cancelled": "Invio annullato", "still_scheduled_at": "Il messaggio è ancora programmato per il {date}.", "still_scheduled": "Il messaggio è ancora programmato.", "already_sent": "Questo messaggio è già stato inviato.", diff --git a/locales/ja/common.json b/locales/ja/common.json index dbd1a8c8d..14f69d637 100644 --- a/locales/ja/common.json +++ b/locales/ja/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "送信をキャンセル", "reschedule_send": "再予約", "cancel_and_edit": "キャンセルして編集", - "cancel_and_compose_again": "キャンセルして新規作成", - "reschedule_prompt": "新しい日時を入力してください。例: 2026-05-04T15:30" + "cancel_and_compose_again": "キャンセルして新規作成" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "送信はキャンセルされましたが、メッセージを下書きに戻せませんでした。メッセージは送信済みに残っています。", "send_cancelled_remove_failed": "送信はキャンセルされましたが、未送信のメッセージを送信済みから削除できませんでした。", "cancel_scheduled_failed": "予約送信をキャンセルできませんでした", + "send_cancelled": "送信を取り消しました", "still_scheduled_at": "メッセージは引き続き {date} に送信予定です。", "still_scheduled": "メッセージは引き続き送信予定です。", "already_sent": "このメッセージはすでに送信されています。", diff --git a/locales/ko/common.json b/locales/ko/common.json index 3e78d12ca..f85d2efa4 100644 --- a/locales/ko/common.json +++ b/locales/ko/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "보내기 취소", "reschedule_send": "다시 예약", "cancel_and_edit": "취소하고 편집", - "cancel_and_compose_again": "취소하고 다시 작성", - "reschedule_prompt": "새 날짜/시간을 입력하세요. 예: 2026-05-04T15:30" + "cancel_and_compose_again": "취소하고 다시 작성" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "보내기가 취소되었지만 메시지를 임시보관함으로 되돌리지 못했습니다. 메시지는 아직 보낸편지함에 있습니다.", "send_cancelled_remove_failed": "보내기가 취소되었지만 보내지 않은 메시지를 보낸편지함에서 제거하지 못했습니다.", "cancel_scheduled_failed": "예약된 보내기를 취소하지 못했습니다", + "send_cancelled": "보내기를 취소했어요", "still_scheduled_at": "메시지는 여전히 {date}에 보내도록 예약되어 있습니다.", "still_scheduled": "메시지는 여전히 예약되어 있습니다.", "already_sent": "이 메시지는 이미 보냈습니다.", diff --git a/locales/lv/common.json b/locales/lv/common.json index 48a59c386..b17309617 100644 --- a/locales/lv/common.json +++ b/locales/lv/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Atcelt sūtīšanu", "reschedule_send": "Pārplānot", "cancel_and_edit": "Atcelt un rediģēt", - "cancel_and_compose_again": "Atcelt un rakstīt no jauna", - "reschedule_prompt": "Ievadiet jaunu datumu/laiku, piem. 2026-05-04T15:30" + "cancel_and_compose_again": "Atcelt un rakstīt no jauna" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Sūtīšana tika atcelta, bet ziņojumu neizdevās atgriezt Melnrakstos. Tas joprojām ir Nosūtītajos.", "send_cancelled_remove_failed": "Sūtīšana tika atcelta, bet nenosūtīto ziņojumu neizdevās noņemt no Nosūtītajiem.", "cancel_scheduled_failed": "Ieplānoto sūtīšanu neizdevās atcelt", + "send_cancelled": "Sūtīšana atcelta", "still_scheduled_at": "Ziņojums joprojām ir ieplānots uz {date}.", "still_scheduled": "Ziņojums joprojām ir ieplānots.", "already_sent": "Šis ziņojums jau ir nosūtīts.", diff --git a/locales/mn/common.json b/locales/mn/common.json index 3dce34d55..2cad8393a 100644 --- a/locales/mn/common.json +++ b/locales/mn/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Илгээхийг цуцлах", "reschedule_send": "Хуваарь солих", "cancel_and_edit": "Цуцлах, засах", - "cancel_and_compose_again": "Цуцлаад дахин бичих", - "reschedule_prompt": "Шинэ огноо/цаг оруулна, ж.нь. 2026-05-04Т15:30" + "cancel_and_compose_again": "Цуцлаад дахин бичих" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Илгээлтийг цуцалсан ч мессежийг Ноорог руу буцааж чадсангүй. Энэ одоо ч Илгээсэн хэсэгт байна.", "send_cancelled_remove_failed": "Илгээлтийг цуцалсан ч илгээгээгүй мессежийг Илгээсэн хэсгээс устгаж чадсангүй.", "cancel_scheduled_failed": "Товлосон илгээлтийг цуцалж чадсангүй", + "send_cancelled": "Илгээхийг цуцаллаа", "still_scheduled_at": "Мессеж {date}-нд илгээгдэхээр товлогдсон хэвээр байна.", "still_scheduled": "Мессеж товлогдсон хэвээр байна.", "already_sent": "Энэ мессеж аль хэдийн илгээгдсэн.", diff --git a/locales/nb/common.json b/locales/nb/common.json index 849e5ce19..2557ba76e 100644 --- a/locales/nb/common.json +++ b/locales/nb/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Avbryt sending", "reschedule_send": "Planlegg på nytt", "cancel_and_edit": "Avbryt og rediger", - "cancel_and_compose_again": "Avbryt og skriv meldingen på nytt", - "reschedule_prompt": "Skriv inn ny dato og klokkeslett, for eksempel 2026-05-04T15:30" + "cancel_and_compose_again": "Avbryt og skriv meldingen på nytt" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Sendingen ble avbrutt, men meldingen kunne ikke legges tilbake i Utkast. Den ligger fortsatt i Sendt.", "send_cancelled_remove_failed": "Sendingen ble avbrutt, men den usendte meldingen kunne ikke fjernes fra Sendt.", "cancel_scheduled_failed": "Den planlagte sendingen kunne ikke avbrytes", + "send_cancelled": "Sendingen er avbrutt", "still_scheduled_at": "Meldingen er fortsatt planlagt til {date}.", "still_scheduled": "Meldingen er fortsatt planlagt.", "already_sent": "Denne meldingen er allerede sendt.", diff --git a/locales/nl/common.json b/locales/nl/common.json index a346f59cc..8861a028c 100644 --- a/locales/nl/common.json +++ b/locales/nl/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Verzenden annuleren", "reschedule_send": "Opnieuw plannen", "cancel_and_edit": "Annuleren en bewerken", - "cancel_and_compose_again": "Annuleren en opnieuw opstellen", - "reschedule_prompt": "Voer een nieuwe datum/tijd in, bijv. 2026-05-04T15:30" + "cancel_and_compose_again": "Annuleren en opnieuw opstellen" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Het verzenden is geannuleerd, maar het bericht kon niet terug naar Concepten. Het staat nog in Verzonden.", "send_cancelled_remove_failed": "Het verzenden is geannuleerd, maar het niet-verzonden bericht kon niet uit Verzonden worden verwijderd.", "cancel_scheduled_failed": "De geplande verzending kon niet worden geannuleerd", + "send_cancelled": "Verzenden geannuleerd", "still_scheduled_at": "Het bericht staat nog steeds gepland voor {date}.", "still_scheduled": "Het bericht staat nog steeds gepland.", "already_sent": "Dit bericht is al verzonden.", diff --git a/locales/pl/common.json b/locales/pl/common.json index dbd99c2b4..d793ab7cd 100644 --- a/locales/pl/common.json +++ b/locales/pl/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Anuluj wysyłkę", "reschedule_send": "Przełóż", "cancel_and_edit": "Anuluj i edytuj", - "cancel_and_compose_again": "Anuluj i napisz ponownie", - "reschedule_prompt": "Wprowadź nową datę/godzinę, np. 2026-05-04T15:30" + "cancel_and_compose_again": "Anuluj i napisz ponownie" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Wysyłka została anulowana, ale nie udało się przenieść wiadomości z powrotem do Szkiców. Nadal jest w Wysłanych.", "send_cancelled_remove_failed": "Wysyłka została anulowana, ale nie udało się usunąć niewysłanej wiadomości z Wysłanych.", "cancel_scheduled_failed": "Nie udało się anulować zaplanowanej wysyłki", + "send_cancelled": "Anulowano wysyłanie", "still_scheduled_at": "Wiadomość jest nadal zaplanowana na {date}.", "still_scheduled": "Wiadomość jest nadal zaplanowana.", "already_sent": "Ta wiadomość została już wysłana.", diff --git a/locales/pt/common.json b/locales/pt/common.json index dad6b3dbf..0953a0e67 100644 --- a/locales/pt/common.json +++ b/locales/pt/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Cancelar envio", "reschedule_send": "Reagendar", "cancel_and_edit": "Cancelar e editar", - "cancel_and_compose_again": "Cancelar e escrever novamente", - "reschedule_prompt": "Informe uma nova data/hora, ex. 2026-05-04T15:30" + "cancel_and_compose_again": "Cancelar e escrever novamente" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "O envio foi cancelado, mas não foi possível devolver a mensagem para Rascunhos. Ela ainda está em Enviados.", "send_cancelled_remove_failed": "O envio foi cancelado, mas não foi possível remover a mensagem não enviada de Enviados.", "cancel_scheduled_failed": "Não foi possível cancelar o envio agendado", + "send_cancelled": "Envio cancelado", "still_scheduled_at": "A mensagem continua agendada para {date}.", "still_scheduled": "A mensagem continua agendada.", "already_sent": "Esta mensagem já foi enviada.", diff --git a/locales/ro/common.json b/locales/ro/common.json index a35ba79f7..d082ffdd8 100644 --- a/locales/ro/common.json +++ b/locales/ro/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Anulează trimiterea", "reschedule_send": "Reprogramare", "cancel_and_edit": "Anulează și editează", - "cancel_and_compose_again": "Anulează și redactează din nou", - "reschedule_prompt": "Introduceți o nouă dată/oră, de exemplu 2026-05-04T15:30" + "cancel_and_compose_again": "Anulează și redactează din nou" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Trimiterea a fost anulată, dar mesajul nu a putut fi mutat înapoi în Ciorne. Se află încă în Trimise.", "send_cancelled_remove_failed": "Trimiterea a fost anulată, dar mesajul netrimis nu a putut fi eliminat din Trimise.", "cancel_scheduled_failed": "Trimiterea programată nu a putut fi anulată", + "send_cancelled": "Trimiterea a fost anulată", "still_scheduled_at": "Mesajul este încă programat pentru {date}.", "still_scheduled": "Mesajul este încă programat.", "already_sent": "Acest mesaj a fost deja trimis.", diff --git a/locales/ru/common.json b/locales/ru/common.json index d243c86db..7030257f8 100644 --- a/locales/ru/common.json +++ b/locales/ru/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Отменить отправку", "reschedule_send": "Перенести", "cancel_and_edit": "Отменить и изменить", - "cancel_and_compose_again": "Отменить и написать заново", - "reschedule_prompt": "Введите новую дату/время, например 2026-05-04T15:30" + "cancel_and_compose_again": "Отменить и написать заново" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Отправка отменена, но вернуть письмо в Черновики не удалось. Оно по-прежнему в Отправленных.", "send_cancelled_remove_failed": "Отправка отменена, но удалить неотправленное письмо из Отправленных не удалось.", "cancel_scheduled_failed": "Не удалось отменить запланированную отправку", + "send_cancelled": "Отправка отменена", "still_scheduled_at": "Письмо по-прежнему запланировано на {date}.", "still_scheduled": "Письмо по-прежнему запланировано.", "already_sent": "Это письмо уже отправлено.", diff --git a/locales/sk/common.json b/locales/sk/common.json index 3a8a4b145..6be419812 100644 --- a/locales/sk/common.json +++ b/locales/sk/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Zrušiť odoslanie", "reschedule_send": "Prenaplánovať", "cancel_and_edit": "Zrušiť a upraviť", - "cancel_and_compose_again": "Zrušiť a napísať znova", - "reschedule_prompt": "Zadajte nový dátum/čas, napr. 2026-05-04T15:30" + "cancel_and_compose_again": "Zrušiť a napísať znova" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Odoslanie bolo zrušené, ale správu sa nepodarilo vrátiť do Konceptov. Stále je v Odoslaných.", "send_cancelled_remove_failed": "Odoslanie bolo zrušené, ale neodoslanú správu sa nepodarilo odstrániť z Odoslaných.", "cancel_scheduled_failed": "Naplánované odoslanie sa nepodarilo zrušiť", + "send_cancelled": "Odoslanie zrušené", "still_scheduled_at": "Správa je stále naplánovaná na {date}.", "still_scheduled": "Správa je stále naplánovaná.", "already_sent": "Táto správa už bola odoslaná.", diff --git a/locales/th/common.json b/locales/th/common.json index 30af5a188..461aef647 100644 --- a/locales/th/common.json +++ b/locales/th/common.json @@ -494,8 +494,7 @@ "cancel_scheduled_send": "ยกเลิกการส่ง", "reschedule_send": "เปลี่ยนเวลาส่งใหม่", "cancel_and_edit": "ยกเลิกและแก้ไข", - "cancel_and_compose_again": "ยกเลิกและเขียนใหม่", - "reschedule_prompt": "ระบุวันและเวลาใหม่ เช่น 2026-05-04T15:30" + "cancel_and_compose_again": "ยกเลิกและเขียนใหม่" }, "context_menu": { "reply": "ตอบกลับ", @@ -1360,6 +1359,7 @@ "send_cancelled_restore_failed": "ยกเลิกการส่งแล้ว แต่ไม่สามารถนำข้อความกลับไปยังจดหมายร่างได้ ข้อความยังคงอยู่ในโฟลเดอร์ส่งแล้ว", "send_cancelled_remove_failed": "ยกเลิกการส่งแล้ว แต่ไม่สามารถนำข้อความที่ไม่ได้ส่งออกจากโฟลเดอร์ส่งแล้วได้", "cancel_scheduled_failed": "ไม่สามารถยกเลิกการกำหนดเวลาส่งได้", + "send_cancelled": "ยกเลิกการส่งแล้ว", "still_scheduled_at": "ข้อความยังคงมีกำหนดส่งในวันที่ {date}", "still_scheduled": "ข้อความยังคงมีกำหนดเวลาส่งอยู่", "already_sent": "ข้อความนี้ถูกส่งออกไปแล้ว", diff --git a/locales/tr/common.json b/locales/tr/common.json index 7fb3e2347..cc013988d 100644 --- a/locales/tr/common.json +++ b/locales/tr/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Göndermeyi iptal et", "reschedule_send": "Yeniden zamanla", "cancel_and_edit": "İptal et ve düzenle", - "cancel_and_compose_again": "İptal et ve yeniden yaz", - "reschedule_prompt": "Yeni tarih/saat girin, ör. 2026-05-04T15:30" + "cancel_and_compose_again": "İptal et ve yeniden yaz" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Gönderim iptal edildi, ancak ileti Taslaklar'a geri taşınamadı. Hâlâ Gönderilenler'de.", "send_cancelled_remove_failed": "Gönderim iptal edildi, ancak gönderilmemiş ileti Gönderilenler'den kaldırılamadı.", "cancel_scheduled_failed": "Zamanlanmış gönderim iptal edilemedi", + "send_cancelled": "Gönderim iptal edildi", "still_scheduled_at": "İleti hâlâ {date} için zamanlanmış durumda.", "still_scheduled": "İleti hâlâ zamanlanmış durumda.", "already_sent": "Bu ileti zaten gönderildi.", diff --git a/locales/uk/common.json b/locales/uk/common.json index d6df7f849..f208740a6 100644 --- a/locales/uk/common.json +++ b/locales/uk/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "Скасувати надсилання", "reschedule_send": "Перенести", "cancel_and_edit": "Скасувати й редагувати", - "cancel_and_compose_again": "Скасувати й написати знову", - "reschedule_prompt": "Введіть нову дату/час, напр. 2026-05-04T15:30" + "cancel_and_compose_again": "Скасувати й написати знову" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "Надсилання скасовано, але повернути лист до Чернеток не вдалося. Він досі в Надісланих.", "send_cancelled_remove_failed": "Надсилання скасовано, але видалити ненадісланий лист із Надісланих не вдалося.", "cancel_scheduled_failed": "Не вдалося скасувати заплановане надсилання", + "send_cancelled": "Надсилання скасовано", "still_scheduled_at": "Лист і далі заплановано на {date}.", "still_scheduled": "Лист і далі заплановано.", "already_sent": "Цей лист уже надіслано.", diff --git a/locales/zh-TW/common.json b/locales/zh-TW/common.json index 538a0bb0d..c5f87b3d7 100644 --- a/locales/zh-TW/common.json +++ b/locales/zh-TW/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "取消傳送", "reschedule_send": "重新排程", "cancel_and_edit": "取消並編輯", - "cancel_and_compose_again": "取消並重新撰寫", - "reschedule_prompt": "輸入新的日期與時間,例如 2026-05-04T15:30" + "cancel_and_compose_again": "取消並重新撰寫" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "已取消傳送,但無法將郵件放回草稿。郵件仍在「寄件備份」中。", "send_cancelled_remove_failed": "已取消傳送,但無法從「寄件備份」移除未寄出的郵件。", "cancel_scheduled_failed": "無法取消排定的傳送", + "send_cancelled": "已取消傳送", "still_scheduled_at": "郵件仍排定於 {date} 傳送。", "still_scheduled": "郵件仍在排定傳送中。", "already_sent": "此郵件已寄出。", diff --git a/locales/zh/common.json b/locales/zh/common.json index 5e7665cd0..78aa2d227 100644 --- a/locales/zh/common.json +++ b/locales/zh/common.json @@ -311,8 +311,7 @@ "cancel_scheduled_send": "取消发送", "reschedule_send": "重新计划", "cancel_and_edit": "取消并编辑", - "cancel_and_compose_again": "取消并重新撰写", - "reschedule_prompt": "输入新的日期/时间,例如 2026-05-04T15:30" + "cancel_and_compose_again": "取消并重新撰写" }, "email_viewer": { "read_receipt": { @@ -628,6 +627,7 @@ "send_cancelled_restore_failed": "已取消发送,但无法将邮件放回草稿。它仍在“已发送”中。", "send_cancelled_remove_failed": "已取消发送,但无法从“已发送”中移除未发送的邮件。", "cancel_scheduled_failed": "无法取消定时发送", + "send_cancelled": "已取消发送", "still_scheduled_at": "邮件仍计划于 {date} 发送。", "still_scheduled": "邮件仍处于定时发送状态。", "already_sent": "此邮件已发送。",