From f1d0511cbb4c0015ffa1050ee1a4352ab2161559 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 22 May 2026 11:56:29 -0400 Subject: [PATCH] feat: recipient details Signed-off-by: Sebastian --- src/components/MessageComposer.vue | 22 ++- src/components/MessageList.vue | 20 ++- src/components/common/RecipientDetails.vue | 183 ++++++++++++++++++++ src/components/composer/ComposerToolbar.vue | 6 +- src/components/reader/ReaderHeader.vue | 43 ++++- src/pages/MailPage.vue | 23 ++- src/stores/mailUiStore.ts | 39 +++-- src/types/composer.ts | 5 + 8 files changed, 297 insertions(+), 44 deletions(-) create mode 100644 src/components/common/RecipientDetails.vue create mode 100644 src/types/composer.ts diff --git a/src/components/MessageComposer.vue b/src/components/MessageComposer.vue index b221085..91959b0 100644 --- a/src/components/MessageComposer.vue +++ b/src/components/MessageComposer.vue @@ -10,14 +10,16 @@ import Placeholder from '@tiptap/extension-placeholder' import { EntityObject } from '@MailManager/models/entity' import type { CollectionObject } from '@MailManager/models' import { useMailStore } from '@/stores/mailStore' +import type { MessageAddressInterface } from '@MailManager/types/message' +import { ComposerMode } from '@/types/composer' import ComposerToolbar from '@/components/composer/ComposerToolbar.vue' import ComposerRecipients from '@/components/composer/ComposerRecipients.vue' import ComposerEditor from '@/components/composer/ComposerEditor.vue' // Props interface Props { - mode: 'new' | 'reply' | 'forward' - source?: EntityObject | null + mode: ComposerMode + source?: EntityObject | MessageAddressInterface | null folder?: CollectionObject | null } @@ -83,7 +85,15 @@ function initializeComposerFromProps() { mailStore.resetComposerState() resetComposerFields() - if (!props.source) { + if (props.mode === ComposerMode.Fresh) { + if (props.source && 'address' in props.source) { + // If source is an email address, pre-fill the "To" field + to.value = [props.source.address] + } + return + } + + if (props.source instanceof EntityObject == false) { return } @@ -94,19 +104,19 @@ function initializeComposerFromProps() { const sentAt = sourceMessage.sent || props.source.created || '' const sentLabel = sentAt ? new Date(sentAt).toLocaleString() : 'an unknown time' - if (props.mode === 'reply') { + if (props.mode === ComposerMode.Reply) { const fromEmail = sourceMessage.replyTo?.[0]?.address || sourceMessage.from?.address to.value = fromEmail ? [fromEmail] : [] subject.value = /^Re:/i.test(originalSubject) ? originalSubject : `Re: ${originalSubject}` editor.value?.commands.setContent( - `


On ${sentLabel}, ${senderName} wrote:

${originalBody}
`, + `


---------- Original message ---------

From: ${senderName}

Date: ${sentLabel}

Subject: ${originalSubject}

${originalBody}
`, ) return } - if (props.mode === 'forward') { + if (props.mode === ComposerMode.Forward) { subject.value = /^Fwd:/i.test(originalSubject) ? originalSubject : `Fwd: ${originalSubject}` diff --git a/src/components/MessageList.vue b/src/components/MessageList.vue index e02ef19..b8a6db7 100644 --- a/src/components/MessageList.vue +++ b/src/components/MessageList.vue @@ -3,6 +3,7 @@ import { computed, onBeforeUnmount, ref } from 'vue' import type { EntityIdentifier } from '@MailManager/types/common' import type { EntityObject } from '@MailManager/models' import type { CollectionObject } from '@MailManager/models/collection' +import RecipientDetails from '@/components/common/RecipientDetails.vue' // Props interface Props { @@ -363,7 +364,11 @@ onBeforeUnmount(() => { - {{ message.properties.from?.label || message.properties.from?.address || 'Unknown Sender' }} + + + {{ formatDate(timeStamp(message)) }} @@ -519,6 +524,19 @@ onBeforeUnmount(() => { background-color: rgba(var(--v-theme-primary), 0.14); } +.message-person-link { + display: inline-block; + max-width: 100%; + border-radius: 4px; + padding: 1px 4px; + margin: -1px -4px; + transition: background-color 0.2s ease; +} + +.message-person-link:hover { + background-color: rgba(var(--v-theme-primary), 0.08); +} + @media (max-width: 960px) { .selection-summary { flex-direction: column; diff --git a/src/components/common/RecipientDetails.vue b/src/components/common/RecipientDetails.vue new file mode 100644 index 0000000..476e6c2 --- /dev/null +++ b/src/components/common/RecipientDetails.vue @@ -0,0 +1,183 @@ + + + + + \ No newline at end of file diff --git a/src/components/composer/ComposerToolbar.vue b/src/components/composer/ComposerToolbar.vue index f7dc47e..068efc2 100644 --- a/src/components/composer/ComposerToolbar.vue +++ b/src/components/composer/ComposerToolbar.vue @@ -1,6 +1,8 @@