diff --git a/app/(main)/[locale]/page.tsx b/app/(main)/[locale]/page.tsx index 9a08f6c7..f5091d73 100644 --- a/app/(main)/[locale]/page.tsx +++ b/app/(main)/[locale]/page.tsx @@ -1561,7 +1561,24 @@ export default function Home() { // entirely, so the body starts blank instead of quoting the original. const handleForwardAsAttachment = async () => { if (!selectedEmail) return; - const payload = buildForwardAsAttachmentPayload(selectedEmail, t('email_composer.prefix.forward')); + // Same filename options "Export as .eml" uses (see emailFilenameOptions + // in email-viewer.tsx), so the two actions produce consistent filenames + // for the same message rather than the synthetic attachment silently + // ignoring the user's configured naming template. + const { + emailDownloadTemplate, + filenameSpaceReplacement, + filenameLowercase, + filenameStripDiacritics, + filenameCollapseSeparators, + } = useSettingsStore.getState(); + const payload = buildForwardAsAttachmentPayload(selectedEmail, t('email_composer.prefix.forward'), { + template: emailDownloadTemplate, + spaceReplacement: filenameSpaceReplacement, + lowercase: filenameLowercase, + stripDiacritics: filenameStripDiacritics, + collapseSeparators: filenameCollapseSeparators, + }); if (!payload) return; const ok = await emailHooks.onBeforeForward.intercept({ diff --git a/lib/__tests__/forward-as-attachment.test.ts b/lib/__tests__/forward-as-attachment.test.ts index 6d092fe3..c52aeb13 100644 --- a/lib/__tests__/forward-as-attachment.test.ts +++ b/lib/__tests__/forward-as-attachment.test.ts @@ -45,4 +45,14 @@ describe('buildForwardAsAttachmentPayload', () => { const payload = buildForwardAsAttachmentPayload(email, 'Fwd:'); expect(payload?.subject).toBe('Fwd: already forwarded once'); }); + + it('honors a custom filename template, matching "Export as .eml" naming instead of always using the default', () => { + const email = makeEmail({ subject: 'Missed spam example' }); + const payload = buildForwardAsAttachmentPayload(email, 'Fwd:', { + template: 'custom-{subject}', + lowercase: true, + spaceReplacement: 'dash', + }); + expect(payload?.attachment.name).toBe('custom-missed-spam-example.eml'); + }); }); diff --git a/lib/forward-as-attachment.ts b/lib/forward-as-attachment.ts index 38067d21..3058c2ec 100644 --- a/lib/forward-as-attachment.ts +++ b/lib/forward-as-attachment.ts @@ -1,6 +1,6 @@ import type { Email } from "@/lib/jmap/types"; import { buildForwardSubject } from "@/lib/subject-prefix"; -import { emailExportFilename } from "@/lib/download-filename"; +import { emailExportFilename, type EmailFilenameOptions } from "@/lib/download-filename"; export interface ForwardAsAttachmentEntry { blobId: string; @@ -24,11 +24,19 @@ export interface ForwardAsAttachmentPayload { * not per-email, so the same blobId a message already has can be attached * to a brand new outgoing email directly. * + * `filenameOptions`, when passed, should be the same options the caller + * uses for "Export as .eml" / drag-out (the user's configured filename + * template, space/case/diacritics transforms - see + * useSettingsStore's emailDownloadTemplate and friends), so the two + * actions produce consistent filenames for the same message. Falls back + * to emailExportFilename's own default template when omitted. + * * Returns null when the email has no blobId (nothing to reference). */ export function buildForwardAsAttachmentPayload( email: Email, forwardPrefix: string, + filenameOptions?: EmailFilenameOptions, ): ForwardAsAttachmentPayload | null { if (!email.blobId) return null; @@ -36,7 +44,7 @@ export function buildForwardAsAttachmentPayload( subject: buildForwardSubject(email.subject, forwardPrefix), attachment: { blobId: email.blobId, - name: emailExportFilename(email), + name: emailExportFilename(email, filenameOptions), type: "message/rfc822", size: email.size, },