mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-01 00:07:01 +00:00
fix: send the quoted inline images along with replies and forwards
This commit is contained in:
@@ -27,3 +27,25 @@ describe('replyComposeParams', () => {
|
|||||||
expect(replyComposeParams('reply', source, undefined, ' ')?.prefillBody).toBeUndefined();
|
expect(replyComposeParams('reply', source, undefined, ' ')?.prefillBody).toBeUndefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('replyComposeParams: quoted inline images', () => {
|
||||||
|
const quotedImage = { blobId: 'b-img', type: 'image/png', name: 'logo.png', disposition: 'inline', cid: '<logo@x>' };
|
||||||
|
const unusedInline = { blobId: 'b-sig', type: 'image/png', name: 'sig.png', disposition: 'inline', cid: 'sig@x' };
|
||||||
|
const file = { blobId: 'b-pdf', type: 'application/pdf', name: 'report.pdf', disposition: 'attachment' };
|
||||||
|
const withImage = {
|
||||||
|
...source,
|
||||||
|
htmlBody: [{ partId: '2', type: 'text/html' }],
|
||||||
|
textBody: [{ partId: '1', type: 'text/plain' }],
|
||||||
|
bodyValues: { 1: { value: 'Hi' }, 2: { value: '<p>Hi <img src="cid:logo@x"></p>' } },
|
||||||
|
attachments: [quotedImage, unusedInline, file],
|
||||||
|
} as unknown as Email;
|
||||||
|
|
||||||
|
it('hands a reply the image its quote embeds and nothing else', () => {
|
||||||
|
expect(replyComposeParams('reply', withImage)?.replyTo?.attachments).toEqual([quotedImage]);
|
||||||
|
expect(replyComposeParams('reply', source)?.replyTo?.attachments).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('hands a forward the quoted image and the files, not unused inline parts', () => {
|
||||||
|
expect(replyComposeParams('forward', withImage)?.replyTo?.attachments).toEqual([quotedImage, file]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,6 +1,23 @@
|
|||||||
import type { Email } from '../api/types';
|
import type { Attachment, Email } from '../api/types';
|
||||||
import type { RootStackParamList } from '../navigation/types';
|
import type { RootStackParamList } from '../navigation/types';
|
||||||
import { pickEmailBody, plainTextBody } from './email-body';
|
import { pickEmailBody, plainTextBody } from './email-body';
|
||||||
|
import { extractCidRefs } from './email-html';
|
||||||
|
import { stripMessageIdBrackets } from './email-threading';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parts a reply or forward hands the composer. The inline images the
|
||||||
|
* quoted HTML embeds go along in both modes: the composer fetches them into
|
||||||
|
* the quote and attaches them again on send (it never shows them as chips).
|
||||||
|
* Without them a quoted `cid:` image went out pointing at a part the new
|
||||||
|
* message did not have. A forward also carries the real attachments.
|
||||||
|
*/
|
||||||
|
function carriedParts(mode: 'reply' | 'replyAll' | 'forward', source: Email, quoteHtml?: string): Attachment[] | undefined {
|
||||||
|
const quoted = new Set(quoteHtml ? extractCidRefs(quoteHtml) : []);
|
||||||
|
const isQuoted = (a: Attachment) => !!a.cid && quoted.has(stripMessageIdBrackets(a.cid));
|
||||||
|
const parts = (source.attachments ?? []).filter((a) =>
|
||||||
|
isQuoted(a) || (mode === 'forward' && !(a.disposition === 'inline' && a.cid)));
|
||||||
|
return parts.length > 0 || mode === 'forward' ? parts : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Composer params for a reply / reply-all / forward of `source`. Shared by
|
* Composer params for a reply / reply-all / forward of `source`. Shared by
|
||||||
@@ -42,11 +59,7 @@ export function replyComposeParams(
|
|||||||
// Threading needs the RFC Message-ID, never the JMAP object id (#234).
|
// Threading needs the RFC Message-ID, never the JMAP object id (#234).
|
||||||
messageId: source.messageId ?? undefined,
|
messageId: source.messageId ?? undefined,
|
||||||
references: source.references ?? undefined,
|
references: source.references ?? undefined,
|
||||||
// Forward carries the original attachments as blob refs; cid-embedded
|
attachments: carriedParts(mode, source, quoteHtml),
|
||||||
// inline images are already part of the quoted HTML.
|
|
||||||
attachments: mode === 'forward'
|
|
||||||
? (source.attachments ?? []).filter((a) => !(a.disposition === 'inline' && a.cid))
|
|
||||||
: undefined,
|
|
||||||
originalEmailId: source.id,
|
originalEmailId: source.id,
|
||||||
jmapAccountId: ownerAccountId,
|
jmapAccountId: ownerAccountId,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user