Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/mail.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgreta <gretadoci@gmail.com>2021-09-08 14:43:35 +0300
committergreta <gretadoci@gmail.com>2021-12-01 17:18:39 +0300
commit35d5d782d1711a37fd710bbdefd4ebd74d818d91 (patch)
treed6613fffdc824b4d33a4ea37db8fabe8e2122113 /src
parent7e14ad8fe990ca27347d06edf4f35c6f7c6f377d (diff)
Add new message into a modal
Signed-off-by: greta <gretadoci@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/components/Composer.vue87
-rw-r--r--src/components/ComposerAttachments.vue2
-rw-r--r--src/components/Envelope.vue28
-rw-r--r--src/components/EnvelopeList.vue23
-rw-r--r--src/components/MailboxThread.vue20
-rw-r--r--src/components/MenuEnvelope.vue28
-rw-r--r--src/components/Navigation.vue30
-rw-r--r--src/components/NewMessageDetail.vue57
-rw-r--r--src/components/NewMessageModal.vue199
-rw-r--r--src/components/RecipientBubble.vue4
-rw-r--r--src/views/Home.vue2
11 files changed, 329 insertions, 151 deletions
diff --git a/src/components/Composer.vue b/src/components/Composer.vue
index dcf1b41cd..83b4f0731 100644
--- a/src/components/Composer.vue
+++ b/src/components/Composer.vue
@@ -150,6 +150,12 @@
:upload-size-limit="attachmentSizeLimit"
@upload="onAttachmentsUploading" />
<div class="composer-actions-right">
+ <button v-if="savingDraft === false"
+ class="button"
+ :title="t('mail', 'Discard & close draft')"
+ @click="discardDraft">
+ {{ t('mail', 'Discard draft') }}
+ </button>
<p class="composer-actions-draft">
<span v-if="!canSaveDraft" id="draft-status">{{ t('mail', 'Cannot save draft because this account does not have a drafts mailbox configured.') }}</span>
<span v-else-if="savingDraft === true" id="draft-status">{{ t('mail', 'Saving draft …') }}</span>
@@ -212,7 +218,14 @@
</div>
</div>
<Loading v-else-if="state === STATES.UPLOADING" :hint="t('mail', 'Uploading attachments …')" role="alert" />
- <Loading v-else-if="state === STATES.SENDING" :hint="t('mail', 'Sending …')" role="alert" />
+ <Loading v-else-if="state === STATES.SENDING"
+ :hint="t('mail', 'Sending …')"
+ role="alert"
+ class="sending-hint" />
+ <Loading v-else-if="state === STATES.DISCARDING" :hint="t('mail', 'Discarding …')" class="emptycontent" />
+ <EmptyContent v-else-if="state === STATES.DISCARDED" icon="icon-mail">
+ <h2>{{ t('mail', 'Draft was discarded!') }}</h2>
+ </EmptyContent>
<div v-else-if="state === STATES.ERROR" class="emptycontent" role="alert">
<h2>{{ t('mail', 'Error sending your message') }}</h2>
<p v-if="errorText">
@@ -237,12 +250,9 @@
{{ t('mail', 'Send anyway') }}
</button>
</div>
- <div v-else class="emptycontent">
+ <EmptyContent v-else icon="icon-checkmark">
<h2>{{ t('mail', 'Message sent!') }}</h2>
- <button v-if="!isReply" class="button primary" @click="reset">
- {{ t('mail', 'Write another message') }}
- </button>
- </div>
+ </EmptyContent>
</template>
<script>
@@ -256,6 +266,7 @@ import Actions from '@nextcloud/vue/dist/Components/Actions'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
import ActionCheckbox from '@nextcloud/vue/dist/Components/ActionCheckbox'
import ActionLink from '@nextcloud/vue/dist/Components/ActionLink'
+import EmptyContent from '@nextcloud/vue/dist/Components/EmptyContent'
import Multiselect from '@nextcloud/vue/dist/Components/Multiselect'
import { showError } from '@nextcloud/dialogs'
import { translate as t } from '@nextcloud/l10n'
@@ -292,6 +303,8 @@ const STATES = Object.seal({
ERROR: 3,
WARNING: 4,
FINISHED: 5,
+ DISCARDING: 6,
+ DISCARDED: 7,
})
export default {
@@ -306,6 +319,7 @@ export default {
Loading,
Multiselect,
TextEditor,
+ EmptyContent,
},
props: {
fromAccount: {
@@ -350,6 +364,11 @@ export default {
required: false,
default: () => undefined,
},
+ forwardedMessages: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
},
data() {
let bodyVal = toHtml(this.body).value
@@ -490,18 +509,6 @@ export default {
this.$refs.toLabel.$el.focus()
}
- // event is triggered when user clicks 'new message' in navigation
- this.$root.$on('newMessage', () => {
- this.draftsPromise
- .then(() => {
- return this.saveDraft(this.getMessageData)
- })
- .then(() => {
- // wait for the draft to be saved before resetting the message content
- this.reset()
- })
- })
-
// Add attachments in case of forward
if (this.forwardFrom?.attachments !== undefined) {
this.forwardFrom.attachments.forEach(att => {
@@ -514,13 +521,12 @@ export default {
})
})
}
-
// Add messages forwarded as attachments
let forwards = []
- if (this.$route.query.forwardedMessages && !isArray(this.$route.query.forwardedMessages)) {
- forwards = [this.$route.query.forwardedMessages]
- } else if (this.$route.query.forwardedMessages && isArray(this.$route.query.forwardedMessages)) {
- forwards = this.$route.query.forwardedMessages
+ if (this.forwardedMessages && !isArray(this.forwardedMessages)) {
+ forwards = [this.forwardedMessages]
+ } else if (this.forwardedMessages && isArray(this.forwardedMessages)) {
+ forwards = this.forwardedMessages
}
forwards.forEach(id => {
const env = this.$store.getters.getEnvelope(id)
@@ -540,8 +546,6 @@ export default {
})
},
beforeDestroy() {
- this.$root.$off('newMessage')
-
window.removeEventListener('mailvelope', this.onMailvelopeLoaded)
},
methods: {
@@ -793,6 +797,7 @@ export default {
this.newRecipients = []
this.requestMdn = false
this.appendSignature = true
+ this.savingDraft = undefined
this.setAlias()
this.initBody()
@@ -815,6 +820,13 @@ export default {
return `${alias.name} <${alias.emailAddress}>`
},
+ async discardDraft() {
+ this.state = STATES.DISCARDING
+ const id = await this.draftsPromise
+ await this.$store.dispatch('deleteMessage', { id })
+ this.state = STATES.DISCARDED
+ this.$emit('close')
+ },
},
}
</script>
@@ -848,6 +860,7 @@ export default {
&.mail-account {
border-top: none;
+ padding-top: 10px;
& > .multiselect {
max-width: none;
@@ -873,7 +886,7 @@ export default {
font-size: 20px;
font-weight: bold;
margin: 0;
- padding: 24px 12px;
+ padding: 24px 20px;
}
.warning-box {
@@ -882,13 +895,15 @@ export default {
}
.message-body {
- min-height: 300px;
+ min-height: 570px;
width: 100%;
margin: 0;
- padding: 12px;
border: none !important;
outline: none !important;
box-shadow: none !important;
+ padding-top: 12px;
+ padding-bottom: 12px;
+ padding-left: 20px;
}
#draft-status {
@@ -902,7 +917,9 @@ export default {
.copy-toggle,
.cc-label,
.bcc-label {
- padding: 12px;
+ padding-top: 12px;
+ padding-bottom: 12px;
+ padding-right: 20px;
cursor: text;
color: var(--color-text-maxcontrast);
width: 100px;
@@ -942,4 +959,16 @@ export default {
.submit-message.send.primary.icon-confirm-white {
color: var(--color-main-background);
}
+.sending-hint {
+ height: 50px;
+ margin-top: 50px;
+}
+.button {
+ background-color: transparent;
+ border: none;
+}
+.emptycontent {
+ margin-top: 250px;
+ height: 120px;
+}
</style>
diff --git a/src/components/ComposerAttachments.vue b/src/components/ComposerAttachments.vue
index 4bf6ef70f..bb873ccca 100644
--- a/src/components/ComposerAttachments.vue
+++ b/src/components/ComposerAttachments.vue
@@ -236,7 +236,7 @@ export default {
.new-message-attachments-action {
display: inline-block;
vertical-align: middle;
- padding: 22px;
+ padding: 10px;
opacity: 0.5;
}
diff --git a/src/components/Envelope.vue b/src/components/Envelope.vue
index 1a360aff9..c98c920ca 100644
--- a/src/components/Envelope.vue
+++ b/src/components/Envelope.vue
@@ -108,20 +108,11 @@
@click.prevent="showEventModal = true">
{{ t('mail', 'Create event') }}
</ActionButton>
- <ActionRouter icon="icon-add"
- :to="{
- name: 'message',
- params: {
- mailboxId: $route.params.mailboxId,
- threadId: 'asNew',
- filter: $route.params.filter,
- },
- query: {
- messageId: data.databaseId,
- },
- }">
+ <ActionButton icon="icon-add"
+ :close-after-click="true"
+ @click.prevent="onOpenEditAsNew">
{{ t('mail', 'Edit as new message') }}
- </ActionRouter>
+ </ActionButton>
<ActionButton icon="icon-delete"
:close-after-click="true"
@click.prevent="onDelete">
@@ -155,13 +146,15 @@
:account="account"
:envelope="data"
@close="onCloseTagModal" />
+ <NewMessageModal v-if="showNewMessage"
+ :template-message-id="data.databaseId"
+ @close="showNewMessage = false" />
</template>
</ListItem>
</template>
<script>
import ListItem from '@nextcloud/vue/dist/Components/ListItem'
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
-import ActionRouter from '@nextcloud/vue/dist/Components/ActionRouter'
import Avatar from './Avatar'
import { calculateAccountColor } from '../util/AccountColor'
import moment from '@nextcloud/moment'
@@ -176,6 +169,7 @@ import { matchError } from '../errors/match'
import MoveModal from './MoveModal'
import TagModal from './TagModal'
import EventModal from './EventModal'
+import NewMessageModal from './NewMessageModal'
export default {
name: 'Envelope',
@@ -184,9 +178,9 @@ export default {
ListItem,
Avatar,
ActionButton,
- ActionRouter,
MoveModal,
TagModal,
+ NewMessageModal,
},
directives: {
draggableEnvelope: DraggableEnvelopeDirective,
@@ -226,6 +220,7 @@ export default {
showMoveModal: false,
showEventModal: false,
showTagModal: false,
+ showNewMessage: false,
}
},
computed: {
@@ -377,6 +372,9 @@ export default {
}))
}
},
+ onOpenEditAsNew() {
+ this.showNewMessage = true
+ },
onOpenMoveModal() {
this.showMoveModal = true
},
diff --git a/src/components/EnvelopeList.vue b/src/components/EnvelopeList.vue
index 60d9053bd..35ac3d823 100644
--- a/src/components/EnvelopeList.vue
+++ b/src/components/EnvelopeList.vue
@@ -116,7 +116,7 @@
<ActionButton
icon="icon-forward"
:close-after-click="true"
- @click.prevent="forwardSelectedAsAttachment">
+ @click.prevent="onOpenNewMessageModal">
{{ n(
'mail',
'Forward {number} as attachment',
@@ -149,6 +149,7 @@
@close="onCloseMoveModal" />
</div>
</transition>
+ <NewMessageModal v-if="showNewMessage" :forwarded-messages="forwardedMessages" @close="showNewMessage = false; forwardedMessages = []" />
<transition-group name="list">
<div id="list-refreshing"
key="loading"
@@ -190,6 +191,7 @@ import NoTrashMailboxConfiguredError
from '../errors/NoTrashMailboxConfiguredError'
import { differenceWith } from 'ramda'
import dragEventBus from '../directives/drag-and-drop/util/dragEventBus'
+import NewMessageModal from './NewMessageModal'
export default {
name: 'EnvelopeList',
@@ -198,6 +200,7 @@ export default {
ActionButton,
Envelope,
MoveModal,
+ NewMessageModal,
},
props: {
account: {
@@ -237,6 +240,8 @@ export default {
selection: [],
showMoveModal: false,
lastToggledIndex: undefined,
+ showNewMessage: false,
+ forwardedMessages: [],
}
},
computed: {
@@ -423,19 +428,13 @@ export default {
this.showMoveModal = true
},
async forwardSelectedAsAttachment() {
- const selected = this.selection
- this.$router.push({
- name: 'message',
- params: {
- mailboxId: this.$route.params.mailboxId,
- threadId: 'new',
- },
- query: {
- forwardedMessages: selected,
- },
- })
+ this.forwardedMessages = this.selection
+ this.showNewMessage = true
this.unselectAll()
},
+ onOpenNewMessageModal() {
+ this.forwardSelectedAsAttachment()
+ },
onCloseMoveModal() {
this.showMoveModal = false
this.unselectAll()
diff --git a/src/components/MailboxThread.vue b/src/components/MailboxThread.vue
index 181c96014..3af61cc2c 100644
--- a/src/components/MailboxThread.vue
+++ b/src/components/MailboxThread.vue
@@ -62,6 +62,9 @@
<NewMessageDetail v-if="newMessage" />
<Thread v-else-if="showThread" @delete="deleteMessage" />
<NoMessageSelected v-else-if="hasEnvelopes && !isMobile" />
+ <NewMessageModal
+ v-if="showComposer"
+ @close="showComposer = false" />
</AppContent>
</template>
@@ -80,6 +83,7 @@ import NewMessageDetail from './NewMessageDetail'
import NoMessageSelected from './NoMessageSelected'
import Thread from './Thread'
import { UNIFIED_ACCOUNT_ID, UNIFIED_INBOX_ID } from '../store/constants'
+import NewMessageModal from './NewMessageModal'
export default {
name: 'MailboxThread',
@@ -95,6 +99,7 @@ export default {
Popover,
SectionTitle,
Thread,
+ NewMessageModal,
},
mixins: [isMobile],
props: {
@@ -121,6 +126,7 @@ export default {
refresh: ['r'],
unseen: ['u'],
},
+ showComposer: false,
}
},
computed: {
@@ -150,13 +156,20 @@ export default {
this.$route.params.threadId === 'new'
|| this.$route.params.threadId === 'reply'
|| this.$route.params.threadId === 'replyAll'
- || this.$route.params.threadId === 'asNew'
)
},
isThreadShown() {
return !!this.$route.params.threadId
},
},
+ watch: {
+ $route() {
+ this.handleMailto()
+ },
+ },
+ created() {
+ this.handleMailto()
+ },
methods: {
deleteMessage(id) {
this.bus.$emit('delete', id)
@@ -184,6 +197,11 @@ export default {
},
})
},
+ handleMailto() {
+ if (this.$route.name === 'message' && this.$route.params.threadId === 'mailto') {
+ this.showComposer = true
+ }
+ },
},
}
</script>
diff --git a/src/components/MenuEnvelope.vue b/src/components/MenuEnvelope.vue
index 5cf0ac0da..720d62a8f 100644
--- a/src/components/MenuEnvelope.vue
+++ b/src/components/MenuEnvelope.vue
@@ -22,20 +22,6 @@
:to="forwardLink">
{{ t('mail', 'Forward') }}
</ActionRouter>
- <ActionRouter icon="icon-add"
- :to="{
- name: 'message',
- params: {
- mailboxId: $route.params.mailboxId,
- threadId: 'asNew',
- filter: $route.params.filter,
- },
- query: {
- messageId: envelope.databaseId,
- },
- }">
- {{ t('mail', 'Edit as new message') }}
- </ActionRouter>
<ActionButton icon="icon-important"
:close-after-click="true"
@click.prevent="onToggleImportant">
@@ -88,6 +74,11 @@
@click.prevent="showEventModal = true">
{{ t('mail', 'Create event') }}
</ActionButton>
+ <ActionButton icon="icon-add"
+ :close-after-click="true"
+ @click="onOpenEditAsNew">
+ {{ t('mail', 'Edit as new message') }}
+ </ActionButton>
<ActionButton v-if="withShowSource"
:icon="sourceLoading ? 'icon-loading-small' : 'icon-details'"
:disabled="sourceLoading"
@@ -129,6 +120,9 @@
:account="account"
:envelope="envelope"
@close="onCloseTagModal" />
+ <NewMessageModal v-if="showNewMessage"
+ :template-message-id="envelope.databaseId"
+ @close="showNewMessage = false" />
</div>
</template>
@@ -149,6 +143,7 @@ import TagModal from './TagModal'
import MoveModal from './MoveModal'
import NoTrashMailboxConfiguredError from '../errors/NoTrashMailboxConfiguredError'
import { showError } from '@nextcloud/dialogs'
+import NewMessageModal from './NewMessageModal'
export default {
name: 'MenuEnvelope',
@@ -161,6 +156,7 @@ export default {
Modal,
MoveModal,
TagModal,
+ NewMessageModal,
},
props: {
envelope: {
@@ -205,6 +201,7 @@ export default {
showMoveModal: false,
showEventModal: false,
showTagModal: false,
+ showNewMessage: false,
}
},
computed: {
@@ -364,6 +361,9 @@ export default {
onCloseTagModal() {
this.showTagModal = false
},
+ onOpenEditAsNew() {
+ this.showNewMessage = true
+ },
},
}
</script>
diff --git a/src/components/Navigation.vue b/src/components/Navigation.vue
index a295b345f..fcb11f200 100644
--- a/src/components/Navigation.vue
+++ b/src/components/Navigation.vue
@@ -27,6 +27,7 @@
button-class="icon-add"
role="complementary"
@click="onNewMessage" />
+ <NewMessageModal v-if="showNewMessage" @close="showNewMessage = false" />
<button v-if="currentMailbox"
class="button icon-history"
:disabled="refreshing"
@@ -88,6 +89,7 @@ import NavigationAccountExpandCollapse from './NavigationAccountExpandCollapse'
import NavigationMailbox from './NavigationMailbox'
import AppSettingsMenu from '../components/AppSettingsMenu'
+import NewMessageModal from './NewMessageModal'
export default {
name: 'Navigation',
@@ -100,10 +102,12 @@ export default {
NavigationAccount,
NavigationAccountExpandCollapse,
NavigationMailbox,
+ NewMessageModal,
},
data() {
return {
refreshing: false,
+ showNewMessage: false,
}
},
computed: {
@@ -147,31 +151,7 @@ export default {
return true
},
onNewMessage() {
- const accountId = this.$route.params.accountId || this.$store.getters.accounts[0].id
-
- const mailboxId = this.$route.params.mailboxId || this.$store.getters.getMailboxes(accountId)[0]?.databaseId
- if (
- this.$router.currentRoute.name === 'message'
- && this.$router.currentRoute.params.threadId === 'new'
- ) {
- // If we already show the composer, navigating to it would be pointless (and doesn't work)
- // instead trigger an event to reset the composer
- this.$root.$emit('newMessage')
- return
- }
-
- this.$router
- .push({
- name: 'message',
- params: {
- mailboxId,
- filter: this.$route.params.filter ? this.$route.params.filter : undefined,
- threadId: 'new',
- },
- })
- .catch((err) => {
- logger.error(err)
- })
+ this.showNewMessage = true
},
isFirst(account) {
const accounts = this.$store.getters.accounts
diff --git a/src/components/NewMessageDetail.vue b/src/components/NewMessageDetail.vue
index 73b4ffbfc..b23e5d5ae 100644
--- a/src/components/NewMessageDetail.vue
+++ b/src/components/NewMessageDetail.vue
@@ -18,7 +18,8 @@
:draft="saveDraft"
:send="sendMessage"
:reply-to="composerData.replyTo"
- :forward-from="composerData.forwardFrom" />
+ :forward-from="composerData.forwardFrom"
+ :template-message-id="templateMessageId" />
</AppContentDetails>
</template>
@@ -26,14 +27,12 @@
import AppContentDetails from '@nextcloud/vue/dist/Components/AppContentDetails'
import Axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
-import { showWarning } from '@nextcloud/dialogs'
import { translate as t } from '@nextcloud/l10n'
import { buildForwardSubject, buildReplySubject, buildRecipients as buildReplyRecipients } from '../ReplyBuilder'
import Composer from './Composer'
-import Error from './Error'
import { getRandomMessageErrorMessage } from '../util/ErrorMessageFactory'
-import { detect, html, plain, toPlain } from '../util/text'
+import { html, plain, toPlain } from '../util/text'
import Loading from './Loading'
import logger from '../logger'
import { saveDraft, sendMessage } from '../service/MessageService'
@@ -43,7 +42,6 @@ export default {
components: {
AppContentDetails,
Composer,
- Error,
Loading,
},
data() {
@@ -55,6 +53,7 @@ export default {
errorMessage: '',
error: undefined,
newDraftId: undefined,
+ templateMessageId: undefined,
}
},
computed: {
@@ -104,21 +103,6 @@ export default {
originalBody: this.originalBody,
replyTo: message,
}
- } else if (this.$route.params.threadId === 'asNew') {
- logger.debug('composing as new', { original: this.original })
-
- if (this.original.attachments.length) {
- showWarning(t('mail', 'Attachments were not copied. Please add them manually.'))
- }
-
- return {
- accountId: message.accountId,
- to: message.to,
- cc: message.cc,
- subject: message.subject,
- body: this.originalBody,
- originalBody: this.originalBody,
- }
} else {
// forward
return {
@@ -132,24 +116,7 @@ export default {
}
}
} else {
- // New or mailto: message
- logger.debug('composing a new message or handling a mailto link', {
- threadId: this.$route.params.threadId,
- })
-
- let accountId
- // Only preselect an account when we're not in a unified mailbox
- if (this.$route.params.accountId !== 0 && this.$route.params.accountId !== '0') {
- accountId = parseInt(this.$route.params.accountId, 10)
- }
-
- return {
- accountId,
- to: this.stringToRecipients(this.$route.query.to),
- cc: this.stringToRecipients(this.$route.query.cc),
- subject: this.$route.query.subject || '',
- body: this.$route.query.body ? detect(this.$route.query.body) : html(''),
- }
+ throw new Error('new message details can only be for replies and forwards')
}
},
},
@@ -179,18 +146,6 @@ export default {
this.fetchMessage()
},
methods: {
- stringToRecipients(str) {
- if (str === undefined) {
- return []
- }
-
- return [
- {
- label: str,
- email: str,
- },
- ]
- },
fetchMessage() {
if (this.$route.params.draftId !== undefined) {
return this.fetchDraftMessage(this.$route.params.draftId)
@@ -301,7 +256,7 @@ export default {
const account = this.$store.getters.getAccount(data.account)
if (parseInt(this.$route.params.mailboxId, 10) === account.draftsMailboxId) {
this.newDraftId = id
- this.$router.replace({
+ await this.$router.replace({
to: 'message',
params: {
mailboxId: this.$route.params.mailboxId,
diff --git a/src/components/NewMessageModal.vue b/src/components/NewMessageModal.vue
new file mode 100644
index 000000000..c8abf4bdf
--- /dev/null
+++ b/src/components/NewMessageModal.vue
@@ -0,0 +1,199 @@
+<template>
+ <Modal
+ size="normal"
+ :title="t('mail', 'New message')"
+ @close="$emit('close')">
+ <Composer v-if="!fetchingTemplateMessage"
+ :from-account="composerData.accountId"
+ :to="composerData.to"
+ :cc="composerData.cc"
+ :bcc="composerData.bcc"
+ :subject="composerData.subject"
+ :body="composerData.body"
+ :draft="saveDraft"
+ :send="sendMessage"
+ :forwarded-messages="forwardedMessages" />
+ </Modal>
+</template>
+<script>
+import Modal from '@nextcloud/vue/dist/Components/Modal'
+import logger from '../logger'
+import { detect, html, plain, toPlain } from '../util/text'
+import { saveDraft, sendMessage } from '../service/MessageService'
+import Composer from './Composer'
+import { showWarning } from '@nextcloud/dialogs'
+import Axios from '@nextcloud/axios'
+import { generateUrl } from '@nextcloud/router'
+import { translate as t } from '@nextcloud/l10n'
+export default {
+ name: 'NewMessageModal',
+ components: {
+ Modal,
+ Composer,
+ },
+ props: {
+ forwardedMessages: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ templateMessageId: {
+ type: Number,
+ required: false,
+ default: undefined,
+ },
+ },
+ data() {
+ return {
+ original: undefined,
+ originalBody: undefined,
+ fetchingTemplateMessage: true,
+ }
+ },
+ computed: {
+ composerData() {
+ logger.debug('composing a new message or handling a mailto link', {
+ threadId: this.$route.params.threadId,
+ })
+
+ let accountId
+ // Only preselect an account when we're not in a unified mailbox
+ if (this.$route.params.accountId !== 0 && this.$route.params.accountId !== '0') {
+ accountId = parseInt(this.$route.params.accountId, 10)
+ }
+ if (this.templateMessageId !== undefined) {
+ if (this.original.attachments.length) {
+ showWarning(t('mail', 'Attachments were not copied. Please add them manually.'))
+ }
+
+ return {
+ accountId: this.original.accountId,
+ to: this.original.to,
+ cc: this.original.cc,
+ subject: this.original.subject,
+ body: this.originalBody,
+ originalBody: this.originalBody,
+ }
+ }
+
+ return {
+ accountId,
+ to: this.stringToRecipients(this.$route.query.to),
+ cc: this.stringToRecipients(this.$route.query.cc),
+ subject: this.$route.query.subject || '',
+ body: this.$route.query.body ? detect(this.$route.query.body) : html(''),
+ }
+ },
+ },
+ created() {
+ this.fetchOriginalMessage()
+ },
+ methods: {
+ stringToRecipients(str) {
+ if (str === undefined) {
+ return []
+ }
+
+ return [
+ {
+ label: str,
+ email: str,
+ },
+ ]
+ },
+ async saveDraft(data) {
+ if (data.draftId === undefined && this.draft) {
+ logger.debug('draft data does not have a draftId, adding one', {
+ draft: this.draft,
+ data,
+ id: this.draft.databaseId,
+ })
+ data.draftId = this.draft.databaseId
+ }
+ const dataForServer = {
+ ...data,
+ body: data.isHtml ? data.body.value : toPlain(data.body).value,
+ }
+ const { id } = await saveDraft(data.account, dataForServer)
+
+ // Remove old draft envelope
+ this.$store.commit('removeEnvelope', { id: data.draftId })
+ this.$store.commit('removeMessage', { id: data.draftId })
+
+ // Fetch new draft envelope
+ await this.$store.dispatch('fetchEnvelope', id)
+
+ return id
+ },
+ async sendMessage(data) {
+ logger.debug('sending message', { data })
+ const dataForServer = {
+ ...data,
+ body: data.isHtml ? data.body.value : toPlain(data.body).value,
+ }
+ await sendMessage(data.account, dataForServer)
+
+ // Remove old draft envelope
+ this.$store.commit('removeEnvelope', { id: data.draftId })
+ this.$store.commit('removeMessage', { id: data.draftId })
+ },
+ async fetchOriginalMessage() {
+ if (this.templateMessageId === undefined) {
+ this.fetchingTemplateMessage = false
+ return
+ }
+ this.loading = true
+ this.error = undefined
+ this.errorMessage = ''
+
+ logger.debug(`fetching original message ${this.templateMessageId}`)
+
+ try {
+ const message = await this.$store.dispatch('fetchMessage', this.templateMessageId)
+ logger.debug('original message fetched', { message })
+ this.original = message
+
+ let body = plain(message.body || '')
+ if (message.hasHtmlBody) {
+ logger.debug('original message has HTML body')
+ const resp = await Axios.get(
+ generateUrl('/apps/mail/api/messages/{id}/html?plain=true', {
+ Id: this.templateMessageId,
+ })
+ )
+
+ body = html(resp.data)
+ }
+ this.originalBody = body
+ } catch (error) {
+ logger.error('could not load original message ' + this.templateMessageId, { error })
+ if (error.isError) {
+ this.errorMessage = t('mail', 'Could not load original message')
+ this.error = error
+ this.loading = false
+ }
+ } finally {
+ this.loading = false
+ }
+ this.fetchingTemplateMessage = false
+ },
+ },
+}
+
+</script>
+
+<style lang="scss" scoped>
+@media only screen and (max-width: 600px) {
+ ::v-deep .modal-container {
+ max-width: 80%;
+ }
+}
+::v-deep .modal-container {
+ width: 80%;
+ min-height: 60%;
+}
+::v-deep .modal-wrapper .modal-container {
+ overflow-y: auto !important;
+ overflow-x: auto !important;
+}
+</style>
diff --git a/src/components/RecipientBubble.vue b/src/components/RecipientBubble.vue
index 95b3af813..b34156ef8 100644
--- a/src/components/RecipientBubble.vue
+++ b/src/components/RecipientBubble.vue
@@ -171,8 +171,8 @@ export default {
this.$router.push({
name: 'message',
params: {
- mailboxId: 'priority', // TODO: figure out current mailbox
- threadId: 'new',
+ mailboxId: this.$route.params.mailboxId,
+ threadId: 'mailto',
},
query: {
to: this.email,
diff --git a/src/views/Home.vue b/src/views/Home.vue
index 0007a7d8d..f7f9b1628 100644
--- a/src/views/Home.vue
+++ b/src/views/Home.vue
@@ -75,7 +75,7 @@ export default {
name: 'message',
params: {
mailboxId: firstMailbox.databaseId,
- threadId: 'new',
+ threadId: 'mailto',
},
query: {
to: this.$route.query.to,