import ko from 'ko';
import {
Notification,
UploadErrorCode
} from 'Common/Enums';
import {
ComposeType,
EditorDefaultType,
SetSystemFoldersNotification
} from 'Common/EnumsUser';
import { pInt, isArray, arrayLength, forEachObjectEntry } from 'Common/Utils';
import { encodeHtml, HtmlEditor, htmlToPlain } from 'Common/Html';
import { koArrayWithDestroy } from 'External/ko';
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
import { messagesDeleteHelper } from 'Common/Folders';
import { serverRequest } from 'Common/Links';
import { i18n, getNotification, getUploadErrorDescByCode, timestampToString } from 'Common/Translator';
import { MessageFlagsCache, setFolderHash } from 'Common/Cache';
import { Settings, SettingsCapa, SettingsGet, elementById, addShortcut } from 'Common/Globals';
//import { exitFullscreen, isFullscreen, toggleFullscreen } from 'Common/Fullscreen';
import { AppUserStore } from 'Stores/User/App';
import { SettingsUserStore } from 'Stores/User/Settings';
import { IdentityUserStore } from 'Stores/User/Identity';
import { AccountUserStore } from 'Stores/User/Account';
import { FolderUserStore } from 'Stores/User/Folder';
import { PgpUserStore } from 'Stores/User/Pgp';
import { OpenPGPUserStore } from 'Stores/User/OpenPGP';
import { GnuPGUserStore } from 'Stores/User/GnuPG';
import { MessageUserStore } from 'Stores/User/Message';
import { MessagelistUserStore } from 'Stores/User/Messagelist';
import Remote from 'Remote/User/Fetch';
import { ComposeAttachmentModel } from 'Model/ComposeAttachment';
import { EmailModel } from 'Model/Email';
import { decorateKoCommands, showScreenPopup } from 'Knoin/Knoin';
import { AbstractViewPopup } from 'Knoin/AbstractViews';
import { FolderSystemPopupView } from 'View/Popup/FolderSystem';
import { AskPopupView } from 'View/Popup/Ask';
import { ContactsPopupView } from 'View/Popup/Contacts';
/*
import { ThemeStore } from 'Stores/Theme';
let alreadyFullscreen;
*/
const
ScopeCompose = 'Compose',
base64_encode = text => btoa(unescape(encodeURIComponent(text))).match(/.{1,76}/g).join('\r\n'),
email = new EmailModel(),
getEmail = value => {
email.clear();
email.parse(value.trim());
return email.email || false;
},
/**
* @param {Array} aList
* @param {boolean} bFriendly
* @returns {string}
*/
emailArrayToStringLineHelper = (aList, bFriendly) =>
aList.map(item => item.toLine(bFriendly)).join(', '),
reloadDraftFolder = () => {
const draftsFolder = FolderUserStore.draftsFolder();
if (draftsFolder && UNUSED_OPTION_VALUE !== draftsFolder) {
setFolderHash(draftsFolder, '');
if (FolderUserStore.currentFolderFullName() === draftsFolder) {
MessagelistUserStore.reload(true);
} else {
rl.app.folderInformation(draftsFolder);
}
}
},
findIdentityByMessage = (composeType, message) => {
let resultIdentity = null;
const find = addresses => {
addresses = addresses.map(item => item.email);
return IdentityUserStore.find(item => addresses.includes(item.email()));
};
if (message) {
switch (composeType) {
case ComposeType.Reply:
case ComposeType.ReplyAll:
case ComposeType.Forward:
case ComposeType.ForwardAsAttachment:
resultIdentity = find(message.to.concat(message.cc, message.bcc))/* || find(message.deliveredTo)*/;
break;
case ComposeType.Draft:
resultIdentity = find(message.from.concat(message.replyTo));
break;
// no default
// case ComposeType.Empty:
}
}
return resultIdentity || IdentityUserStore()[0] || null;
},
/**
* @param {Function} fKoValue
* @param {Array} emails
*/
addEmailsTo = (fKoValue, emails) => {
if (arrayLength(emails)) {
const value = fKoValue().trim(),
values = emails.map(item => item ? item.toLine() : null)
.validUnique();
fKoValue(value + (value ? ', ' : '') + values.join(', ').trim());
}
},
isPlainEditor = () => {
let type = SettingsUserStore.editorDefaultType();
return EditorDefaultType.Html !== type;
},
/**
* @param {string} prefix
* @param {string} subject
* @returns {string}
*/
replySubjectAdd = (prefix, subject) => {
prefix = prefix.toUpperCase().trim();
subject = subject.replace(/\s+/g, ' ').trim();
let drop = false,
re = 'RE' === prefix,
fwd = 'FWD' === prefix;
const parts = [],
prefixIsRe = !fwd;
if (subject) {
subject.split(':').forEach(part => {
const trimmedPart = part.trim();
if (!drop && (/^(RE|FWD)$/i.test(trimmedPart) || /^(RE|FWD)[[(][\d]+[\])]$/i.test(trimmedPart))) {
if (!re) {
re = !!/^RE/i.test(trimmedPart);
}
if (!fwd) {
fwd = !!/^FWD/i.test(trimmedPart);
}
} else {
parts.push(part);
drop = true;
}
});
}
if (prefixIsRe) {
re = false;
} else {
fwd = false;
}
return ((prefixIsRe ? 'Re: ' : 'Fwd: ') + (re ? 'Re: ' : '')
+ (fwd ? 'Fwd: ' : '') + parts.join(':').trim()).trim();
};
ko.extenders.toggleSubscribe = (target, options) => {
target.subscribe(options[1], options[0], 'beforeChange');
target.subscribe(options[2], options[0]);
return target;
};
class MimePart {
constructor() {
this.headers = {};
this.body = '';
this.boundary = '';
this.children = [];
}
toString() {
const hasSub = this.children.length,
boundary = this.boundary || (this.boundary = 'part' + Jua.randomId()),
headers = this.headers;
if (hasSub) {
headers['Content-Type'] += `; boundary="${boundary}"`;
}
let result = Object.entries(headers).map(([key, value]) => `${key}: ${value}`).join('\r\n') + '\r\n';
if (this.body) {
result += '\r\n' + this.body.replace(/\r?\n/g, '\r\n');
}
if (hasSub) {
this.children.forEach(part => result += '\r\n--' + boundary + '\r\n' + part);
result += '\r\n--' + boundary + '--\r\n';
}
return result;
}
}
export class ComposePopupView extends AbstractViewPopup {
constructor() {
super('Compose');
const fEmailOutInHelper = (context, identity, name, isIn) => {
if (identity && context && identity[name]() && (isIn ? true : context[name]())) {
const identityEmail = identity[name]();
let list = context[name]().trim().split(',');
list = list.filter(email => {
email = email.trim();
return email && identityEmail.trim() !== email;
});
if (isIn) {
list.push(identityEmail);
}
context[name](list.join(','));
}
};
this.oLastMessage = null;
this.oEditor = null;
this.aDraftInfo = null;
this.sInReplyTo = '';
this.bFromDraft = false;
this.sReferences = '';
this.sLastFocusedField = 'to';
this.allowContacts = AppUserStore.allowContacts();
this.allowIdentities = SettingsCapa('Identities');
this.bSkipNextHide = false;
this.addObservables({
identitiesDropdownTrigger: false,
from: '',
to: '',
cc: '',
bcc: '',
replyTo: '',
subject: '',
isHtml: false,
requestDsn: false,
requestReadReceipt: false,
markAsImportant: false,
sendError: false,
sendSuccessButSaveError: false,
savedError: false,
sendErrorDesc: '',
savedErrorDesc: '',
savedTime: 0,
emptyToError: false,
attachmentsInProcessError: false,
attachmentsInErrorError: false,
showCc: false,
showBcc: false,
showReplyTo: false,
pgpSign: false,
canPgpSign: false,
pgpEncrypt: false,
canPgpEncrypt: false,
canMailvelope: false,
draftsFolder: '',
draftUid: 0,
sending: false,
saving: false,
viewArea: 'body',
attacheMultipleAllowed: false,
addAttachmentEnabled: false,
editorArea: null, // initDom
currentIdentity: IdentityUserStore()[0]
});
// this.to.subscribe((v) => console.log(v));
// Used by ko.bindingHandlers.emailsTags
this.to.focused = ko.observable(false);
this.to.focused.subscribe(value => value && (this.sLastFocusedField = 'to'));
this.cc.focused = ko.observable(false);
this.cc.focused.subscribe(value => value && (this.sLastFocusedField = 'cc'));
this.bcc.focused = ko.observable(false);
this.bcc.focused.subscribe(value => value && (this.sLastFocusedField = 'bcc'));
this.attachments = koArrayWithDestroy();
this.dragAndDropOver = ko.observable(false).extend({ debounce: 1 });
this.dragAndDropVisible = ko.observable(false).extend({ debounce: 1 });
this.currentIdentity.extend({
toggleSubscribe: [
this,
(identity) => {
fEmailOutInHelper(this, identity, 'bcc');
fEmailOutInHelper(this, identity, 'replyTo');
},
(identity) => {
fEmailOutInHelper(this, identity, 'bcc', true);
fEmailOutInHelper(this, identity, 'replyTo', true);
}
]
});
this.tryToClosePopup = this.tryToClosePopup.debounce(200);
this.iTimer = 0;
this.addComputables({
sendButtonSuccess: () => !this.sendError() && !this.sendSuccessButSaveError(),
savedTimeText: () =>
this.savedTime() ? i18n('COMPOSE/SAVED_TIME', { TIME: this.savedTime().format('LT') }) : '',
emptyToErrorTooltip: () => (this.emptyToError() ? i18n('COMPOSE/EMPTY_TO_ERROR_DESC') : ''),
attachmentsErrorTooltip: () => {
let result = '';
switch (true) {
case this.attachmentsInProcessError():
result = i18n('COMPOSE/ATTACHMENTS_UPLOAD_ERROR_DESC');
break;
case this.attachmentsInErrorError():
result = i18n('COMPOSE/ATTACHMENTS_ERROR_DESC');
break;
// no default
}
return result;
},
attachmentsInProcess: () => this.attachments.filter(item => item && !item.complete()),
attachmentsInError: () => this.attachments.filter(item => item && item.error()),
attachmentsCount: () => this.attachments.length,
attachmentsInErrorCount: () => this.attachmentsInError.length,
attachmentsInProcessCount: () => this.attachmentsInProcess.length,
isDraftFolderMessage: () => this.draftsFolder() && this.draftUid(),
identitiesOptions: () =>
IdentityUserStore.map(item => ({
item: item,
optValue: item.id(),
optText: item.formattedName()
})),
canBeSentOrSaved: () => !this.sending() && !this.saving()
});
this.addSubscribables({
sendError: value => !value && this.sendErrorDesc(''),
savedError: value => !value && this.savedErrorDesc(''),
sendSuccessButSaveError: value => !value && this.savedErrorDesc(''),
currentIdentity: value => value && this.from(value.formattedName()),
from: value => {
this.canPgpSign(false);
value = getEmail(value);
value && PgpUserStore.getKeyForSigning(value).then(result => {
console.log({
email: value,
canPgpSign:result
});
this.canPgpSign(result)
});
},
cc: value => {
if (false === this.showCc() && value.length) {
this.showCc(true);
}
this.initPgpEncrypt();
},
bcc: value => {
if (false === this.showBcc() && value.length) {
this.showBcc(true);
}
this.initPgpEncrypt();
},
replyTo: value => {
if (false === this.showReplyTo() && value.length) {
this.showReplyTo(true);
}
},
attachmentsInErrorCount: value => {
if (0 === value) {
this.attachmentsInErrorError(false);
}
},
to: value => {
if (this.emptyToError() && value.length) {
this.emptyToError(false);
}
this.initPgpEncrypt();
},
attachmentsInProcess: value => {
if (this.attachmentsInProcessError() && arrayLength(value)) {
this.attachmentsInProcessError(false);
}
}
});
decorateKoCommands(this, {
sendCommand: self => self.canBeSentOrSaved(),
saveCommand: self => self.canBeSentOrSaved(),
deleteCommand: self => self.isDraftFolderMessage(),
skipCommand: self => self.canBeSentOrSaved(),
contactsCommand: self => self.allowContacts
});
this.from(IdentityUserStore()[0].formattedName());
}
async getMessageRequestParams(sSaveFolder, draft)
{
const
identity = this.currentIdentity(),
params = {
IdentityID: identity.id(),
MessageFolder: this.draftsFolder(),
MessageUid: this.draftUid(),
SaveFolder: sSaveFolder,
From: this.from(),
To: this.to(),
Cc: this.cc(),
Bcc: this.bcc(),
ReplyTo: this.replyTo(),
subject: this.subject(),
DraftInfo: this.aDraftInfo,
InReplyTo: this.sInReplyTo,
References: this.sReferences,
MarkAsImportant: this.markAsImportant() ? 1 : 0,
Attachments: this.prepareAttachmentsForSendOrSave(),
// Only used at send, not at save:
Dsn: this.requestDsn() ? 1 : 0,
ReadReceiptRequest: this.requestReadReceipt() ? 1 : 0
},
recipients = draft ? [identity.email()] : this.allRecipients(),
sign = !draft && this.pgpSign() && this.canPgpSign(),
encrypt = this.pgpEncrypt() && this.canPgpEncrypt(),
TextIsHtml = this.oEditor.isHtml();
let Text = this.oEditor.getData();
if (TextIsHtml) {
let l;
do {
l = Text.length;
Text = Text
// Remove Microsoft Office styling
.replace(/(<[^>]+[;"'])\s*mso-[a-z-]+\s*:[^;"']+/gi, '$1')
// Remove hubspot data-hs- attributes
.replace(/(<[^>]+)\s+data-hs-[a-z-]+=("[^"]+"|'[^']+')/gi, '$1');
} while (l != Text.length)
params.Html = Text;
params.Text = htmlToPlain(Text);
} else {
params.Text = Text;
}
if (this.mailvelope && 'mailvelope' === this.viewArea()) {
params.Encrypted = draft
? await this.mailvelope.createDraft()
: await this.mailvelope.encrypt(recipients);
} else if (sign || encrypt) {
let data = new MimePart;
data.headers['Content-Type'] = 'text/'+(TextIsHtml?'html':'plain')+'; charset="utf-8"';
data.headers['Content-Transfer-Encoding'] = 'base64';
data.body = base64_encode(Text);
if (TextIsHtml) {
const alternative = new MimePart, plain = new MimePart;
alternative.headers['Content-Type'] = 'multipart/alternative';
plain.headers['Content-Type'] = 'text/plain; charset="utf-8"';
plain.headers['Content-Transfer-Encoding'] = 'base64';
plain.body = base64_encode(params.Text);
// First add plain
alternative.children.push(plain);
// Now add HTML
alternative.children.push(data);
data = alternative;
}
if (sign && !draft && sign[1]) {
if ('openpgp' == sign[0]) {
// Doesn't sign attachments
params.Html = params.Text = '';
let signed = new MimePart;
signed.headers['Content-Type'] =
'multipart/signed; micalg="pgp-sha256"; protocol="application/pgp-signature"';
signed.headers['Content-Transfer-Encoding'] = '7Bit';
signed.children.push(data);
let signature = new MimePart;
signature.headers['Content-Type'] = 'application/pgp-signature; name="signature.asc"';
signature.headers['Content-Transfer-Encoding'] = '7Bit';
signature.body = await OpenPGPUserStore.sign(data.toString(), sign[1], 1);
signed.children.push(signature);
params.Signed = signed.toString();
params.Boundary = signed.boundary;
data = signed;
} else if ('gnupg' == sign[0]) {
// TODO: sign in PHP fails
// params.SignData = data.toString();
params.SignFingerprint = sign[1].fingerprint;
params.SignPassphrase = await GnuPGUserStore.sign(sign[1]);
} else {
throw 'Signing with ' + sign[0] + ' not yet implemented';
}
}
if (encrypt) {
if ('openpgp' == encrypt) {
// Doesn't encrypt attachments
params.Encrypted = await OpenPGPUserStore.encrypt(data.toString(), recipients);
params.Signed = '';
} else if ('gnupg' == encrypt) {
// Does encrypt attachments
params.EncryptFingerprints = JSON.stringify(GnuPGUserStore.getPublicKeyFingerprints(recipients));
} else {
throw 'Encryption with ' + encrypt + ' not yet implemented';
}
}
}
return params;
}
sendCommand() {
let sSentFolder = FolderUserStore.sentFolder();
this.attachmentsInProcessError(false);
this.attachmentsInErrorError(false);
this.emptyToError(false);
if (this.attachmentsInProcess().length) {
this.attachmentsInProcessError(true);
this.attachmentsArea();
} else if (this.attachmentsInError().length) {
this.attachmentsInErrorError(true);
this.attachmentsArea();
}
if (!this.to().trim() && !this.cc().trim() && !this.bcc().trim()) {
this.emptyToError(true);
}
if (!this.emptyToError() && !this.attachmentsInErrorError() && !this.attachmentsInProcessError()) {
if (SettingsUserStore.replySameFolder()) {
if (
3 === arrayLength(this.aDraftInfo) &&
null != this.aDraftInfo[2] &&
this.aDraftInfo[2].length
) {
sSentFolder = this.aDraftInfo[2];
}
}
if (!sSentFolder) {
showScreenPopup(FolderSystemPopupView, [SetSystemFoldersNotification.Sent]);
} else try {
this.sendError(false);
this.sending(true);
if (3 === arrayLength(this.aDraftInfo)) {
const flagsCache = MessageFlagsCache.getFor(this.aDraftInfo[2], this.aDraftInfo[1]);
if (isArray(flagsCache)) {
flagsCache.push(('forward' === this.aDraftInfo[0]) ? '$forwarded' : '\\answered');
MessageFlagsCache.setFor(this.aDraftInfo[2], this.aDraftInfo[1], flagsCache);
MessagelistUserStore.reloadFlagsAndCachedMessage();
setFolderHash(this.aDraftInfo[2], '');
}
}
sSentFolder = UNUSED_OPTION_VALUE === sSentFolder ? '' : sSentFolder;
this.getMessageRequestParams(sSentFolder).then(params => {
Remote.request('SendMessage',
(iError, data) => {
this.sending(false);
if (iError) {
if (Notification.CantSaveMessage === iError) {
this.sendSuccessButSaveError(true);
this.savedErrorDesc(i18n('COMPOSE/SAVED_ERROR_ON_SEND').trim());
} else {
this.sendError(true);
this.sendErrorDesc(getNotification(iError, data && data.ErrorMessage)
|| getNotification(Notification.CantSendMessage));
}
} else {
this.close();
}
setFolderHash(this.draftsFolder(), '');
setFolderHash(sSentFolder, '');
reloadDraftFolder();
},
params,
30000
);
}).catch(e => {
console.error(e);
this.sendError(true);
this.sendErrorDesc(e);
this.sending(false);
});
} catch (e) {
console.error(e);
this.sendError(true);
this.sendErrorDesc(e);
this.sending(false);
}
}
}
saveCommand() {
if (FolderUserStore.draftsFolderNotEnabled()) {
showScreenPopup(FolderSystemPopupView, [SetSystemFoldersNotification.Draft]);
} else {
this.savedError(false);
this.saving(true);
this.autosaveStart();
this.getMessageRequestParams(FolderUserStore.draftsFolder(), 1).then(params => {
Remote.request('SaveMessage',
(iError, oData) => {
let result = false;
this.saving(false);
if (!iError) {
if (oData.Result.NewFolder && oData.Result.NewUid) {
result = true;
if (this.bFromDraft) {
const message = MessageUserStore.message();
if (message && this.draftsFolder() === message.folder && this.draftUid() == message.uid) {
MessageUserStore.message(null);
}
}
this.draftsFolder(oData.Result.NewFolder);
this.draftUid(oData.Result.NewUid);
this.savedTime(new Date);
if (this.bFromDraft) {
setFolderHash(this.draftsFolder(), '');
}
setFolderHash(FolderUserStore.draftsFolder(), '');
}
}
if (!result) {
this.savedError(true);
this.savedErrorDesc(getNotification(Notification.CantSaveMessage));
}
reloadDraftFolder();
},
params,
200000
);
}).catch(e => {
this.saving(false);
this.savedError(true);
this.savedErrorDesc(getNotification(Notification.CantSaveMessage) + ': ' + e);
});
}
}
deleteCommand() {
AskPopupView.hidden()
&& showScreenPopup(AskPopupView, [
i18n('POPUPS_ASK/DESC_WANT_DELETE_MESSAGES'),
() => {
const
sFromFolderFullName = this.draftsFolder(),
aUidForRemove = [this.draftUid()];
messagesDeleteHelper(sFromFolderFullName, aUidForRemove);
MessagelistUserStore.removeMessagesFromList(sFromFolderFullName, aUidForRemove);
this.close();
}
]);
}
onClose() {
this.skipCommand();
return false;
}
skipCommand() {
this.bSkipNextHide = true;
if (
!this.saving() &&
!this.sending() &&
!FolderUserStore.draftsFolderNotEnabled() &&
SettingsUserStore.allowDraftAutosave()
) {
this.saveCommand();
}
this.tryToClosePopup();
}
contactsCommand() {
if (this.allowContacts) {
this.skipCommand();
setTimeout(() => {
showScreenPopup(ContactsPopupView, [true, this.sLastFocusedField]);
}, 200);
}
}
autosaveStart() {
clearTimeout(this.iTimer);
this.iTimer = setTimeout(()=>{
if (this.modalVisible()
&& !FolderUserStore.draftsFolderNotEnabled()
&& SettingsUserStore.allowDraftAutosave()
&& !this.isEmptyForm(false)
&& !this.saving()
&& !this.sending()
&& !this.savedError()
) {
this.saveCommand();
}
this.autosaveStart();
}, 60000);
}
// getAutocomplete
emailsSource(oData, fResponse) {
Remote.request('Suggestions',
(iError, data) => {
if (!iError && isArray(data.Result)) {
fResponse(
data.Result.map(item => (item && item[0] ? (new EmailModel(item[0], item[1])).toLine() : null))
.filter(v => v)
);
} else if (Notification.RequestAborted !== iError) {
fResponse([]);
}
},
{
Query: oData.term
// ,Page: 1
},
null,
'',
['Suggestions']
);
}
selectIdentity(identity) {
identity = identity && identity.item;
if (identity) {
this.currentIdentity(identity);
this.setSignatureFromIdentity(identity);
}
}
onHide() {
// Stop autosave
clearTimeout(this.iTimer);
AppUserStore.composeInEdit(this.bSkipNextHide);
this.bSkipNextHide || this.reset();
this.bSkipNextHide = false;
this.to.focused(false);
// alreadyFullscreen || exitFullscreen();
}
dropMailvelope() {
if (this.mailvelope) {
elementById('mailvelope-editor').textContent = '';
this.mailvelope = null;
}
}
editor(fOnInit) {
if (fOnInit && this.editorArea()) {
if (this.oEditor) {
fOnInit(this.oEditor);
} else {
// setTimeout(() => {
this.oEditor = new HtmlEditor(
this.editorArea(),
null,
() => fOnInit(this.oEditor),
bHtml => this.isHtml(!!bHtml)
);
// }, 1000);
}
}
}
setSignatureFromIdentity(identity) {
if (identity) {
this.editor(editor => {
let signature = identity.signature() || '',
isHtml = ':HTML:' === signature.slice(0, 6),
fromLine = this.oLastMessage ? emailArrayToStringLineHelper(this.oLastMessage.from, true) : '';
if (fromLine) {
signature = signature.replace(/{{FROM-FULL}}/g, fromLine);
if (!fromLine.includes(' ') && 0 < fromLine.indexOf('@')) {
fromLine = fromLine.replace(/@\S+/, '');
}
signature = signature.replace(/{{FROM}}/g, fromLine);
}
signature = (isHtml ? signature.slice(6) : signature)
.replace(/\r/g, '')
.replace(/\s{1,2}?{{FROM}}/g, '')
.replace(/\s{1,2}?{{FROM-FULL}}/g, '')
.replace(/{{DATE}}/g, new Date().format('LLLL'))
.replace(/{{TIME}}/g, new Date().format('LT'))
.replace(/{{MOMENT:[^}]+}}/g, '');
signature.length && editor.setSignature(signature, isHtml, !!identity.signatureInsertBefore());
});
}
}
/**
* @param {string=} type = ComposeType.Empty
* @param {?MessageModel|Array=} oMessageOrArray = null
* @param {Array=} aToEmails = null
* @param {Array=} aCcEmails = null
* @param {Array=} aBccEmails = null
* @param {string=} sCustomSubject = null
* @param {string=} sCustomPlainText = null
*/
onShow(type, oMessageOrArray, aToEmails, aCcEmails, aBccEmails, sCustomSubject, sCustomPlainText) {
this.autosaveStart();
this.viewModelDom.dataset.wysiwyg = SettingsUserStore.editorDefaultType();
if (AppUserStore.composeInEdit()) {
type = type || ComposeType.Empty;
if (ComposeType.Empty !== type) {
showScreenPopup(AskPopupView, [
i18n('COMPOSE/DISCARD_UNSAVED_DATA'),
() => {
this.initOnShow(type, oMessageOrArray, aToEmails, aCcEmails, aBccEmails, sCustomSubject, sCustomPlainText);
},
null,
false
]);
} else {
addEmailsTo(this.to, aToEmails);
addEmailsTo(this.cc, aCcEmails);
addEmailsTo(this.bcc, aBccEmails);
if (sCustomSubject && !this.subject()) {
this.subject(sCustomSubject);
}
}
} else {
this.initOnShow(type, oMessageOrArray, aToEmails, aCcEmails, aBccEmails, sCustomSubject, sCustomPlainText);
}
// Chrome bug #298
// alreadyFullscreen = isFullscreen();
// alreadyFullscreen || (ThemeStore.isMobile() && toggleFullscreen());
}
/**
* @param {string=} sType = ComposeType.Empty
* @param {?MessageModel|Array=} oMessageOrArray = null
* @param {Array=} aToEmails = null
* @param {Array=} aCcEmails = null
* @param {Array=} aBccEmails = null
* @param {string=} sCustomSubject = null
* @param {string=} sCustomPlainText = null
*/
initOnShow(sType, oMessageOrArray, aToEmails, aCcEmails, aBccEmails, sCustomSubject, sCustomPlainText) {
let sFrom = '',
sTo = '',
sCc = '',
sDate = '',
sSubject = '',
sText = '',
identity = null,
aDraftInfo = null,
message = null;
const excludeEmail = {},
mEmail = AccountUserStore.email(),
lineComposeType = sType || ComposeType.Empty;
if (oMessageOrArray) {
message =
1 === arrayLength(oMessageOrArray)
? oMessageOrArray[0]
: isArray(oMessageOrArray)
? null
: oMessageOrArray;
}
this.oLastMessage = message;
if (null !== mEmail) {
excludeEmail[mEmail] = true;
}
this.reset();
identity = findIdentityByMessage(lineComposeType, message);
if (identity) {
excludeEmail[identity.email()] = true;
}
if (arrayLength(aToEmails)) {
this.to(emailArrayToStringLineHelper(aToEmails));
}
if (arrayLength(aCcEmails)) {
this.cc(emailArrayToStringLineHelper(aCcEmails));
}
if (arrayLength(aBccEmails)) {
this.bcc(emailArrayToStringLineHelper(aBccEmails));
}
if (lineComposeType && message) {
sDate = timestampToString(message.dateTimeStampInUTC(), 'FULL');
sSubject = message.subject();
aDraftInfo = message.draftInfo;
switch (lineComposeType) {
case ComposeType.Empty:
break;
case ComposeType.Reply:
this.to(emailArrayToStringLineHelper(message.replyEmails(excludeEmail)));
this.subject(replySubjectAdd('Re', sSubject));
this.prepareMessageAttachments(message, lineComposeType);
this.aDraftInfo = ['reply', message.uid, message.folder];
this.sInReplyTo = message.messageId;
this.sReferences = (message.messageId + ' ' + message.references).trim();
break;
case ComposeType.ReplyAll: {
let parts = message.replyAllEmails(excludeEmail);
this.to(emailArrayToStringLineHelper(parts[0]));
this.cc(emailArrayToStringLineHelper(parts[1]));
this.subject(replySubjectAdd('Re', sSubject));
this.prepareMessageAttachments(message, lineComposeType);
this.aDraftInfo = ['reply', message.uid, message.folder];
this.sInReplyTo = message.messageId;
this.sReferences = (message.messageId + ' ' + message.references).trim();
break;
}
case ComposeType.Forward:
this.subject(replySubjectAdd('Fwd', sSubject));
this.prepareMessageAttachments(message, lineComposeType);
this.aDraftInfo = ['forward', message.uid, message.folder];
this.sInReplyTo = message.messageId;
this.sReferences = (message.messageId + ' ' + message.references).trim();
break;
case ComposeType.ForwardAsAttachment:
this.subject(replySubjectAdd('Fwd', sSubject));
this.prepareMessageAttachments(message, lineComposeType);
this.aDraftInfo = ['forward', message.uid, message.folder];
this.sInReplyTo = message.messageId;
this.sReferences = (message.messageId + ' ' + message.references).trim();
break;
case ComposeType.Draft:
this.to(emailArrayToStringLineHelper(message.to));
this.cc(emailArrayToStringLineHelper(message.cc));
this.bcc(emailArrayToStringLineHelper(message.bcc));
this.replyTo(emailArrayToStringLineHelper(message.replyTo));
this.bFromDraft = true;
this.draftsFolder(message.folder);
this.draftUid(message.uid);
this.subject(sSubject);
this.prepareMessageAttachments(message, lineComposeType);
this.aDraftInfo = 3 === arrayLength(aDraftInfo) ? aDraftInfo : null;
this.sInReplyTo = message.inReplyTo;
this.sReferences = message.references;
break;
case ComposeType.EditAsNew:
this.to(emailArrayToStringLineHelper(message.to));
this.cc(emailArrayToStringLineHelper(message.cc));
this.bcc(emailArrayToStringLineHelper(message.bcc));
this.replyTo(emailArrayToStringLineHelper(message.replyTo));
this.subject(sSubject);
this.prepareMessageAttachments(message, lineComposeType);
this.aDraftInfo = 3 === arrayLength(aDraftInfo) ? aDraftInfo : null;
this.sInReplyTo = message.inReplyTo;
this.sReferences = message.references;
break;
// no default
}
sText = message.bodyAsHTML();
let encrypted;
switch (lineComposeType) {
case ComposeType.Reply:
case ComposeType.ReplyAll:
sFrom = message.fromToLine(false, true);
sText = '
' + i18n('COMPOSE/REPLY_MESSAGE_TITLE', { DATETIME: sDate, EMAIL: sFrom }) + ':
' + sText.replace(/]+>/g, '').replace(/]+><\/a>/g, '').trim() + ''; break; case ComposeType.Forward: sFrom = message.fromToLine(false, true); sTo = message.toToLine(false, true); sCc = message.ccToLine(false, true); sText = '
' + i18n('COMPOSE/FORWARD_MESSAGE_TOP_TITLE') + '