diff --git a/src/components/NewMessageModal.vue b/src/components/NewMessageModal.vue index 8446e22325..33097862b8 100644 --- a/src/components/NewMessageModal.vue +++ b/src/components/NewMessageModal.vue @@ -113,6 +113,7 @@ import { UNDO_DELAY } from '../store/constants' import { matchError } from '../errors/match' import NoSentMailboxConfiguredError from '../errors/NoSentMailboxConfiguredError' import ManyRecipientsError from '../errors/ManyRecipientsError' +import AttachmentMissingError from '../errors/AttachmentMissingError.js' import Loading from './Loading' import { mapGetters } from 'vuex' import MinimizeIcon from 'vue-material-design-icons/Minus.vue' @@ -305,6 +306,20 @@ export default { if (dataForServer.sendAt < Math.floor((now + UNDO_DELAY) / 1000)) { dataForServer.sendAt = Math.floor((now + UNDO_DELAY) / 1000) } + + if (!data.force && data.attachments.length === 0) { + const lines = toPlain(data.body).value.toLowerCase().split('\n') + const wordAttachment = t('mail', 'attachment').toLowerCase() + const wordAttached = t('mail', 'attached').toLowerCase() + for (let line of lines) { + if (line.startsWith('>') || line.startsWith('--')) { + break + } + if (line.includes(wordAttachment) || line.includes(wordAttached)) { + throw new AttachmentMissingError() + } + } + } if (!this.composerData.id) { const { id } = await saveDraft(data.account, dataForServer) @@ -340,9 +355,15 @@ export default { return t('mail', 'You are trying to send to many recipients in To and/or Cc. Consider using Bcc to hide recipient addresses.') }, default(error) { - if (error && error.toString) { - return error.toString() - } + return undefined + }, + }) + this.warning = await matchError(error, { + [AttachmentMissingError.getName()]() { + return t('mail', 'You mentioned an attachment. Did you forget to add it?') + }, + default(error) { + return undefined }, }) } finally { diff --git a/src/errors/AttachmentMissingError.js b/src/errors/AttachmentMissingError.js new file mode 100644 index 0000000000..c00c3b0136 --- /dev/null +++ b/src/errors/AttachmentMissingError.js @@ -0,0 +1,32 @@ +/** + * @author 2023 Maximilian Martin + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +export default class AttachmentMissingError extends Error { + + constructor(message) { + super(message) + this.name = AttachmentMissingError.getName() + this.message = message + } + + static getName() { + return 'AttachmentMissingError' + } + +}