2016-08-17 06:01:20 +08:00
|
|
|
import ko from 'ko';
|
|
|
|
|
2020-09-30 22:10:01 +08:00
|
|
|
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
|
2016-08-17 06:01:20 +08:00
|
|
|
|
|
|
|
import {
|
2019-07-05 03:19:24 +08:00
|
|
|
Capa,
|
2021-03-16 23:06:16 +08:00
|
|
|
Scope
|
2021-01-25 05:58:06 +08:00
|
|
|
} from 'Common/Enums';
|
|
|
|
|
|
|
|
import {
|
2019-07-05 03:19:24 +08:00
|
|
|
ComposeType,
|
|
|
|
ClientSideKeyName,
|
|
|
|
FolderType,
|
|
|
|
MessageSetAction
|
2021-01-25 05:58:06 +08:00
|
|
|
} from 'Common/EnumsUser';
|
2016-08-17 06:01:20 +08:00
|
|
|
|
2022-02-02 20:02:48 +08:00
|
|
|
import {
|
|
|
|
elementById,
|
|
|
|
$htmlCL,
|
|
|
|
leftPanelDisabled,
|
|
|
|
keyScopeReal,
|
|
|
|
moveAction,
|
|
|
|
Settings,
|
2022-02-08 21:13:06 +08:00
|
|
|
SettingsCapa,
|
2022-02-02 20:02:48 +08:00
|
|
|
getFullscreenElement,
|
|
|
|
exitFullscreen
|
|
|
|
} from 'Common/Globals';
|
2016-08-17 06:01:20 +08:00
|
|
|
|
2021-07-22 03:34:17 +08:00
|
|
|
import { arrayLength, inFocus } from 'Common/Utils';
|
2022-02-10 23:35:55 +08:00
|
|
|
import { download, mailToHelper, showMessageComposer, initFullscreen } from 'Common/UtilsUser';
|
2016-08-17 06:01:20 +08:00
|
|
|
|
2021-03-11 05:41:35 +08:00
|
|
|
import { SMAudio } from 'Common/Audio';
|
2016-08-17 06:01:20 +08:00
|
|
|
|
2019-07-05 03:19:24 +08:00
|
|
|
import { i18n } from 'Common/Translator';
|
|
|
|
import { attachmentDownload } from 'Common/Links';
|
2016-08-17 06:01:20 +08:00
|
|
|
|
2020-10-25 20:50:26 +08:00
|
|
|
import { MessageFlagsCache } from 'Common/Cache';
|
2016-08-17 06:01:20 +08:00
|
|
|
|
2021-03-11 05:41:35 +08:00
|
|
|
import { AppUserStore } from 'Stores/User/App';
|
|
|
|
import { SettingsUserStore } from 'Stores/User/Settings';
|
|
|
|
import { AccountUserStore } from 'Stores/User/Account';
|
|
|
|
import { FolderUserStore } from 'Stores/User/Folder';
|
|
|
|
import { MessageUserStore } from 'Stores/User/Message';
|
2021-02-17 03:12:23 +08:00
|
|
|
import { ThemeStore } from 'Stores/Theme';
|
2016-08-17 06:01:20 +08:00
|
|
|
|
|
|
|
import * as Local from 'Storage/Client';
|
|
|
|
|
2020-09-15 01:40:56 +08:00
|
|
|
import Remote from 'Remote/User/Fetch';
|
2016-08-17 06:01:20 +08:00
|
|
|
|
2021-03-10 18:43:23 +08:00
|
|
|
import { decorateKoCommands, createCommand } from 'Knoin/Knoin';
|
2021-01-24 17:25:23 +08:00
|
|
|
import { AbstractViewRight } from 'Knoin/AbstractViews';
|
2016-08-17 06:01:20 +08:00
|
|
|
|
2022-01-17 22:58:23 +08:00
|
|
|
import { PgpUserStore } from 'Stores/User/Pgp';
|
|
|
|
|
2022-02-10 22:37:05 +08:00
|
|
|
import { ParseMime } from 'Mime/Parser';
|
2022-02-01 00:29:41 +08:00
|
|
|
import { AttachmentModel } from 'Model/Attachment';
|
2022-01-31 22:24:51 +08:00
|
|
|
|
2022-02-02 20:02:48 +08:00
|
|
|
const
|
|
|
|
oMessageScrollerDom = () => elementById('messageItem') || {},
|
|
|
|
|
|
|
|
currentMessage = () => MessageUserStore.message(),
|
|
|
|
|
|
|
|
mimeToMessage = (data, message) => {
|
|
|
|
const headers = data.split(/\r?\n\r?\n/)[0];
|
2022-02-04 16:54:59 +08:00
|
|
|
if (/Content-Type:/i.test(headers)) {
|
2022-02-10 22:37:05 +08:00
|
|
|
const struct = ParseMime(data),
|
|
|
|
text = struct.getByContentType('text/plain');
|
|
|
|
let html = struct.getByContentType('text/html');
|
|
|
|
html = html ? html.body : '';
|
|
|
|
|
|
|
|
// TODO: Check multipart/signed application/pgp-signature application/pgp-keys
|
|
|
|
struct.forEach(part => {
|
|
|
|
let cd = part.header('content-disposition'),
|
|
|
|
cid = part.header('content-id'),
|
|
|
|
type = part.header('content-type');
|
|
|
|
if (cid || cd) {
|
|
|
|
// if (cd && 'attachment' === cd.value) {
|
2022-02-02 20:02:48 +08:00
|
|
|
let attachment = new AttachmentModel;
|
2022-02-10 22:37:05 +08:00
|
|
|
attachment.mimeType = type.value;
|
|
|
|
attachment.fileName = (type.name || (cd && cd.params.filename));
|
|
|
|
attachment.url = part.dataUrl;
|
|
|
|
/*
|
|
|
|
attachment.fileNameExt = '';
|
|
|
|
attachment.fileType = FileType.Unknown;
|
|
|
|
attachment.friendlySize = '';
|
2022-02-11 00:01:36 +08:00
|
|
|
attachment.isLinked(false);
|
2022-02-10 22:37:05 +08:00
|
|
|
attachment.isThumbnail = false;
|
|
|
|
attachment.contentLocation = '';
|
|
|
|
attachment.download = '';
|
|
|
|
attachment.folder = '';
|
|
|
|
attachment.uid = '';
|
|
|
|
attachment.mimeIndex = part.id;
|
|
|
|
attachment.framed = false;
|
|
|
|
*/
|
|
|
|
attachment.cid = cid ? cid.value : '';
|
|
|
|
if (cid && html) {
|
2022-02-11 00:01:36 +08:00
|
|
|
let cid = 'cid:' + attachment.contentId(),
|
|
|
|
found = html.includes(cid);
|
|
|
|
attachment.isInline(found);
|
|
|
|
attachment.isLinked(found);
|
|
|
|
found && (html = html
|
2022-02-10 22:37:05 +08:00
|
|
|
.replace('src="' + cid + '"', 'src="' + attachment.url + '"')
|
2022-02-11 00:01:36 +08:00
|
|
|
.replace("src='" + cid + "'", "src='" + attachment.url + "'")
|
|
|
|
);
|
2022-02-10 22:37:05 +08:00
|
|
|
} else {
|
|
|
|
message.attachments.push(attachment);
|
2022-02-01 00:29:41 +08:00
|
|
|
}
|
2022-02-02 20:02:48 +08:00
|
|
|
}
|
2022-02-01 00:29:41 +08:00
|
|
|
});
|
2022-02-10 22:37:05 +08:00
|
|
|
|
|
|
|
message.plain(text ? text.body : '');
|
|
|
|
if (html) {
|
|
|
|
message.html(html.replace(/<\/?script[\s\S]*?>/gi, ''));
|
|
|
|
message.viewHtml();
|
|
|
|
} else {
|
|
|
|
message.viewPlain();
|
|
|
|
}
|
2022-02-02 20:02:48 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
message.plain(data);
|
|
|
|
message.viewPlain();
|
|
|
|
};
|
2022-01-31 22:24:51 +08:00
|
|
|
|
2021-09-23 15:41:02 +08:00
|
|
|
export class MailMessageView extends AbstractViewRight {
|
2016-08-17 06:01:20 +08:00
|
|
|
constructor() {
|
2021-09-23 15:41:02 +08:00
|
|
|
super('MailMessageView');
|
2014-08-20 23:03:12 +08:00
|
|
|
|
2021-03-13 00:08:58 +08:00
|
|
|
const
|
|
|
|
createCommandReplyHelper = type =>
|
|
|
|
createCommand(() => {
|
|
|
|
this.lastReplyAction(type);
|
|
|
|
this.replyOrforward(type);
|
|
|
|
}, this.canBeRepliedOrForwarded),
|
|
|
|
|
|
|
|
createCommandActionHelper = (folderType, useFolder) =>
|
|
|
|
createCommand(() => {
|
2022-01-27 00:08:10 +08:00
|
|
|
const message = currentMessage();
|
2021-09-17 20:07:52 +08:00
|
|
|
if (message) {
|
2021-08-13 02:17:37 +08:00
|
|
|
MessageUserStore.message(null);
|
2021-03-13 00:08:58 +08:00
|
|
|
rl.app.deleteMessagesFromFolder(folderType, message.folder, [message.uid], useFolder);
|
|
|
|
}
|
|
|
|
}, this.messageVisibility);
|
2014-08-20 23:03:12 +08:00
|
|
|
|
2020-10-26 19:54:03 +08:00
|
|
|
this.addObservables({
|
2022-01-17 23:39:10 +08:00
|
|
|
showAttachmentControls: false,
|
2020-10-26 19:54:03 +08:00
|
|
|
downloadAsZipLoading: false,
|
|
|
|
lastReplyAction_: '',
|
|
|
|
showFullInfo: '1' === Local.get(ClientSideKeyName.MessageHeaderFullInfo),
|
2022-02-02 20:02:48 +08:00
|
|
|
moreDropdownTrigger: false,
|
|
|
|
|
|
|
|
// viewer
|
|
|
|
viewFromShort: '',
|
|
|
|
viewFromDkimData: ['none', ''],
|
|
|
|
viewToShort: ''
|
2020-10-26 19:54:03 +08:00
|
|
|
});
|
2014-08-20 23:03:12 +08:00
|
|
|
|
2017-03-02 02:38:18 +08:00
|
|
|
this.moveAction = moveAction;
|
|
|
|
|
2022-02-08 21:13:06 +08:00
|
|
|
this.allowMessageActions = SettingsCapa(Capa.MessageActions);
|
2014-12-06 05:01:33 +08:00
|
|
|
|
2021-03-16 23:06:16 +08:00
|
|
|
const attachmentsActions = Settings.app('attachmentsActions');
|
2021-07-22 03:34:17 +08:00
|
|
|
this.attachmentsActions = ko.observableArray(arrayLength(attachmentsActions) ? attachmentsActions : []);
|
2016-05-01 09:07:10 +08:00
|
|
|
|
2021-03-11 05:41:35 +08:00
|
|
|
this.message = MessageUserStore.message;
|
|
|
|
this.hasCheckedMessages = MessageUserStore.hasCheckedMessages;
|
2021-03-12 23:54:37 +08:00
|
|
|
this.messageLoadingThrottle = MessageUserStore.messageLoading;
|
2021-03-11 05:41:35 +08:00
|
|
|
this.messagesBodiesDom = MessageUserStore.messagesBodiesDom;
|
|
|
|
this.messageActiveDom = MessageUserStore.messageActiveDom;
|
|
|
|
this.messageError = MessageUserStore.messageError;
|
2015-04-25 06:15:11 +08:00
|
|
|
|
2021-03-11 05:41:35 +08:00
|
|
|
this.fullScreenMode = MessageUserStore.messageFullScreenMode;
|
2014-08-22 23:08:56 +08:00
|
|
|
|
2019-07-05 03:19:24 +08:00
|
|
|
this.messageListOfThreadsLoading = ko.observable(false).extend({ rateLimit: 1 });
|
|
|
|
this.highlightUnselectedAttachments = ko.observable(false).extend({ falseTimeout: 2000 });
|
2014-08-20 23:03:12 +08:00
|
|
|
|
2022-01-17 23:39:10 +08:00
|
|
|
this.showAttachmentControlsState = v => Local.set(ClientSideKeyName.MessageAttachmentControls, !!v);
|
2017-09-22 04:28:14 +08:00
|
|
|
|
2019-07-05 03:19:24 +08:00
|
|
|
this.downloadAsZipError = ko.observable(false).extend({ falseTimeout: 7000 });
|
2015-04-25 06:15:11 +08:00
|
|
|
|
2019-07-05 03:19:24 +08:00
|
|
|
this.messageDomFocused = ko.observable(false).extend({ rateLimit: 0 });
|
2013-11-16 06:21:12 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
// commands
|
2016-09-03 07:19:37 +08:00
|
|
|
this.replyCommand = createCommandReplyHelper(ComposeType.Reply);
|
|
|
|
this.replyAllCommand = createCommandReplyHelper(ComposeType.ReplyAll);
|
|
|
|
this.forwardCommand = createCommandReplyHelper(ComposeType.Forward);
|
|
|
|
this.forwardAsAttachmentCommand = createCommandReplyHelper(ComposeType.ForwardAsAttachment);
|
|
|
|
this.editAsNewCommand = createCommandReplyHelper(ComposeType.EditAsNew);
|
|
|
|
|
|
|
|
this.deleteCommand = createCommandActionHelper(FolderType.Trash, true);
|
|
|
|
this.deleteWithoutMoveCommand = createCommandActionHelper(FolderType.Trash, false);
|
|
|
|
this.archiveCommand = createCommandActionHelper(FolderType.Archive, true);
|
|
|
|
this.spamCommand = createCommandActionHelper(FolderType.Spam, true);
|
|
|
|
this.notSpamCommand = createCommandActionHelper(FolderType.NotSpam, true);
|
2016-08-17 06:01:20 +08:00
|
|
|
|
|
|
|
// viewer
|
|
|
|
this.viewHash = '';
|
2014-08-20 23:03:12 +08:00
|
|
|
|
2020-10-26 21:44:34 +08:00
|
|
|
this.addComputables({
|
2022-02-08 21:13:06 +08:00
|
|
|
allowAttachmentControls: () => this.attachmentsActions.length && SettingsCapa(Capa.AttachmentsActions),
|
2020-10-26 21:44:34 +08:00
|
|
|
|
2022-01-17 23:39:10 +08:00
|
|
|
downloadAsZipAllowed: () => this.attachmentsActions.includes('zip') && this.allowAttachmentControls(),
|
2020-10-26 21:44:34 +08:00
|
|
|
|
|
|
|
lastReplyAction: {
|
|
|
|
read: this.lastReplyAction_,
|
|
|
|
write: value => this.lastReplyAction_(
|
|
|
|
[ComposeType.Reply, ComposeType.ReplyAll, ComposeType.Forward].includes(value)
|
|
|
|
? ComposeType.Reply
|
|
|
|
: value
|
|
|
|
)
|
|
|
|
},
|
|
|
|
|
2022-01-27 00:08:10 +08:00
|
|
|
messageVisibility: () => !MessageUserStore.messageLoading() && !!currentMessage(),
|
2020-10-26 21:44:34 +08:00
|
|
|
|
|
|
|
canBeRepliedOrForwarded: () => !this.isDraftFolder() && this.messageVisibility(),
|
|
|
|
|
|
|
|
viewFromDkimVisibility: () => 'none' !== this.viewFromDkimData()[0],
|
|
|
|
|
|
|
|
viewFromDkimStatusIconClass:() => {
|
|
|
|
switch (this.viewFromDkimData()[0]) {
|
|
|
|
case 'none':
|
2021-02-22 22:16:33 +08:00
|
|
|
return '';
|
2020-10-26 21:44:34 +08:00
|
|
|
case 'pass':
|
|
|
|
return 'icon-ok iconcolor-green';
|
|
|
|
default:
|
|
|
|
return 'icon-warning-alt iconcolor-red';
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
viewFromDkimStatusTitle:() => {
|
|
|
|
const status = this.viewFromDkimData();
|
2021-07-22 03:34:17 +08:00
|
|
|
if (arrayLength(status) && status[0]) {
|
|
|
|
return status[1] || 'DKIM: ' + status[0];
|
2020-10-26 21:44:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return '';
|
|
|
|
},
|
|
|
|
|
2022-01-27 00:08:10 +08:00
|
|
|
pgpSupported: () => currentMessage() && PgpUserStore.isSupported(),
|
2022-01-17 22:58:23 +08:00
|
|
|
|
2021-11-30 17:19:43 +08:00
|
|
|
messageListOrViewLoading:
|
2021-12-16 02:02:36 +08:00
|
|
|
() => MessageUserStore.listIsLoading() | MessageUserStore.messageLoading()
|
2020-10-26 21:44:34 +08:00
|
|
|
});
|
|
|
|
|
2020-10-26 19:54:03 +08:00
|
|
|
this.addSubscribables({
|
2022-01-27 00:08:10 +08:00
|
|
|
showAttachmentControls: v => currentMessage()
|
|
|
|
&& currentMessage().attachments.forEach(item => item && item.checked(!!v)),
|
2020-10-26 19:54:03 +08:00
|
|
|
|
|
|
|
lastReplyAction_: value => Local.set(ClientSideKeyName.LastReplyAction, value),
|
|
|
|
|
|
|
|
message: message => {
|
|
|
|
this.messageActiveDom(null);
|
|
|
|
|
|
|
|
if (message) {
|
2022-01-17 23:39:10 +08:00
|
|
|
this.showAttachmentControls(false);
|
2020-10-26 19:54:03 +08:00
|
|
|
if (Local.get(ClientSideKeyName.MessageAttachmentControls)) {
|
|
|
|
setTimeout(() => {
|
2022-01-17 23:39:10 +08:00
|
|
|
this.showAttachmentControls(true);
|
2020-10-26 19:54:03 +08:00
|
|
|
}, 50);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.viewHash !== message.hash) {
|
|
|
|
this.scrollMessageToTop();
|
|
|
|
}
|
|
|
|
|
|
|
|
this.viewHash = message.hash;
|
|
|
|
this.viewFromShort(message.fromToLine(true, true));
|
|
|
|
this.viewFromDkimData(message.fromDkimData());
|
|
|
|
this.viewToShort(message.toToLine(true, true));
|
|
|
|
} else {
|
2021-03-11 05:41:35 +08:00
|
|
|
MessageUserStore.selectorMessageSelected(null);
|
2020-10-26 19:54:03 +08:00
|
|
|
|
|
|
|
this.viewHash = '';
|
2016-08-17 06:01:20 +08:00
|
|
|
|
|
|
|
this.scrollMessageToTop();
|
2015-06-01 01:40:54 +08:00
|
|
|
}
|
2020-10-26 19:54:03 +08:00
|
|
|
},
|
2016-06-30 08:02:45 +08:00
|
|
|
|
2021-03-03 18:16:02 +08:00
|
|
|
fullScreenMode: value => {
|
|
|
|
if (this.oContent) {
|
2021-09-01 17:01:13 +08:00
|
|
|
value ? this.oContent.requestFullscreen() : exitFullscreen();
|
2021-03-03 18:16:02 +08:00
|
|
|
} else {
|
|
|
|
$htmlCL.toggle('rl-message-fullscreen', value);
|
|
|
|
}
|
|
|
|
}
|
2016-08-17 06:01:20 +08:00
|
|
|
});
|
|
|
|
|
2020-10-26 19:54:03 +08:00
|
|
|
this.lastReplyAction(Local.get(ClientSideKeyName.LastReplyAction) || ComposeType.Reply);
|
2016-06-30 08:02:45 +08:00
|
|
|
|
2020-09-03 18:51:15 +08:00
|
|
|
addEventListener('mailbox.message-view.toggle-full-screen', () => this.toggleFullScreen());
|
2013-11-16 06:21:12 +08:00
|
|
|
|
2021-02-19 19:09:20 +08:00
|
|
|
decorateKoCommands(this, {
|
|
|
|
closeMessageCommand: 1,
|
|
|
|
messageEditCommand: self => self.messageVisibility(),
|
2021-11-30 17:19:43 +08:00
|
|
|
goUpCommand: self => !self.messageListOrViewLoading(),
|
|
|
|
goDownCommand: self => !self.messageListOrViewLoading()
|
2021-02-19 19:09:20 +08:00
|
|
|
});
|
2016-06-30 08:02:45 +08:00
|
|
|
}
|
2016-08-17 06:01:20 +08:00
|
|
|
|
2016-09-03 07:19:37 +08:00
|
|
|
closeMessageCommand() {
|
2021-03-11 05:41:35 +08:00
|
|
|
MessageUserStore.message(null);
|
2016-09-03 07:19:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
messageEditCommand() {
|
2022-02-04 16:54:59 +08:00
|
|
|
if (currentMessage()) {
|
|
|
|
showMessageComposer([ComposeType.Draft, currentMessage()]);
|
|
|
|
}
|
2016-09-03 07:19:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
goUpCommand() {
|
2020-08-15 02:35:39 +08:00
|
|
|
dispatchEvent(new CustomEvent('mailbox.message-list.selector.go-up',
|
2022-01-27 00:08:10 +08:00
|
|
|
{detail:SettingsUserStore.usePreviewPane() || !!currentMessage()} // bForceSelect
|
2020-08-15 02:35:39 +08:00
|
|
|
));
|
2016-09-03 07:19:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
goDownCommand() {
|
2020-10-09 17:04:35 +08:00
|
|
|
dispatchEvent(new CustomEvent('mailbox.message-list.selector.go-down',
|
2022-01-27 00:08:10 +08:00
|
|
|
{detail:SettingsUserStore.usePreviewPane() || !!currentMessage()} // bForceSelect
|
2020-08-15 02:35:39 +08:00
|
|
|
));
|
2016-09-03 07:19:37 +08:00
|
|
|
}
|
2021-03-12 18:57:07 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
toggleFullScreen() {
|
2020-10-03 05:54:15 +08:00
|
|
|
try {
|
|
|
|
getSelection().removeAllRanges();
|
|
|
|
} catch (e) {} // eslint-disable-line no-empty
|
2015-01-18 23:26:00 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
this.fullScreenMode(!this.fullScreenMode());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {string} sType
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
replyOrforward(sType) {
|
2022-01-27 00:08:10 +08:00
|
|
|
showMessageComposer([sType, currentMessage()]);
|
2016-06-30 08:02:45 +08:00
|
|
|
}
|
2016-05-01 09:07:10 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
onBuild(dom) {
|
2021-08-13 02:17:37 +08:00
|
|
|
this.fullScreenMode.subscribe(value =>
|
2022-01-27 00:08:10 +08:00
|
|
|
value && currentMessage() && AppUserStore.focusedState(Scope.MessageView));
|
2016-08-17 06:01:20 +08:00
|
|
|
|
2020-09-03 18:51:15 +08:00
|
|
|
this.showFullInfo.subscribe(value => Local.set(ClientSideKeyName.MessageHeaderFullInfo, value ? '1' : '0'));
|
2016-08-17 06:01:20 +08:00
|
|
|
|
2021-11-16 20:15:02 +08:00
|
|
|
const el = dom.querySelector('.b-content');
|
|
|
|
this.oContent = initFullscreen(el, () => this.fullScreenMode(getFullscreenElement() === el));
|
2021-03-03 18:16:02 +08:00
|
|
|
|
2020-08-30 16:30:50 +08:00
|
|
|
const eqs = (ev, s) => ev.target.closestWithin(s, dom);
|
|
|
|
dom.addEventListener('click', event => {
|
2021-02-17 03:12:23 +08:00
|
|
|
ThemeStore.isMobile() && leftPanelDisabled(true);
|
2014-04-08 05:03:58 +08:00
|
|
|
|
2020-08-30 16:30:50 +08:00
|
|
|
let el = eqs(event, 'a');
|
|
|
|
if (el) {
|
2019-07-05 03:19:24 +08:00
|
|
|
return !(
|
2021-03-10 16:43:31 +08:00
|
|
|
0 === event.button &&
|
2021-03-10 18:43:23 +08:00
|
|
|
mailToHelper(el.href)
|
2019-07-05 03:19:24 +08:00
|
|
|
);
|
2020-08-30 16:30:50 +08:00
|
|
|
}
|
2016-08-17 06:01:20 +08:00
|
|
|
|
2020-08-30 16:30:50 +08:00
|
|
|
if (eqs(event, '.attachmentsPlace .attachmentIconParent')) {
|
|
|
|
event.stopPropagation();
|
|
|
|
}
|
|
|
|
|
|
|
|
el = eqs(event, '.attachmentsPlace .showPreplay');
|
|
|
|
if (el) {
|
|
|
|
event.stopPropagation();
|
2021-03-13 00:08:58 +08:00
|
|
|
const attachment = ko.dataFor(el);
|
2021-03-11 05:41:35 +08:00
|
|
|
if (attachment && SMAudio.supported) {
|
2019-07-05 03:19:24 +08:00
|
|
|
switch (true) {
|
2021-03-11 05:41:35 +08:00
|
|
|
case SMAudio.supportedMp3 && attachment.isMp3():
|
|
|
|
SMAudio.playMp3(attachment.linkDownload(), attachment.fileName);
|
2016-08-17 06:01:20 +08:00
|
|
|
break;
|
2021-03-11 05:41:35 +08:00
|
|
|
case SMAudio.supportedOgg && attachment.isOgg():
|
|
|
|
SMAudio.playOgg(attachment.linkDownload(), attachment.fileName);
|
2016-08-17 06:01:20 +08:00
|
|
|
break;
|
2021-03-11 05:41:35 +08:00
|
|
|
case SMAudio.supportedWav && attachment.isWav():
|
|
|
|
SMAudio.playWav(attachment.linkDownload(), attachment.fileName);
|
2016-08-17 06:01:20 +08:00
|
|
|
break;
|
|
|
|
// no default
|
|
|
|
}
|
|
|
|
}
|
2020-08-30 16:30:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
el = eqs(event, '.attachmentsPlace .attachmentItem .attachmentNameParent');
|
|
|
|
if (el) {
|
|
|
|
const attachment = ko.dataFor(el);
|
2022-02-10 23:35:55 +08:00
|
|
|
attachment && attachment.linkDownload() && download(attachment.linkDownload(), attachment.fileName);
|
2020-08-30 16:30:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (eqs(event, '.messageItemHeader .subjectParent .flagParent')) {
|
2022-01-27 00:08:10 +08:00
|
|
|
const message = currentMessage();
|
2020-09-15 15:29:25 +08:00
|
|
|
message && rl.app.messageListAction(
|
2020-10-23 21:15:54 +08:00
|
|
|
message.folder,
|
|
|
|
message.isFlagged() ? MessageSetAction.UnsetFlag : MessageSetAction.SetFlag,
|
2020-09-03 18:51:15 +08:00
|
|
|
[message]
|
|
|
|
);
|
2020-08-30 16:30:50 +08:00
|
|
|
}
|
|
|
|
});
|
2014-04-08 05:03:58 +08:00
|
|
|
|
2021-03-11 05:41:35 +08:00
|
|
|
AppUserStore.focusedState.subscribe((value) => {
|
2021-03-16 23:06:16 +08:00
|
|
|
if (Scope.MessageView !== value) {
|
2016-08-17 06:01:20 +08:00
|
|
|
this.scrollMessageToTop();
|
|
|
|
this.scrollMessageToLeft();
|
|
|
|
}
|
|
|
|
});
|
2014-04-08 05:03:58 +08:00
|
|
|
|
2021-03-16 23:06:16 +08:00
|
|
|
keyScopeReal.subscribe(value => this.messageDomFocused(Scope.MessageView === value && !inFocus()));
|
2014-04-08 05:03:58 +08:00
|
|
|
|
2021-08-13 02:17:37 +08:00
|
|
|
// initShortcuts
|
2014-04-08 05:03:58 +08:00
|
|
|
|
2021-04-23 16:47:24 +08:00
|
|
|
// exit fullscreen, back
|
|
|
|
shortcuts.add('escape,backspace', '', Scope.MessageView, () => {
|
2022-01-27 00:08:10 +08:00
|
|
|
if (!this.viewModelDom.hidden && currentMessage()) {
|
2021-04-23 16:47:24 +08:00
|
|
|
const preview = SettingsUserStore.usePreviewPane();
|
|
|
|
if (this.fullScreenMode()) {
|
|
|
|
this.fullScreenMode(false);
|
|
|
|
|
|
|
|
if (preview) {
|
|
|
|
AppUserStore.focusedState(Scope.MessageList);
|
|
|
|
}
|
|
|
|
} else if (!preview) {
|
2021-08-13 02:17:37 +08:00
|
|
|
MessageUserStore.message(null);
|
2021-04-23 16:47:24 +08:00
|
|
|
} else {
|
2021-03-16 23:06:16 +08:00
|
|
|
AppUserStore.focusedState(Scope.MessageList);
|
2016-08-17 06:01:20 +08:00
|
|
|
}
|
2016-07-01 06:50:11 +08:00
|
|
|
|
2021-04-23 16:47:24 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
2016-08-17 06:01:20 +08:00
|
|
|
|
|
|
|
// fullscreen
|
2021-03-16 23:06:16 +08:00
|
|
|
shortcuts.add('enter,open', '', Scope.MessageView, () => {
|
2016-08-17 06:01:20 +08:00
|
|
|
this.toggleFullScreen();
|
2016-06-30 08:02:45 +08:00
|
|
|
return false;
|
2016-08-17 06:01:20 +08:00
|
|
|
});
|
2016-07-01 06:50:11 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
// reply
|
2021-03-16 23:06:16 +08:00
|
|
|
shortcuts.add('r,mailreply', '', [Scope.MessageList, Scope.MessageView], () => {
|
2022-01-27 00:08:10 +08:00
|
|
|
if (currentMessage()) {
|
2016-08-17 06:01:20 +08:00
|
|
|
this.replyCommand();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
});
|
2016-06-30 08:02:45 +08:00
|
|
|
|
2021-08-13 02:17:37 +08:00
|
|
|
// replyAll
|
2021-03-16 23:06:16 +08:00
|
|
|
shortcuts.add('a', '', [Scope.MessageList, Scope.MessageView], () => {
|
2022-01-27 00:08:10 +08:00
|
|
|
if (currentMessage()) {
|
2016-08-17 06:01:20 +08:00
|
|
|
this.replyAllCommand();
|
|
|
|
return false;
|
|
|
|
}
|
2020-10-09 16:31:44 +08:00
|
|
|
});
|
2021-03-16 23:06:16 +08:00
|
|
|
shortcuts.add('mailreply', 'shift', [Scope.MessageList, Scope.MessageView], () => {
|
2022-01-27 00:08:10 +08:00
|
|
|
if (currentMessage()) {
|
2020-10-09 16:31:44 +08:00
|
|
|
this.replyAllCommand();
|
|
|
|
return false;
|
|
|
|
}
|
2016-08-17 06:01:20 +08:00
|
|
|
});
|
2014-04-08 05:03:58 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
// forward
|
2021-03-16 23:06:16 +08:00
|
|
|
shortcuts.add('f,mailforward', '', [Scope.MessageList, Scope.MessageView], () => {
|
2022-01-27 00:08:10 +08:00
|
|
|
if (currentMessage()) {
|
2016-08-17 06:01:20 +08:00
|
|
|
this.forwardCommand();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// message information
|
2021-03-16 23:06:16 +08:00
|
|
|
shortcuts.add('i', 'meta', [Scope.MessageList, Scope.MessageView], () => {
|
2022-01-27 00:08:10 +08:00
|
|
|
if (currentMessage()) {
|
2016-08-17 06:01:20 +08:00
|
|
|
this.showFullInfo(!this.showFullInfo());
|
2014-11-20 07:25:39 +08:00
|
|
|
}
|
2016-08-17 06:01:20 +08:00
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
// toggle message blockquotes
|
2021-03-16 23:06:16 +08:00
|
|
|
shortcuts.add('b', '', [Scope.MessageList, Scope.MessageView], () => {
|
2022-01-27 00:08:10 +08:00
|
|
|
const message = currentMessage();
|
2020-08-27 21:45:47 +08:00
|
|
|
if (message && message.body) {
|
|
|
|
message.body.querySelectorAll('.rlBlockquoteSwitcher').forEach(node => node.click());
|
2016-08-17 06:01:20 +08:00
|
|
|
return false;
|
2014-11-20 07:25:39 +08:00
|
|
|
}
|
2016-08-17 06:01:20 +08:00
|
|
|
});
|
|
|
|
|
2021-03-16 23:06:16 +08:00
|
|
|
shortcuts.add('arrowup,arrowleft', 'meta', [Scope.MessageList, Scope.MessageView], () => {
|
2016-08-17 06:01:20 +08:00
|
|
|
this.goUpCommand();
|
2016-06-30 08:02:45 +08:00
|
|
|
return false;
|
2016-08-17 06:01:20 +08:00
|
|
|
});
|
2016-07-01 06:50:11 +08:00
|
|
|
|
2021-03-16 23:06:16 +08:00
|
|
|
shortcuts.add('arrowdown,arrowright', 'meta', [Scope.MessageList, Scope.MessageView], () => {
|
2016-08-17 06:01:20 +08:00
|
|
|
this.goDownCommand();
|
|
|
|
return false;
|
|
|
|
});
|
2015-04-14 02:45:09 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
// print
|
2021-03-16 23:06:16 +08:00
|
|
|
shortcuts.add('p,printscreen', 'meta', [Scope.MessageView, Scope.MessageList], () => {
|
2022-01-27 00:08:10 +08:00
|
|
|
currentMessage() && currentMessage().printMessage();
|
2016-08-17 06:01:20 +08:00
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
// delete
|
2021-03-16 23:06:16 +08:00
|
|
|
shortcuts.add('delete', '', Scope.MessageView, () => {
|
2020-09-26 06:02:29 +08:00
|
|
|
this.deleteCommand();
|
|
|
|
return false;
|
|
|
|
});
|
2021-03-16 23:06:16 +08:00
|
|
|
shortcuts.add('delete', 'shift', Scope.MessageView, () => {
|
2020-09-26 06:02:29 +08:00
|
|
|
this.deleteWithoutMoveCommand();
|
|
|
|
return false;
|
2016-08-17 06:01:20 +08:00
|
|
|
});
|
2015-04-14 02:45:09 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
// change focused state
|
2021-03-16 23:06:16 +08:00
|
|
|
shortcuts.add('arrowleft', '', Scope.MessageView, () => {
|
2022-01-27 00:08:10 +08:00
|
|
|
if (!this.fullScreenMode() && currentMessage() && SettingsUserStore.usePreviewPane()
|
2022-02-02 20:02:48 +08:00
|
|
|
&& !oMessageScrollerDom().scrollLeft) {
|
2021-03-16 23:06:16 +08:00
|
|
|
AppUserStore.focusedState(Scope.MessageList);
|
2020-09-26 06:02:29 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
2021-07-21 20:15:31 +08:00
|
|
|
shortcuts.add('tab', 'shift', Scope.MessageView, () => {
|
2022-01-27 00:08:10 +08:00
|
|
|
if (!this.fullScreenMode() && currentMessage() && SettingsUserStore.usePreviewPane()) {
|
2021-03-16 23:06:16 +08:00
|
|
|
AppUserStore.focusedState(Scope.MessageList);
|
2016-08-17 06:01:20 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
2016-06-30 08:02:45 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
/**
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
|
|
|
isDraftFolder() {
|
2022-01-27 00:08:10 +08:00
|
|
|
return currentMessage() && FolderUserStore.draftsFolder() === currentMessage().folder;
|
2016-08-17 06:01:20 +08:00
|
|
|
}
|
2016-06-30 08:02:45 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
/**
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
|
|
|
isSentFolder() {
|
2022-01-27 00:08:10 +08:00
|
|
|
return currentMessage() && FolderUserStore.sentFolder() === currentMessage().folder;
|
2016-08-17 06:01:20 +08:00
|
|
|
}
|
2016-06-30 08:02:45 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
/**
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
|
|
|
isSpamFolder() {
|
2022-01-27 00:08:10 +08:00
|
|
|
return currentMessage() && FolderUserStore.spamFolder() === currentMessage().folder;
|
2016-08-17 06:01:20 +08:00
|
|
|
}
|
2016-06-30 08:02:45 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
/**
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
|
|
|
isSpamDisabled() {
|
2022-01-27 00:08:10 +08:00
|
|
|
return currentMessage() && FolderUserStore.spamFolder() === UNUSED_OPTION_VALUE;
|
2016-08-17 06:01:20 +08:00
|
|
|
}
|
2016-06-30 08:02:45 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
/**
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
|
|
|
isArchiveFolder() {
|
2022-01-27 00:08:10 +08:00
|
|
|
return currentMessage() && FolderUserStore.archiveFolder() === currentMessage().folder;
|
2016-08-17 06:01:20 +08:00
|
|
|
}
|
2016-06-30 08:02:45 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
/**
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
|
|
|
isArchiveDisabled() {
|
2022-01-27 00:08:10 +08:00
|
|
|
return currentMessage() && FolderUserStore.archiveFolder() === UNUSED_OPTION_VALUE;
|
2016-06-30 08:02:45 +08:00
|
|
|
}
|
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
/**
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
|
|
|
isDraftOrSentFolder() {
|
|
|
|
return this.isDraftFolder() || this.isSentFolder();
|
2016-06-30 08:02:45 +08:00
|
|
|
}
|
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
composeClick() {
|
2021-03-10 18:43:23 +08:00
|
|
|
showMessageComposer();
|
2016-06-30 08:02:45 +08:00
|
|
|
}
|
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
scrollMessageToTop() {
|
2022-02-02 20:02:48 +08:00
|
|
|
oMessageScrollerDom().scrollTop = (50 < oMessageScrollerDom().scrollTop) ? 50 : 0;
|
2016-06-30 08:02:45 +08:00
|
|
|
}
|
2016-08-17 06:01:20 +08:00
|
|
|
|
|
|
|
scrollMessageToLeft() {
|
2022-02-02 20:02:48 +08:00
|
|
|
oMessageScrollerDom().scrollLeft = 0;
|
2016-06-30 08:02:45 +08:00
|
|
|
}
|
2015-04-25 06:15:11 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
downloadAsZip() {
|
2022-01-27 00:08:10 +08:00
|
|
|
const hashes = (currentMessage() ? currentMessage().attachments : [])
|
2022-02-11 00:01:36 +08:00
|
|
|
.map(item => (item && !item.isLinked() && item.checked() ? item.download : ''))
|
2021-01-22 19:23:20 +08:00
|
|
|
.filter(v => v);
|
2020-07-28 18:35:41 +08:00
|
|
|
if (hashes.length) {
|
2020-09-15 01:40:56 +08:00
|
|
|
Remote.attachmentsActions('Zip', hashes, this.downloadAsZipLoading)
|
2021-08-25 19:22:40 +08:00
|
|
|
.then(result => {
|
2022-02-10 23:35:55 +08:00
|
|
|
let hash = result && result.Result && result.Result.FileHash;
|
|
|
|
if (hash) {
|
|
|
|
download(attachmentDownload(hash), hash+'.zip');
|
2019-07-05 03:19:24 +08:00
|
|
|
} else {
|
|
|
|
this.downloadAsZipError(true);
|
|
|
|
}
|
|
|
|
})
|
2021-08-25 19:22:40 +08:00
|
|
|
.catch(() => this.downloadAsZipError(true));
|
2019-07-05 03:19:24 +08:00
|
|
|
} else {
|
2016-08-17 06:01:20 +08:00
|
|
|
this.highlightUnselectedAttachments(true);
|
|
|
|
}
|
2016-06-30 08:02:45 +08:00
|
|
|
}
|
2015-04-14 02:45:09 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
/**
|
|
|
|
* @param {MessageModel} oMessage
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
2021-08-13 02:17:37 +08:00
|
|
|
showImages() {
|
2022-02-02 20:02:48 +08:00
|
|
|
currentMessage().showExternalImages();
|
2016-06-30 08:02:45 +08:00
|
|
|
}
|
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
/**
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
|
|
|
printableCheckedMessageCount() {
|
2021-03-30 17:48:22 +08:00
|
|
|
const cnt = MessageUserStore.listCheckedOrSelectedUidsWithSubMails().length;
|
2021-03-13 00:08:58 +08:00
|
|
|
return 0 < cnt ? (100 > cnt ? cnt : '99+') : '';
|
2016-06-30 08:02:45 +08:00
|
|
|
}
|
2014-04-13 08:32:07 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
/**
|
|
|
|
* @param {MessageModel} oMessage
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
2021-08-13 02:17:37 +08:00
|
|
|
readReceipt() {
|
2022-01-27 00:08:10 +08:00
|
|
|
let oMessage = currentMessage()
|
2022-02-02 20:02:48 +08:00
|
|
|
if (oMessage.readReceipt()) {
|
2021-12-03 06:15:24 +08:00
|
|
|
Remote.request('SendReadReceiptMessage', null, {
|
|
|
|
MessageFolder: oMessage.folder,
|
|
|
|
MessageUid: oMessage.uid,
|
|
|
|
ReadReceipt: oMessage.readReceipt(),
|
|
|
|
Subject: i18n('READ_RECEIPT/SUBJECT', { SUBJECT: oMessage.subject() }),
|
|
|
|
Text: i18n('READ_RECEIPT/BODY', { 'READ-RECEIPT': AccountUserStore.email() })
|
|
|
|
});
|
2016-06-30 08:02:45 +08:00
|
|
|
|
2021-12-06 23:08:58 +08:00
|
|
|
oMessage.flags.push('$mdnsent');
|
|
|
|
// oMessage.flags.valueHasMutated();
|
2013-11-16 06:21:12 +08:00
|
|
|
|
2020-10-25 20:50:26 +08:00
|
|
|
MessageFlagsCache.store(oMessage);
|
2014-08-25 15:10:51 +08:00
|
|
|
|
2022-02-08 00:27:25 +08:00
|
|
|
MessageUserStore.reloadFlagsAndCachedMessage();
|
2016-08-17 06:01:20 +08:00
|
|
|
}
|
2016-06-30 08:02:45 +08:00
|
|
|
}
|
2022-01-17 22:58:23 +08:00
|
|
|
|
2022-02-02 20:02:48 +08:00
|
|
|
pgpDecrypt() {
|
|
|
|
const oMessage = currentMessage();
|
|
|
|
PgpUserStore.decrypt(oMessage).then(result => {
|
2022-02-01 18:49:56 +08:00
|
|
|
if (result && result.data) {
|
2022-02-02 20:02:48 +08:00
|
|
|
mimeToMessage(result.data, oMessage);
|
2022-02-04 00:04:10 +08:00
|
|
|
if (result.signatures && result.signatures.length) {
|
2022-02-03 17:17:18 +08:00
|
|
|
oMessage.pgpSigned(true);
|
|
|
|
oMessage.pgpVerified({
|
|
|
|
signatures: result.signatures,
|
|
|
|
success: !!result.signatures.length
|
|
|
|
});
|
|
|
|
}
|
2022-02-01 18:45:20 +08:00
|
|
|
}
|
|
|
|
});
|
2022-01-17 22:58:23 +08:00
|
|
|
}
|
|
|
|
|
2022-02-02 21:36:49 +08:00
|
|
|
pgpVerify(/*self, event*/) {
|
|
|
|
const oMessage = currentMessage()/*, ctrl = event.target.closest('.openpgp-control')*/;
|
|
|
|
PgpUserStore.verify(oMessage).then(result => {
|
|
|
|
if (result) {
|
|
|
|
oMessage.pgpVerified(result);
|
|
|
|
}
|
2022-02-02 22:24:32 +08:00
|
|
|
/*
|
|
|
|
if (result && result.success) {
|
2022-02-09 22:43:14 +08:00
|
|
|
i18n('OPENPGP/GOOD_SIGNATURE', {
|
2022-02-02 22:24:32 +08:00
|
|
|
USER: validKey.user + ' (' + validKey.id + ')'
|
|
|
|
});
|
|
|
|
message.getText()
|
|
|
|
} else {
|
|
|
|
const keyIds = arrayLength(signingKeyIds) ? signingKeyIds : null,
|
|
|
|
additional = keyIds
|
|
|
|
? keyIds.map(item => (item && item.toHex ? item.toHex() : null)).filter(v => v).join(', ')
|
|
|
|
: '';
|
|
|
|
|
2022-02-09 22:43:14 +08:00
|
|
|
i18n('OPENPGP/ERROR', {
|
2022-02-02 22:24:32 +08:00
|
|
|
ERROR: 'message'
|
|
|
|
}) + (additional ? ' (' + additional + ')' : '');
|
|
|
|
}
|
|
|
|
*/
|
2022-02-02 21:36:49 +08:00
|
|
|
});
|
2022-01-17 22:58:23 +08:00
|
|
|
}
|
2022-01-20 23:38:27 +08:00
|
|
|
|
2016-08-17 06:01:20 +08:00
|
|
|
}
|