mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-06 07:57:02 +03:00
Improved messages cache handling and fixed broken messagesBodiesDom
This commit is contained in:
parent
15f9aa11db
commit
4fb359be59
7 changed files with 124 additions and 135 deletions
|
|
@ -5,7 +5,6 @@ import { doc, createElement, elementById, dropdowns, dropdownVisibility, Setting
|
||||||
import { plainToHtml } from 'Common/Html';
|
import { plainToHtml } from 'Common/Html';
|
||||||
import { getNotification } from 'Common/Translator';
|
import { getNotification } from 'Common/Translator';
|
||||||
import { EmailCollectionModel } from 'Model/EmailCollection';
|
import { EmailCollectionModel } from 'Model/EmailCollection';
|
||||||
import { MessageModel } from 'Model/Message';
|
|
||||||
import { MessageUserStore } from 'Stores/User/Message';
|
import { MessageUserStore } from 'Stores/User/Message';
|
||||||
import { MessagelistUserStore } from 'Stores/User/Messagelist';
|
import { MessagelistUserStore } from 'Stores/User/Messagelist';
|
||||||
import { SettingsUserStore } from 'Stores/User/Settings';
|
import { SettingsUserStore } from 'Stores/User/Settings';
|
||||||
|
|
@ -246,75 +245,80 @@ setLayoutResizer = (source, sClientSideKeyName, mode) =>
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
viewMessage = (oMessage, popup) => {
|
||||||
|
if (popup) {
|
||||||
|
oMessage.viewPopupMessage();
|
||||||
|
} else {
|
||||||
|
MessageUserStore.error('');
|
||||||
|
let id = 'rl-msg-' + oMessage.hash,
|
||||||
|
body = oMessage.body || elementById(id);
|
||||||
|
if (!body) {
|
||||||
|
body = createElement('div',{
|
||||||
|
id:id,
|
||||||
|
hidden:'',
|
||||||
|
class:'b-text-part'
|
||||||
|
+ (oMessage.pgpSigned() ? ' openpgp-signed' : '')
|
||||||
|
+ (oMessage.pgpEncrypted() ? ' openpgp-encrypted' : '')
|
||||||
|
});
|
||||||
|
MessageUserStore.purgeCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
body.message = oMessage;
|
||||||
|
oMessage.body = body;
|
||||||
|
|
||||||
|
if (!SettingsUserStore.viewHTML() || !oMessage.viewHtml()) {
|
||||||
|
oMessage.viewPlain();
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageUserStore.bodiesDom().append(body);
|
||||||
|
|
||||||
|
MessageUserStore.loading(false);
|
||||||
|
oMessage.body.hidden = false;
|
||||||
|
|
||||||
|
if (oMessage.isUnseen()) {
|
||||||
|
MessageUserStore.MessageSeenTimer = setTimeout(
|
||||||
|
() => MessagelistUserStore.setAction(oMessage.folder, MessageSetAction.SetSeen, [oMessage]),
|
||||||
|
SettingsUserStore.messageReadDelay() * 1000 // seconds
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
populateMessageBody = (oMessage, popup) => {
|
populateMessageBody = (oMessage, popup) => {
|
||||||
if (oMessage) {
|
if (oMessage) {
|
||||||
popup || MessageUserStore.message(oMessage);
|
popup || MessageUserStore.message(oMessage);
|
||||||
popup || MessageUserStore.loading(true);
|
if (oMessage.body) {
|
||||||
Remote.message((iError, oData/*, bCached*/) => {
|
viewMessage(oMessage, popup);
|
||||||
if (iError) {
|
} else {
|
||||||
if (Notification.RequestAborted !== iError && !popup) {
|
popup || MessageUserStore.loading(true);
|
||||||
MessageUserStore.message(null);
|
Remote.message((iError, oData/*, bCached*/) => {
|
||||||
MessageUserStore.error(getNotification(iError));
|
if (iError) {
|
||||||
}
|
if (Notification.RequestAborted !== iError && !popup) {
|
||||||
} else {
|
MessageUserStore.message(null);
|
||||||
let json = oData?.Result;
|
MessageUserStore.error(getNotification(iError));
|
||||||
if (json
|
}
|
||||||
&& MessageModel.validJson(json)
|
} else {
|
||||||
&& oMessage.hash === json.hash
|
let json = oData?.Result;
|
||||||
// && oMessage.folder === json.folder
|
if (json
|
||||||
// && oMessage.uid == json.uid
|
&& oMessage.hash === json.hash
|
||||||
&& oMessage.revivePropertiesFromJson(json)
|
// && oMessage.folder === json.folder
|
||||||
) {
|
// && oMessage.uid == json.uid
|
||||||
|
&& oMessage.revivePropertiesFromJson(json)
|
||||||
|
) {
|
||||||
/*
|
/*
|
||||||
if (bCached) {
|
if (bCached) {
|
||||||
delete json.flags;
|
delete json.flags;
|
||||||
}
|
|
||||||
*/
|
|
||||||
if (popup) {
|
|
||||||
oMessage.viewPopupMessage();
|
|
||||||
} else {
|
|
||||||
MessageUserStore.error('');
|
|
||||||
const messagesDom = MessageUserStore.bodiesDom();
|
|
||||||
if (messagesDom) {
|
|
||||||
let id = 'rl-msg-' + oMessage.hash,
|
|
||||||
body = elementById(id);
|
|
||||||
if (body) {
|
|
||||||
oMessage.body = body;
|
|
||||||
oMessage.isHtml(body.classList.contains('html'));
|
|
||||||
oMessage.hasImages(body.rlHasImages);
|
|
||||||
} else {
|
|
||||||
body = createElement('div',{
|
|
||||||
id:id,
|
|
||||||
hidden:'',
|
|
||||||
class:'b-text-part'
|
|
||||||
+ (oMessage.pgpSigned() ? ' openpgp-signed' : '')
|
|
||||||
+ (oMessage.pgpEncrypted() ? ' openpgp-encrypted' : '')
|
|
||||||
});
|
|
||||||
oMessage.body = body;
|
|
||||||
if (!SettingsUserStore.viewHTML() || !oMessage.viewHtml()) {
|
|
||||||
oMessage.viewPlain();
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageUserStore.purgeMessageBodyCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
messagesDom.append(body);
|
|
||||||
|
|
||||||
oMessage.body.hidden = false;
|
|
||||||
}
|
}
|
||||||
}
|
oMessage.body.remove();
|
||||||
|
*/
|
||||||
|
viewMessage(oMessage, popup);
|
||||||
|
|
||||||
MessageFlagsCache.initMessage(oMessage);
|
MessageFlagsCache.initMessage(oMessage);
|
||||||
if (oMessage.isUnseen()) {
|
|
||||||
MessageUserStore.MessageSeenTimer = setTimeout(
|
|
||||||
() => MessagelistUserStore.setAction(oMessage.folder, MessageSetAction.SetSeen, [oMessage]),
|
|
||||||
SettingsUserStore.messageReadDelay() * 1000 // seconds
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
popup || MessageUserStore.loading(false);
|
||||||
popup || MessageUserStore.loading(false);
|
}, oMessage.folder, oMessage.uid);
|
||||||
}, oMessage.folder, oMessage.uid);
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -290,49 +290,46 @@ export class MessageModel extends AbstractModel {
|
||||||
return [[...toResult.values()], [...ccResult.values()]];
|
return [[...toResult.values()], [...ccResult.values()]];
|
||||||
}
|
}
|
||||||
|
|
||||||
viewHtml() {
|
viewBody(html) {
|
||||||
const body = this.body;
|
const body = this.body;
|
||||||
if (body && this.html()) {
|
if (body) {
|
||||||
let result = msgHtml(this);
|
if (html) {
|
||||||
this.hasExternals(result.hasExternals);
|
let result = msgHtml(this);
|
||||||
this.hasImages(body.rlHasImages = !!result.hasExternals);
|
this.hasExternals(result.hasExternals);
|
||||||
|
this.hasImages(!!result.hasExternals);
|
||||||
body.innerHTML = result.html;
|
body.innerHTML = result.html;
|
||||||
|
if (!this.isSpam() && FolderUserStore.spamFolder() != this.folder) {
|
||||||
body.classList.toggle('html', 1);
|
if ('always' === SettingsUserStore.viewImages()) {
|
||||||
body.classList.toggle('plain', 0);
|
this.showExternalImages();
|
||||||
|
}
|
||||||
if (!this.isSpam() && FolderUserStore.spamFolder() != this.folder) {
|
if ('match' === SettingsUserStore.viewImages()) {
|
||||||
if ('always' === SettingsUserStore.viewImages()) {
|
this.showExternalImages(1);
|
||||||
this.showExternalImages();
|
}
|
||||||
}
|
|
||||||
if ('match' === SettingsUserStore.viewImages()) {
|
|
||||||
this.showExternalImages(1);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
body.innerHTML = plainToHtml(
|
||||||
|
(this.plain()
|
||||||
|
? this.plain()
|
||||||
|
.replace(/-----BEGIN PGP (SIGNED MESSAGE-----(\r?\n[a-z][^\r\n]+)+|SIGNATURE-----[\s\S]*)/, '')
|
||||||
|
.trim()
|
||||||
|
: htmlToPlain(body.innerHTML)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
this.hasImages(false);
|
||||||
}
|
}
|
||||||
|
body.classList.toggle('html', html);
|
||||||
this.isHtml(true);
|
body.classList.toggle('plain', !html);
|
||||||
|
this.isHtml(html);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewHtml() {
|
||||||
|
return this.html() && this.viewBody(true);
|
||||||
|
}
|
||||||
|
|
||||||
viewPlain() {
|
viewPlain() {
|
||||||
const body = this.body;
|
return this.viewBody(false);
|
||||||
if (body) {
|
|
||||||
body.classList.toggle('html', 0);
|
|
||||||
body.classList.toggle('plain', 1);
|
|
||||||
body.innerHTML = plainToHtml(
|
|
||||||
(this.plain()
|
|
||||||
? this.plain()
|
|
||||||
.replace(/-----BEGIN PGP (SIGNED MESSAGE-----(\r?\n[a-z][^\r\n]+)+|SIGNATURE-----[\s\S]*)/, '')
|
|
||||||
.trim()
|
|
||||||
: htmlToPlain(body.innerHTML)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
this.isHtml(false);
|
|
||||||
this.hasImages(false);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
viewPopupMessage(print) {
|
viewPopupMessage(print) {
|
||||||
|
|
@ -447,7 +444,6 @@ export class MessageModel extends AbstractModel {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.hasImages(hasImages);
|
this.hasImages(hasImages);
|
||||||
body.rlHasImages = hasImages;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ import { LanguageStore } from 'Stores/Language';
|
||||||
import { SettingsUserStore } from 'Stores/User/Settings';
|
import { SettingsUserStore } from 'Stores/User/Settings';
|
||||||
import { IdentityUserStore } from 'Stores/User/Identity';
|
import { IdentityUserStore } from 'Stores/User/Identity';
|
||||||
import { NotificationUserStore } from 'Stores/User/Notification';
|
import { NotificationUserStore } from 'Stores/User/Notification';
|
||||||
import { MessageUserStore } from 'Stores/User/Message';
|
|
||||||
import { MessagelistUserStore } from 'Stores/User/Messagelist';
|
import { MessagelistUserStore } from 'Stores/User/Messagelist';
|
||||||
|
|
||||||
import Remote from 'Remote/User/Fetch';
|
import Remote from 'Remote/User/Fetch';
|
||||||
|
|
@ -102,7 +101,7 @@ export class UserSettingsGeneral extends AbstractViewSettings {
|
||||||
this.addSetting('Layout');
|
this.addSetting('Layout');
|
||||||
this.addSetting('MaxBlockquotesLevel');
|
this.addSetting('MaxBlockquotesLevel');
|
||||||
|
|
||||||
this.addSettings(['ViewHTML', 'ViewImages', 'ViewImagesWhitelist', 'HideDeleted', 'AllowStyles',
|
this.addSettings(['ViewHTML', 'ViewImages', 'ViewImagesWhitelist', 'HideDeleted', 'RemoveColors', 'AllowStyles',
|
||||||
'ListInlineAttachments', 'simpleAttachmentsList', 'UseCheckboxesInList', 'listGrouped', 'ReplySameFolder',
|
'ListInlineAttachments', 'simpleAttachmentsList', 'UseCheckboxesInList', 'listGrouped', 'ReplySameFolder',
|
||||||
'requestReadReceipt', 'requestDsn', 'requireTLS', 'pgpSign', 'pgpEncrypt', 'allowSpellcheck',
|
'requestReadReceipt', 'requestDsn', 'requireTLS', 'pgpSign', 'pgpEncrypt', 'allowSpellcheck',
|
||||||
'DesktopNotifications', 'SoundNotification', 'CollapseBlockquotes', 'AllowDraftAutosave']);
|
'DesktopNotifications', 'SoundNotification', 'CollapseBlockquotes', 'AllowDraftAutosave']);
|
||||||
|
|
@ -123,14 +122,6 @@ export class UserSettingsGeneral extends AbstractViewSettings {
|
||||||
hourCycle: value =>
|
hourCycle: value =>
|
||||||
Remote.saveSetting('hourCycle', value),
|
Remote.saveSetting('hourCycle', value),
|
||||||
|
|
||||||
removeColors: value => {
|
|
||||||
let dom = MessageUserStore.bodiesDom();
|
|
||||||
if (dom) {
|
|
||||||
dom.innerHTML = '';
|
|
||||||
}
|
|
||||||
Remote.saveSetting('RemoveColors', value);
|
|
||||||
},
|
|
||||||
|
|
||||||
notificationSound: value => {
|
notificationSound: value => {
|
||||||
Remote.saveSetting('NotificationSound', value);
|
Remote.saveSetting('NotificationSound', value);
|
||||||
Settings.set('NotificationSound', value);
|
Settings.set('NotificationSound', value);
|
||||||
|
|
|
||||||
|
|
@ -30,25 +30,21 @@ export const MessageUserStore = new class {
|
||||||
AppUserStore.focusedState(Scope.MessageList);
|
AppUserStore.focusedState(Scope.MessageList);
|
||||||
exitFullscreen();
|
exitFullscreen();
|
||||||
}
|
}
|
||||||
this.hideMessageBodies();
|
[...(this.bodiesDom()?.children || [])].forEach(el => el.hidden = true);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
this.purgeMessageBodyCache = this.purgeMessageBodyCache.throttle(30000);
|
this.purgeCache = this.purgeCache.throttle(30000);
|
||||||
}
|
}
|
||||||
|
|
||||||
purgeMessageBodyCache() {
|
purgeCache(all) {
|
||||||
const messagesDom = this.bodiesDom(),
|
const children = this.bodiesDom()?.children || [];
|
||||||
children = messagesDom?.children;
|
let i = Math.max(0, children.length - (all ? 0 : 15));
|
||||||
if (children) {
|
while (i--) {
|
||||||
while (15 < children.length) {
|
children[i].remove();
|
||||||
children[0].remove();
|
if (children[i].message) {
|
||||||
|
children[i].message.body = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hideMessageBodies() {
|
|
||||||
const messagesDom = this.bodiesDom();
|
|
||||||
messagesDom && Array.from(messagesDom.children).forEach(el => el.hidden = true);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,6 @@ export class MailMessageView extends AbstractViewRight {
|
||||||
|
|
||||||
this.message = currentMessage;
|
this.message = currentMessage;
|
||||||
this.messageLoadingThrottle = MessageUserStore.loading;
|
this.messageLoadingThrottle = MessageUserStore.loading;
|
||||||
this.messagesBodiesDom = MessageUserStore.bodiesDom;
|
|
||||||
this.messageError = MessageUserStore.error;
|
this.messageError = MessageUserStore.error;
|
||||||
|
|
||||||
this.fullScreenMode = isFullscreen;
|
this.fullScreenMode = isFullscreen;
|
||||||
|
|
@ -166,7 +165,7 @@ export class MailMessageView extends AbstractViewRight {
|
||||||
|
|
||||||
listAttachments: () => currentMessage()?.attachments()
|
listAttachments: () => currentMessage()?.attachments()
|
||||||
.filter(item => SettingsUserStore.listInlineAttachments() || !item.isLinked()),
|
.filter(item => SettingsUserStore.listInlineAttachments() || !item.isLinked()),
|
||||||
hasAttachments: () => this.listAttachments().length,
|
hasAttachments: () => this.listAttachments()?.length,
|
||||||
|
|
||||||
canBeRepliedOrForwarded: () => !MessagelistUserStore.isDraftFolder() && this.messageVisibility(),
|
canBeRepliedOrForwarded: () => !MessagelistUserStore.isDraftFolder() && this.messageVisibility(),
|
||||||
|
|
||||||
|
|
@ -459,6 +458,8 @@ export class MailMessageView extends AbstractViewRight {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
MessageUserStore.bodiesDom(dom.querySelector('.bodyText'));
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollMessageToTop() {
|
scrollMessageToTop() {
|
||||||
|
|
|
||||||
|
|
@ -70,9 +70,8 @@ export class SystemDropDownUserView extends AbstractViewRight {
|
||||||
/* // Not working yet
|
/* // Not working yet
|
||||||
forEachObjectEntry(oData.Result, (key, value) => rl.settings.set(key, value));
|
forEachObjectEntry(oData.Result, (key, value) => rl.settings.set(key, value));
|
||||||
clearCache();
|
clearCache();
|
||||||
// MessageUserStore.setMessage();
|
// MessageUserStore.message();
|
||||||
// MessageUserStore.purgeMessageBodyCache();
|
// MessageUserStore.purgeCache();
|
||||||
// MessageUserStore.hideMessageBodies();
|
|
||||||
MessagelistUserStore([]);
|
MessagelistUserStore([]);
|
||||||
// FolderUserStore.folderList([]);
|
// FolderUserStore.folderList([]);
|
||||||
loadFolders(value => {
|
loadFolders(value => {
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,7 @@
|
||||||
<div class="b-message-view-desc" data-i18n="MESSAGE/MESSAGE_VIEW_DESC" data-bind="visible: !message() && '' === messageError() && !hasCheckedMessages()">
|
<div class="b-message-view-desc" data-i18n="MESSAGE/MESSAGE_VIEW_DESC" data-bind="visible: !message() && '' === messageError() && !hasCheckedMessages()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ko if: message -->
|
<div class="b-message" data-bind="visible: message, css: message()?.lineAsCss(0)">
|
||||||
<div class="b-message" data-bind="i18nUpdate: message, css: message()?.lineAsCss(0)">
|
|
||||||
<div class="message-fixed-button-toolbar">
|
<div class="message-fixed-button-toolbar">
|
||||||
<a class="btn btn-success buttonEdit fontastic hide-mobile" data-bind="visible: isDraftFolder(), command: editCommand">🖉</a>
|
<a class="btn btn-success buttonEdit fontastic hide-mobile" data-bind="visible: isDraftFolder(), command: editCommand">🖉</a>
|
||||||
<div class="btn-group" style="margin-right: -8px; display: inline;">
|
<div class="btn-group" style="margin-right: -8px; display: inline;">
|
||||||
|
|
@ -121,7 +120,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="messageItemHeader">
|
<div class="messageItemHeader" data-bind="if: message, i18nUpdate: message">
|
||||||
<div class="subjectParent">
|
<div class="subjectParent">
|
||||||
<span class="infoParent g-ui-user-select-none fontastic" data-bind="click: toggleFullInfo">ℹ</span>
|
<span class="infoParent g-ui-user-select-none fontastic" data-bind="click: toggleFullInfo">ℹ</span>
|
||||||
<span class="flagParent g-ui-user-select-none flagOff fontastic" data-bind="text: message().isFlagged() ? '★' : '☆', css: {'flagOn': message().isFlagged(), 'flagOff': !message().isFlagged()}"></span>
|
<span class="flagParent g-ui-user-select-none flagOff fontastic" data-bind="text: message().isFlagged() ? '★' : '☆', css: {'flagOn': message().isFlagged(), 'flagOff': !message().isFlagged()}"></span>
|
||||||
|
|
@ -176,7 +175,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="messageItem">
|
<div id="messageItem">
|
||||||
<div class="messageItemHeader">
|
<div class="messageItemHeader" data-bind="if: message, i18nUpdate: message">
|
||||||
<div data-bind="hidden: showFullInfo">
|
<div data-bind="hidden: showFullInfo">
|
||||||
<time class="date" data-moment-format="FULL" data-bind="visible: 0 < message().dateTimeStampInUTC(), moment: message().dateTimeStampInUTC()"></time>
|
<time class="date" data-moment-format="FULL" data-bind="visible: 0 < message().dateTimeStampInUTC(), moment: message().dateTimeStampInUTC()"></time>
|
||||||
<div class="informationShortWrp">
|
<div class="informationShortWrp">
|
||||||
|
|
@ -223,7 +222,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-bind="hidden: messageLoadingThrottle">
|
<div data-bind="hidden: messageLoadingThrottle">
|
||||||
<div class="bodySubHeader">
|
<div class="bodySubHeader" data-bind="if: message, i18nUpdate: message">
|
||||||
<div class="readReceipt" data-bind="visible: askReadReceipt, click: readReceipt"
|
<div class="readReceipt" data-bind="visible: askReadReceipt, click: readReceipt"
|
||||||
data-icon="✉" data-i18n="MESSAGE/BUTTON_NOTIFY_READ_RECEIPT"></div>
|
data-icon="✉" data-i18n="MESSAGE/BUTTON_NOTIFY_READ_RECEIPT"></div>
|
||||||
<details class="attachmentsPlace" data-bind="visible: hasAttachments, css: {'selection-mode' : showAttachmentControls}">
|
<details class="attachmentsPlace" data-bind="visible: hasAttachments, css: {'selection-mode' : showAttachmentControls}">
|
||||||
|
|
@ -294,19 +293,22 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="openpgp-control encrypted" data-bind="visible: message().pgpEncrypted(), css: {'success': message().pgpDecrypted()}">
|
<!-- ko if: message()?.pgpEncrypted() -->
|
||||||
|
<div class="openpgp-control encrypted" data-bind="i18nUpdate: message, css: {'success': message().pgpDecrypted()}">
|
||||||
<span data-icon="🔒" data-i18n="OPENPGP/ENCRYPTED_MESSAGE"></span>
|
<span data-icon="🔒" data-i18n="OPENPGP/ENCRYPTED_MESSAGE"></span>
|
||||||
<button class="btn" data-bind="visible: pgpSupported, click: pgpDecrypt" data-i18n="OPENPGP/BUTTON_DECRYPT"></button>
|
<button class="btn" data-bind="visible: pgpSupported, click: pgpDecrypt" data-i18n="OPENPGP/BUTTON_DECRYPT"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="openpgp-control signed" data-bind="visible: message().pgpSigned(), css: {'success': message().pgpVerified() && message().pgpVerified().success, 'error': message().pgpVerified() && !message().pgpVerified().success}">
|
<!-- /ko -->
|
||||||
|
<!-- ko if: message()?.pgpSigned() -->
|
||||||
|
<div class="openpgp-control signed" data-bind="i18nUpdate: message, css: {'success': message().pgpVerified() && message().pgpVerified().success, 'error': message().pgpVerified() && !message().pgpVerified().success}">
|
||||||
<span data-icon="✍" data-i18n="OPENPGP/SIGNED_MESSAGE"></span>
|
<span data-icon="✍" data-i18n="OPENPGP/SIGNED_MESSAGE"></span>
|
||||||
<button class="btn" data-bind="visible: pgpSupported, click: pgpVerify" data-i18n="OPENPGP/BUTTON_VERIFY"></button>
|
<button class="btn" data-bind="visible: pgpSupported, click: pgpVerify" data-i18n="OPENPGP/BUTTON_VERIFY"></button>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- /ko -->
|
||||||
|
|
||||||
<div class="bodyText" data-bind="initDom: messagesBodiesDom"></div>
|
<div class="bodyText"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- /ko -->
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue