mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-04 16:14:07 +00:00
61 lines
2.8 KiB
TypeScript
61 lines
2.8 KiB
TypeScript
import type { ComposerDraftData } from '@/components/email/email-composer';
|
|
import { findDraftIdentityIdForLogin, type DraftSource } from '@/lib/draft-source';
|
|
import { getDraftComposerBody } from '@/lib/email-body-selection';
|
|
import type { Email, Identity } from '@/lib/jmap/types';
|
|
import { messagePriorityFromHeaders } from '@/lib/message-priority';
|
|
import { reopenedLabelChoice } from '@/lib/outgoing/classification';
|
|
|
|
/**
|
|
* What a composer starts from when a saved draft is opened: from the list, or from
|
|
* last time the desktop app was running. `draft` has its full body.
|
|
*/
|
|
export function composerDataFromDraft(
|
|
draft: Email,
|
|
{ accountId, localAccountId, identities, noSubject }: DraftSource & { identities: Identity[]; noSubject: string },
|
|
): ComposerDraftData {
|
|
const { body, plainTextMode } = getDraftComposerBody(draft);
|
|
return {
|
|
to: draft.to?.map((a) => a.email).filter(Boolean).join(', ') || '',
|
|
cc: draft.cc?.map((a) => a.email).filter(Boolean).join(', ') || '',
|
|
bcc: draft.bcc?.map((a) => a.email).filter(Boolean).join(', ') || '',
|
|
// Drafts saved before #1189 stored an empty subject as the composer's
|
|
// "(No Subject)" placeholder; reopen those with an empty field.
|
|
subject: draft.subject && draft.subject !== noSubject ? draft.subject : '',
|
|
body,
|
|
// Re-open in the format the draft was written in (#1022).
|
|
plainTextMode,
|
|
showCc: (draft.cc?.length || 0) > 0,
|
|
showBcc: (draft.bcc?.length || 0) > 0,
|
|
// Restore the identity the draft was composed with: the saved From (name and
|
|
// address) against the list the composer renders, so a draft from a non-active
|
|
// account, or one of two identities sharing an address, isn't reset to the default.
|
|
selectedIdentityId: findDraftIdentityIdForLogin(identities, draft.from?.[0], localAccountId),
|
|
subAddressTag: '',
|
|
mode: 'compose',
|
|
draftId: draft.id,
|
|
draftAccountId: accountId,
|
|
draftLocalAccountId: localAccountId,
|
|
// A reply draft re-opens in compose mode; its threading headers must
|
|
// come along or the reply leaves its thread.
|
|
inReplyTo: draft.inReplyTo ?? undefined,
|
|
references: draft.references ?? undefined,
|
|
priority: messagePriorityFromHeaders(draft.headers),
|
|
// A sent message brought back (Undo, Cancel and edit) has no draft
|
|
// marker: its SIO-Label says which label it went out with.
|
|
classification: reopenedLabelChoice(draft.headers, localAccountId),
|
|
// Existing server-side attachments must ride along, or the composer
|
|
// starts empty and the next save/send silently rebuilds the draft
|
|
// without them (#849).
|
|
attachments: (draft.attachments ?? [])
|
|
.filter((a) => !!a.blobId)
|
|
.map((a) => ({
|
|
blobId: a.blobId,
|
|
name: a.name,
|
|
type: a.type,
|
|
size: a.size,
|
|
cid: a.cid,
|
|
disposition: a.disposition,
|
|
})),
|
|
};
|
|
}
|