Merge remote-tracking branch 'origin/master' into addressbook

This commit is contained in:
djmaze 2022-09-02 15:15:01 +02:00
commit 1a5b8819fa
204 changed files with 2050 additions and 2773 deletions

View file

@ -12,7 +12,7 @@ export class AbstractCollectionModel extends Array
}
onDestroy() {
this.forEach(item => item.onDestroy && item.onDestroy());
this.forEach(item => item.onDestroy?.());
}
/**

View file

@ -1,4 +1,3 @@
import { encodeHtml } from 'Common/Html';
import { AbstractModel } from 'Knoin/AbstractModel';
@ -284,7 +283,7 @@ export class EmailModel extends AbstractModel {
*/
static reviveFromJson(json) {
const email = super.reviveFromJson(json);
email && email.clearDuplicateName();
email?.clearDuplicateName();
return email;
}
@ -333,45 +332,13 @@ export class EmailModel extends AbstractModel {
/**
* @param {boolean} friendlyView = false
* @param {boolean=} wrapWithLink = false
* @param {boolean=} useEncodeHtml = false
* @returns {string}
*/
toLine(friendlyView, wrapWithLink, useEncodeHtml) {
let result = '',
toLink = (to, txt) => '<a href="mailto:' + to + '" target="_blank" tabindex="-1">' + encodeHtml(txt) + '</a>';
if (this.email) {
if (friendlyView && this.name) {
result = wrapWithLink
? toLink(
encodeHtml(this.email) + '?to=' + encodeURIComponent('"' + this.name + '" <' + this.email + '>'),
this.name
)
: (useEncodeHtml ? encodeHtml(this.name) : this.name);
} else {
result = this.email;
if (this.name) {
if (wrapWithLink) {
result =
encodeHtml('"' + this.name + '" <')
+ toLink(
encodeHtml(this.email) + '?to=' + encodeURIComponent('"' + this.name + '" <' + this.email + '>'),
result
)
+ encodeHtml('>');
} else {
result = '"' + this.name + '" <' + result + '>';
if (useEncodeHtml) {
result = encodeHtml(result);
}
}
} else if (wrapWithLink) {
result = toLink(encodeHtml(this.email), this.email);
}
}
}
return result;
toLine(friendlyView) {
let result = this.email;
return (result && this.name)
? (friendlyView ? this.name : '"' + this.name + '" <' + result + '>')
: result;
}
static splitEmailLine(line) {
@ -384,7 +351,7 @@ export class EmailModel extends AbstractModel {
? new EmailModel(item.address.replace(/^[<]+(.*)[>]+$/g, '$1'), item.name || '')
: null;
if (address && address.email) {
if (address?.email) {
exists = true;
}

View file

@ -30,7 +30,7 @@ export class EmailCollectionModel extends AbstractCollectionModel
toStringClear() {
const result = [];
this.forEach(email => {
if (email && email.email && email.name) {
if (email?.email && email?.name) {
result.push(email.email);
}
});

View file

@ -100,8 +100,8 @@ export const
.post('Folders', FolderUserStore.foldersLoading)
.then(data => {
data = FolderCollectionModel.reviveFromJson(data.Result);
data && data.storeIt();
fCallback && fCallback(true);
data?.storeIt();
fCallback?.(true);
// Repeat every 15 minutes?
// this.foldersTimeout = setTimeout(loadFolders, 900000);
})
@ -128,7 +128,7 @@ export class FolderCollectionModel extends AbstractCollectionModel
*/
static reviveFromJson(object) {
const expandedFolders = Local.get(ClientSideKeyNameExpandedFolders);
if (object && object.SystemFolders) {
if (object?.SystemFolders) {
forEachObjectEntry(SystemFolders, key =>
SystemFolders[key] = SettingsGet(key+'Folder') || object.SystemFolders[FolderType[key]]
);

View file

@ -3,10 +3,10 @@ import ko from 'ko';
import { MessagePriority } from 'Common/EnumsUser';
import { i18n } from 'Common/Translator';
import { doc } from 'Common/Globals';
import { doc, SettingsGet } from 'Common/Globals';
import { encodeHtml, plainToHtml, cleanHtml } from 'Common/Html';
import { isArray, arrayLength, forEachObjectEntry } from 'Common/Utils';
import { serverRequestRaw } from 'Common/Links';
import { serverRequestRaw, proxy } from 'Common/Links';
import { FolderUserStore } from 'Stores/User/Folder';
import { SettingsUserStore } from 'Stores/User/Settings';
@ -89,11 +89,15 @@ const
})
},
/**
* @param {EmailCollectionModel} emails
* @param {Object} unic
* @param {Map} localEmails
*/
replyHelper = (emails, unic, localEmails) => {
emails.forEach(email => {
if (undefined === unic[email.email]) {
unic[email.email] = true;
localEmails.push(email);
if (!unic[email.email] && !localEmails.has(email.email)) {
localEmails.set(email.email, email);
}
});
};
@ -319,7 +323,7 @@ export class MessageModel extends AbstractModel {
*/
fromDkimData() {
let result = ['none', ''];
if (1 === arrayLength(this.from) && this.from[0] && this.from[0].dkimStatus) {
if (1 === arrayLength(this.from) && this.from[0]?.dkimStatus) {
result = [this.from[0].dkimStatus, this.from[0].dkimValue || ''];
}
@ -375,7 +379,6 @@ export class MessageModel extends AbstractModel {
focused: this.focused(),
important: this.isImportant(),
withAttachments: !!this.attachments().length,
emptySubject: !this.subject(),
// hasChildrenMessage: 1 < this.threadsLen(),
hasUnseenSubMessage: this.hasUnseenSubMessage(),
hasFlaggedSubMessage: this.hasFlaggedSubMessage()
@ -396,7 +399,7 @@ export class MessageModel extends AbstractModel {
* @returns {string}
*/
fromAsSingleEmail() {
return isArray(this.from) && this.from[0] ? this.from[0].email : '';
return (isArray(this.from) && this.from[0]?.email) || '';
}
/**
@ -415,50 +418,36 @@ export class MessageModel extends AbstractModel {
/**
* @param {Object} excludeEmails
* @param {boolean=} last = false
* @returns {Array}
*/
replyEmails(excludeEmails, last) {
const result = [],
unic = undefined === excludeEmails ? {} : excludeEmails;
replyEmails(excludeEmails) {
const
result = new Map(),
unic = excludeEmails || {};
replyHelper(this.replyTo, unic, result);
if (!result.length) {
replyHelper(this.from, unic, result);
}
if (!result.length && !last) {
return this.replyEmails({}, true);
}
return result;
result.size || replyHelper(this.from, unic, result);
return result.size ? [...result.values()] : [this.to[0]];
}
/**
* @param {Object} excludeEmails
* @param {boolean=} last = false
* @returns {Array.<Array>}
*/
replyAllEmails(excludeEmails, last) {
let data = [];
const toResult = [],
ccResult = [],
unic = undefined === excludeEmails ? {} : excludeEmails;
replyAllEmails(excludeEmails) {
const
toResult = new Map(),
ccResult = new Map(),
unic = excludeEmails || {};
replyHelper(this.replyTo, unic, toResult);
if (!toResult.length) {
if (!toResult.size) {
replyHelper(this.from, unic, toResult);
}
replyHelper(this.to, unic, toResult);
replyHelper(this.cc, unic, ccResult);
if (!toResult.length && !last) {
data = this.replyAllEmails({}, true);
return [data[0], ccResult];
}
return [toResult, ccResult];
return [[...toResult.values()], [...ccResult.values()]];
}
viewHtml() {
@ -617,16 +606,18 @@ export class MessageModel extends AbstractModel {
this.hasImages(false);
body.rlHasImages = false;
let attr = 'data-x-src';
body.querySelectorAll('[' + attr + ']').forEach(node => {
if (node.matches('img')) {
node.loading = 'lazy';
}
node.src = node.getAttribute(attr);
let attr = 'data-x-src',
src, useProxy = !!SettingsGet('UseLocalProxyForExternalImages');
body.querySelectorAll('img[' + attr + ']').forEach(node => {
node.loading = 'lazy';
src = node.getAttribute(attr);
node.src = useProxy ? proxy(src) : src;
});
body.querySelectorAll('[data-x-style-url]').forEach(node => {
JSON.parse(node.dataset.xStyleUrl).forEach(data => node.style[data[0]] = "url('" + data[1] + "')");
JSON.parse(node.dataset.xStyleUrl).forEach(data =>
node.style[data[0]] = "url('" + (useProxy ? proxy(data[1]) : data[1]) + "')"
);
});
}
}