Revamp array filtering

Replaced fakeMd5 with new Jua.randomId
Cleanup more code
This commit is contained in:
djmaze
2020-10-02 23:54:15 +02:00
parent 9992b20163
commit c3a2da65df
23 changed files with 130 additions and 289 deletions

View File

@@ -106,22 +106,22 @@ RainLoop 1.14 vs SnappyMail
|js/* |RainLoop |Snappy |
|----------- |--------: |--------: |
|admin.js |2.130.942 | 798.252 |
|app.js |4.184.455 |2.450.286 |
|admin.js |2.130.942 | 776.615 |
|app.js |4.184.455 |2.430.639 |
|boot.js | 671.522 | 5.285 |
|libs.js | 647.614 | 254.910 |
|libs.js | 647.614 | 255.041 |
|polyfills.js | 325.834 | 0 |
|TOTAL |7.960.367 |3.508.733 |
|TOTAL |7.960.367 |3.467.580 |
|js/min/* |RainLoop |Snappy |Rain gzip |gzip |brotli |
|--------------- |--------: |--------: |--------: |--------: |--------: |
|admin.min.js | 252.147 | 106.871 | 73.657 | 28.834 | 25.063 |
|app.min.js | 511.202 | 332.055 |140.462 | 85.613 | 69.336 |
|admin.min.js | 252.147 | 104.046 | 73.657 | 27.739 | 24.058 |
|app.min.js | 511.202 | 329.887 |140.462 | 84.844 | 68.843 |
|boot.min.js | 66.007 | 2.935 | 22.567 | 1.510 | 1.285 |
|libs.min.js | 572.545 | 149.580 |176.720 | 52.695 | 46.823 |
|libs.min.js | 572.545 | 149.712 |176.720 | 52.703 | 46.853 |
|polyfills.min.js | 32.452 | 0 | 11.312 | 0 | 0 |
|TOTAL |1.434.353 | 591.441 |424.718 |168.652 |142.507 |
|TOTAL (no admin) |1.182.206 | 484.570 |351.061 |139.818 |117.444 |
|TOTAL |1.434.353 | 586.580 |424.718 |166.796 |141.039 |
|TOTAL (no admin) |1.182.206 | 482.534 |351.061 |139.057 |116.981 |
For a user its around 60% smaller and faster than traditional RainLoop.

View File

@@ -82,7 +82,7 @@ class AdminApp extends AbstractApp {
return 'core' === item.type && !item.canBeInstalled ? null : item;
}
return null;
}).filter(value => !!value);
}).filter(v => v);
}
PackageStore.packages(list);

View File

@@ -255,8 +255,7 @@ class AppUser extends AbstractApp {
};
}
this.moveCache[hash].Uid = this.moveCache[hash].Uid.concat(uidsForMove)
.filter((value, index, self) => self.indexOf(value) == index);
this.moveCache[hash].Uid = this.moveCache[hash].Uid.concat(uidsForMove).unique();
this.messagesMoveTrigger();
}
@@ -457,7 +456,7 @@ class AppUser extends AbstractApp {
.toLowerCase(),
oItem.getKeyIds()
.map(item => (item && item.toHex ? item.toHex() : null))
.filter((value, index, self) => !!value && self.indexOf(value) == index),
.validUnique(),
aUsers,
aEmails,
oItem.isPrivate(),
@@ -537,7 +536,7 @@ class AppUser extends AbstractApp {
data.Result.Templates.map(templateData => {
const template = new TemplateModel();
return template.parse(templateData) ? template : null;
}).filter(value => !!value)
}).filter(v => v)
);
}
});
@@ -718,7 +717,7 @@ class AppUser extends AbstractApp {
}
rootUids = messages.map(oMessage => oMessage && oMessage.uid ? oMessage.uid : null)
.filter((value, index, self) => !!value && self.indexOf(value) == index);
.validUnique();
if (sFolderFullNameRaw && rootUids.length) {
switch (iSetAction) {
@@ -779,7 +778,7 @@ class AppUser extends AbstractApp {
Remote.suggestions((result, data) => {
if (StorageResultType.Success === result && data && Array.isArray(data.Result)) {
autocompleteCallback(
data.Result.map(item => (item && item[0] ? new EmailModel(item[0], item[1]) : null)).filter(value => !!value)
data.Result.map(item => (item && item[0] ? new EmailModel(item[0], item[1]) : null)).filter(v => v)
);
} else if (StorageResultType.Abort !== result) {
autocompleteCallback([]);

View File

@@ -301,7 +301,7 @@ export const File = {
if (Array.isNotEmpty(data)) {
let icons = data
.map(item => item ? File.getIconClass(File.getExtension(item[0]), item[1])[0] : '')
.filter((value, index, self) => value && self.indexOf(value) == index);
.validUnique();
return (icons && 1 === icons.length && 'icon-file' !== icons[0])
? icons[0]

View File

@@ -40,38 +40,6 @@ export function pString(value) {
return null != value ? '' + value : '';
}
/**
* @param {string} queryString
* @returns {Object}
*/
export function simpleQueryParser(queryString) {
const queries = queryString.split('&'),
params = {};
queries.forEach(temp => {
temp = temp.split('=');
params[decodeURIComponent(temp[0])] = decodeURIComponent(temp[1]);
});
return params;
}
/**
* @param {number=} len = 32
* @returns {string}
*/
export function fakeMd5(len = 32) {
const line = '0123456789abcdefghijklmnopqrstuvwxyz';
len = pInt(len);
let result = '';
while (len--)
result += line.substr(Math.round(Math.random() * 36), 1);
return result;
}
/**
* @param {string} text
* @returns {string}
@@ -85,7 +53,7 @@ export function encodeHtml(text) {
* @param {number=} len = 100
* @returns {string}
*/
export function splitPlainText(text, len = 100) {
function splitPlainText(text, len = 100) {
let prefix = '',
subText = '',
result = text,
@@ -139,72 +107,6 @@ export function inFocus() {
return false;
}
/**
* @param {boolean} force
* @returns {void}
*/
export function removeInFocus(force) {
if (doc.activeElement && doc.activeElement.blur) {
try {
if (force || doc.activeElement.matches('input,textarea')) {
doc.activeElement.blur();
}
} catch (e) {} // eslint-disable-line no-empty
}
}
/**
* @returns {void}
*/
export function removeSelection() {
try {
getSelection().removeAllRanges();
} catch (e) {} // eslint-disable-line no-empty
}
/**
* @param {string} prefix
* @param {string} subject
* @returns {string}
*/
export function 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();
}
/**
* @param {(number|string)} sizeInBytes
* @returns {string}
@@ -256,88 +158,18 @@ export function defautOptionsAfterRender(domItem, item) {
}
}
/**
* @param {Function} fCallback
* @param {?} koTrigger
* @param {?} context = null
* @param {number=} timer = 1000
* @returns {Function}
*/
export function settingsSaveHelperFunction(fCallback, koTrigger, context = null, timer = 1000) {
timer = pInt(timer);
return (type, data, cached, requestAction, requestParameters) => {
koTrigger.call(context, data && data.Result ? SaveSettingsStep.TrueResult : SaveSettingsStep.FalseResult);
if (fCallback) {
fCallback.call(context, type, data, cached, requestAction, requestParameters);
}
setTimeout(() => {
koTrigger.call(context, SaveSettingsStep.Idle);
}, timer);
};
}
/**
* @param {object} koTrigger
* @param {mixed} context
* @returns {mixed}
*/
export function settingsSaveHelperSimpleFunction(koTrigger, context) {
return settingsSaveHelperFunction(null, koTrigger, context, 1000);
}
/**
* @param {object} remote
* @param {string} settingName
* @param {string} type
* @param {function} fTriggerFunction
* @returns {function}
*/
export function settingsSaveHelperSubscribeFunction(remote, settingName, type, fTriggerFunction) {
return (value) => {
if (remote) {
switch (type) {
case 'bool':
case 'boolean':
value = value ? '1' : '0';
break;
case 'int':
case 'integer':
case 'number':
value = pInt(value);
break;
case 'trim':
value = value.trim();
break;
default:
value = pString(value);
break;
}
const data = {};
data[settingName] = value;
if (remote.saveAdminConfig) {
remote.saveAdminConfig(fTriggerFunction || null, data);
} else if (remote.saveSettings) {
remote.saveSettings(fTriggerFunction || null, data);
}
}
return (type, data) => {
koTrigger.call(context, data && data.Result ? SaveSettingsStep.TrueResult : SaveSettingsStep.FalseResult);
setTimeout(() => koTrigger.call(context, SaveSettingsStep.Idle), 1000);
};
}
/**
* @param {string} html
* @returns {string}
*/
/*eslint-disable max-len*/
const url = /(^|[\s\n]|\/?>)(https:\/\/[-A-Z0-9+\u0026\u2019#/%?=()~_|!:,.;]*[-A-Z0-9+\u0026#/%=~()_|])/gi,
email = /(^|[\s\n]|\/?>)((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x21\x23-\x5b\x5d-\x7f]|\\[\x21\x23-\x5b\x5d-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x21-\x5a\x53-\x7f]|\\[\x21\x23-\x5b\x5d-\x7f])+)\]))/gi;
export function findEmailAndLinks(html) {
return html
.replace(url, '$1<a href="$2" target="_blank">$2</a>')
.replace(email, '$1<a href="mailto:$2">$2</a>');
}
/**
* @param {string} html
* @returns {string}
@@ -644,18 +476,6 @@ export function folderListOptionsBuilder(
return aResult;
}
/**
* @param {object} element
* @returns {void}
*/
export function selectElement(element) {
let sel = getSelection(),
range = doc.createRange();
sel.removeAllRanges();
range.selectNodeContents(element);
sel.addRange(range);
}
/**
* @param {Object|Array} objectOrObjects
* @returns {void}
@@ -827,38 +647,6 @@ export function isTransparent(color) {
return 'rgba(0, 0, 0, 0)' === color || 'transparent' === color;
}
/**
* @param {string} url
* @param {number} value
* @param {Function} fCallback
*/
export function resizeAndCrop(url, value, fCallback) {
const img = new Image();
img.onload = function() {
let diff = [0, 0];
const canvas = doc.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.width = value;
canvas.height = value;
if (this.width > this.height) {
diff = [this.width - this.height, 0];
} else {
diff = [0, this.height - this.width];
}
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, value, value);
ctx.drawImage(this, diff[0] / 2, diff[1] / 2, this.width - diff[0], this.height - diff[1], 0, 0, value, value);
fCallback(canvas.toDataURL('image/jpeg'));
};
img.src = url;
}
/**
* @param {string} mailToUrl
* @param {Function} PopupComposeViewModel
@@ -888,7 +676,10 @@ export function mailToHelper(mailToUrl, PopupComposeViewModel) {
query = mailToUrl.replace(/^[^?]*\?/, ''),
EmailModel = require('Model/Email').default;
params = simpleQueryParser(query);
query.split('&').forEach(temp => {
temp = temp.split('=');
params[decodeURIComponent(temp[0])] = decodeURIComponent(temp[1]);
});
if (undefined !== params.to) {
to = EmailModel.parseEmailLine(decodeURIComponent(email + ',' + params.to));

View File

@@ -440,7 +440,7 @@ class EmailModel {
if (parsedResult.length) {
return parsedResult.map(item =>
item.address ? new EmailModel(item.address.replace(/^[<]+(.*)[>]+$/g, '$1'), item.name || '') : null
).filter(value => !!value);
).filter(v => v);
}
return [];

View File

@@ -1,7 +1,7 @@
import ko from 'ko';
import { FilterRulesType, FiltersAction } from 'Common/Enums';
import { pString, fakeMd5, delegateRunOnDestroy } from 'Common/Utils';
import { pString, delegateRunOnDestroy } from 'Common/Utils';
import { i18n } from 'Common/Translator';
import { getFolderFromCacheList } from 'Common/Cache';
@@ -133,7 +133,7 @@ class FilterModel extends AbstractModel {
}
generateID() {
this.id = fakeMd5();
this.id = Jua.randomId();
}
verify() {
@@ -230,7 +230,7 @@ class FilterModel extends AbstractModel {
json.Conditions.map(aData => {
const filterCondition = new FilterConditionModel();
return filterCondition && filterCondition.parse(aData) ? filterCondition : null;
}).filter(value => !!value)
}).filter(v => v)
);
}

View File

@@ -182,7 +182,7 @@ class MessageModel extends AbstractModel {
getEmails(properties) {
return properties.reduce((carry, property) => carry.concat(this[property]), []).map(
oItem => oItem ? oItem.email : ''
).filter((value, index, self) => !!value && self.indexOf(value) == index);
).validUnique();
}
/**

View File

@@ -105,7 +105,7 @@ class FiltersUserSettings {
data.Result.Filters.map(aItem => {
const filter = new FilterModel();
return filter && filter.parse(aItem) ? filter : null;
}).filter(value => !!value)
}).filter(v => v)
);
this.modules(data.Result.Modules ? data.Result.Modules : {});

View File

@@ -10,7 +10,7 @@ class AccountUserStore {
this.accounts = ko.observableArray([]);
this.accounts.loading = ko.observable(false).extend({ throttle: 100 });
this.getEmailAddresses = () => this.accounts().map(item => item ? item.email : null).filter(value => !!value);
this.getEmailAddresses = () => this.accounts().map(item => item ? item.email : null).filter(v => v);
this.accountsUnreadCount = ko.computed(() => 0);
// this.accountsUnreadCount = ko.computed(() => {

View File

@@ -85,7 +85,7 @@ class FolderUserStore {
});
this.folderListSystem = ko.computed(() =>
this.folderListSystemNames().map(name => getFolderFromCacheList(name)).filter(value => !!value)
this.folderListSystemNames().map(name => getFolderFromCacheList(name)).filter(v => v)
);
this.folderMenuForMove = ko.computed(() =>

View File

@@ -5,8 +5,7 @@ import { Layout, Focused, MessageSetAction, StorageResultType, Notification } fr
import {
pInt,
pString,
plainToHtml,
findEmailAndLinks
plainToHtml
} from 'Common/Utils';
import {
@@ -44,6 +43,14 @@ const
const result = hcont.clientHeight;
hcont.innerHTML = '';
return result;
},
/*eslint-disable max-len*/
url = /(^|[\s\n]|\/?>)(https:\/\/[-A-Z0-9+\u0026\u2019#/%?=()~_|!:,.;]*[-A-Z0-9+\u0026#/%=~()_|])/gi,
email = /(^|[\s\n]|\/?>)((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x21\x23-\x5b\x5d-\x7f]|\\[\x21\x23-\x5b\x5d-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x21-\x5a\x53-\x7f]|\\[\x21\x23-\x5b\x5d-\x7f])+)\]))/gi,
findEmailAndLinks = html => {
return html
.replace(url, '$1<a href="$2" target="_blank">$2</a>')
.replace(email, '$1<a href="mailto:$2">$2</a>');
};
let iMessageBodyCacheCount = 0;
@@ -142,7 +149,7 @@ class MessageUserStore {
if (checked.length) {
return selectedMessage
? checked.concat([selectedMessage]).filter((value, index, self) => self.indexOf(value) == index)
? checked.concat([selectedMessage]).unique()
: checked;
}
@@ -155,7 +162,7 @@ class MessageUserStore {
if (message) {
result.push(message.uid);
if (1 < message.threadsLen()) {
result = result.concat(message.threads()).filter((value, index, self) => self.indexOf(value) == index);
result = result.concat(message.threads()).unique();
}
}
});

View File

@@ -53,7 +53,7 @@ function domControlEncryptedClickHelper(store, dom, armoredMessage, recipients)
} else if (validPrivateKey) {
const keyIds = Array.isNotEmpty(signingKeyIds) ? signingKeyIds : null,
additional = keyIds
? keyIds.map(item => (item && item.toHex ? item.toHex() : null)).filter(value => !!value).join(', ')
? keyIds.map(item => (item && item.toHex ? item.toHex() : null)).filter(v => v).join(', ')
: '';
controlsHelper(
@@ -109,7 +109,7 @@ function domControlSignedClickHelper(store, dom, armoredMessage) {
} else {
const keyIds = Array.isNotEmpty(signingKeyIds) ? signingKeyIds : null,
additional = keyIds
? keyIds.map(item => (item && item.toHex ? item.toHex() : null)).filter(value => !!value).join(', ')
? keyIds.map(item => (item && item.toHex ? item.toHex() : null)).filter(v => v).join(', ')
: '';
controlsHelper(
@@ -138,8 +138,8 @@ class PgpUserStore {
this.openpgpkeys = ko.observableArray([]);
this.openpgpKeyring = null;
this.openpgpkeysPublic = ko.computed(() => this.openpgpkeys().filter(item => !!(item && !item.isPrivate)));
this.openpgpkeysPrivate = ko.computed(() => this.openpgpkeys().filter(item => !!(item && item.isPrivate)));
this.openpgpkeysPublic = ko.computed(() => this.openpgpkeys().filter(item => item && !item.isPrivate));
this.openpgpkeysPrivate = ko.computed(() => this.openpgpkeys().filter(item => item && item.isPrivate));
}
/**
@@ -165,14 +165,14 @@ class PgpUserStore {
return this.openpgpkeysPublic().map(item => {
const key = item && item.emails.includes(email) ? item : null;
return key ? key.getNativeKeys() : [null];
}).flat().filter(value => !!value);
}).flat().filter(v => v);
}
findPublicKeysBySigningKeyIds(signingKeyIds) {
return signingKeyIds.map(id => {
const key = id && id.toHex ? this.findPublicKeyByHex(id.toHex()) : null;
return key ? key.getNativeKeys() : [null];
}).flat().filter(value => !!value);
}).flat().filter(v => v);
}
findPrivateKeysByEncryptionKeyIds(encryptionKeyIds, recipients, returnWrapKeys) {
@@ -180,7 +180,7 @@ class PgpUserStore {
? encryptionKeyIds.map(id => {
const key = id && id.toHex ? this.findPrivateKeyByHex(id.toHex()) : null;
return key ? (returnWrapKeys ? [key] : key.getNativeKeys()) : [null];
}).flat().filter(value => !!value)
}).flat().filter(v => v)
: [];
if (!result.length && Array.isNotEmpty(recipients)) {
@@ -191,7 +191,7 @@ class PgpUserStore {
? keys
: keys.map(key => key.getNativeKeys()).flat()
: [null];
}).flat().filter((key, index, self) => key => !!key.id && self.indexOf(key) == index);
}).flat().validUnique(key => key.id);
}
return result;

View File

@@ -15,7 +15,7 @@ class TemplateUserStore {
subscribers() {
this.templates.subscribe((list) => {
this.templatesNames(list.map(item => (item ? item.name : null)).filter(value => !!value));
this.templatesNames(list.map(item => (item ? item.name : null)).filter(v => v));
});
// this.templatesNames.subscribe((aList) => {

View File

@@ -12,7 +12,6 @@ import {
} from 'Common/Enums';
import {
replySubjectAdd,
encodeHtml,
inFocus,
delegateRunOnDestroy,
@@ -42,7 +41,50 @@ import { ComposeAttachmentModel } from 'Model/ComposeAttachment';
import { popup, command, isPopupVisible, showScreenPopup, hideScreenPopup } from 'Knoin/Knoin';
import { AbstractViewNext } from 'Knoin/AbstractViewNext';
const Settings = rl.settings;
const Settings = rl.settings,
/**
* @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');
@@ -773,7 +815,7 @@ class ComposePopupView extends AbstractViewNext {
if (Array.isNotEmpty(emails)) {
const value = fKoValue().trim(),
values = emails.map(item => item ? item.toLine(false) : null)
.filter((value, index, self) => !!value && self.indexOf(value) == index);
.validUnique();
fKoValue(value + (value ? ', ' : '') + values.join(', ').trim());
}

View File

@@ -40,7 +40,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext {
this.encryptKeys = ko.observableArray([]);
this.encryptKeysView = ko.computed(
() => this.encryptKeys().map(oKey => (oKey ? oKey.key : null)).filter(value => !!value)
() => this.encryptKeys().map(oKey => (oKey ? oKey.key : null)).filter(v => v)
);
this.privateKeysOptions = ko.computed(() => {
@@ -56,7 +56,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext {
}));
});
return opts.flat().filter(value => !!value);
return opts.flat().filter(v => v);
});
this.publicKeysOptions = ko.computed(() => {
@@ -71,7 +71,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext {
'class': index % 2 ? 'odd' : 'even'
}));
});
return opts.flat().filter(value => !!value);
return opts.flat().filter(v => v);
});
this.submitRequest = ko.observable(false);
@@ -156,7 +156,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext {
this.encryptKeys().forEach(oKey => {
if (oKey && oKey.key) {
aPublicKeys = aPublicKeys.concat(oKey.key.getNativeKeys().flat(Infinity).filter(value => !!value));
aPublicKeys = aPublicKeys.concat(oKey.key.getNativeKeys().flat(Infinity).filter(v => v));
} else if (oKey && oKey.email) {
this.notification(
i18n('PGP_NOTIFICATIONS/NO_PUBLIC_KEYS_FOUND_FOR', {
@@ -349,7 +349,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext {
email.clear();
email.parse(value.trim());
return email.email || false;
}).filter(value => !!value);
}).filter(v => v);
if (identity && identity.email()) {
emailLine = identity.email();
@@ -385,9 +385,7 @@ class ComposeOpenPgpPopupView extends AbstractViewNext {
'key': publicKey
}))
: [];
}).flat().filter(
(encryptKey, index, self) => encryptKey => !!encryptKey.hash && self.indexOf(encryptKey) == index
)
}).flat().validUnique(encryptKey => encryptKey.hash)
);
if (this.encryptKeys().length) {

View File

@@ -13,7 +13,6 @@ import {
import {
delegateRunOnDestroy,
computedPagenatorHelper,
fakeMd5,
pInt
} from 'Common/Utils';
@@ -154,7 +153,7 @@ class ContactsPopupView extends AbstractViewNext {
selected = this.currentContact();
return selected
? checked.concat([selected]).filter((value, index, self) => self.indexOf(value) == index)
? checked.concat([selected]).unique()
: checked;
});
@@ -282,7 +281,7 @@ class ContactsPopupView extends AbstractViewNext {
this.viewSaving(true);
this.viewSaveTrigger(SaveSettingsStep.Animate);
const requestUid = fakeMd5(),
const requestUid = Jua.randomId(),
properties = [];
this.viewProperties().forEach(oItem => {
@@ -579,7 +578,7 @@ class ContactsPopupView extends AbstractViewNext {
return contact.parse(item) ? contact : null;
});
list = list.filter(value => !!value);
list = list.filter(v => v);
count = pInt(data.Result.Count);
count = 0 < count ? count : 0;

View File

@@ -1,7 +1,6 @@
import ko from 'ko';
import { StorageResultType, Notification } from 'Common/Enums';
import { fakeMd5 } from 'Common/Utils';
import { getNotification } from 'Common/Translator';
import Remote from 'Remote/User/Fetch';
@@ -158,7 +157,7 @@ class IdentityPopupView extends AbstractViewNext {
this.owner(!this.id);
} else {
this.id = fakeMd5();
this.id = Jua.randomId();
}
}

View File

@@ -1,7 +1,6 @@
import ko from 'ko';
import { KeyState } from 'Common/Enums';
import { selectElement } from 'Common/Utils';
import { popup } from 'Knoin/Knoin';
import { AbstractViewNext } from 'Knoin/AbstractViewNext';
@@ -27,7 +26,11 @@ class ViewOpenPgpKeyPopupView extends AbstractViewNext {
selectKey() {
const el = this.keyDom();
if (el) {
selectElement(el);
let sel = getSelection(),
range = document.createRange();
sel.removeAllRanges();
range.selectNodeContents(el);
sel.addRange(range);
}
}

View File

@@ -17,7 +17,6 @@ import { $htmlCL, leftPanelDisabled, keyScopeReal, moveAction } from 'Common/Glo
import {
inFocus,
removeSelection,
mailToHelper,
isTransparent
} from 'Common/Utils';
@@ -336,7 +335,9 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
}
toggleFullScreen() {
removeSelection();
try {
getSelection().removeAllRanges();
} catch (e) {} // eslint-disable-line no-empty
this.fullScreenMode(!this.fullScreenMode());
}
@@ -365,7 +366,7 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
// var oEmailModel = new EmailModel();
// oEmailModel.parse(sItem);
// return oEmailModel.email ? oEmailModel : null;
// }).filter(value => !!value) : null;
// }).filter(v => v) : null;
// }
// ;
//
@@ -395,7 +396,7 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
};
}
return null;
}).filter(value => !!value);
}).filter(v => v);
if (items.length) {
}
@@ -712,7 +713,7 @@ class MessageViewMailBoxUserView extends AbstractViewNext {
getAttachmentsHashes() {
const atts = this.message() ? this.message().attachments() : [];
return atts.map(item => (item && !item.isLinked && item.checked() ? item.download : '')).filter(value => !!value);
return atts.map(item => (item && !item.isLinked && item.checked() ? item.download : '')).filter(v => v);
}
downloadAsZip() {

6
dev/prototype.js vendored
View File

@@ -2,6 +2,9 @@
(w=>{
Array.isNotEmpty = array => Array.isArray(array) && array.length;
Array.prototype.unique = function() { return this.filter((v, i, a) => a.indexOf(v) === i); };
Array.prototype.validUnique = function(fn) {
return this.filter((v, i, a) => (fn ? fn(v) : v) && a.indexOf(v) === i);
};
// Import momentjs locales function
w.moment = {
@@ -45,7 +48,6 @@
}
},
pad2 = v => 10 > v ? '0' + v : v,
pad3 = v => 10 > v ? '00' + v : (100 > v ? '0' + v : v),
getISODay = x => x.getDay() || 7,
getDayOfYear = x => Math.floor((Date.UTC(x.getFullYear(),x.getMonth(),x.getDate())
- Date.UTC(x.getFullYear(),0,1)) / 86400000),
@@ -149,7 +151,7 @@
case 'H': return pad2(d.H);
case 'i': return pad2(UTC?x.getUTCMinutes():x.getMinutes());
case 's': return pad2(UTC?x.getUTCSeconds():x.getSeconds());
case 'u': return pad3(UTC?x.getUTCMilliseconds():x.getMilliseconds());
case 'u': return (UTC?x.getUTCMilliseconds():x.getMilliseconds()).toString().padStart(3,'0');
// Timezone
case 'I': return UTC ? 0 : isDST(x) ? 1 : 0;
case 'O': return UTC ? 'Z' : (d.Z > 0 ? '+' : '-') + pad2(Math.abs(d.Z / 60)) + '00';

14
vendors/jua/jua.js vendored
View File

@@ -488,13 +488,7 @@
*/
addNewFile(oFileInfo)
{
let iLen = 16,
fakeMd5 = '';
while (iLen--)
fakeMd5 += '0123456789abcdefghijklmnopqrstuvwxyz'.substr(Math.round(Math.random() * 36), 1);
this.addFile('jua-uid-' + fakeMd5 + '-' + (Date.now().toString()), oFileInfo);
this.addFile('jua-uid-' + Jua.randomId(16) + '-' + (Date.now().toString()), oFileInfo);
}
/**
@@ -516,6 +510,12 @@
}
}
Jua.randomId = len => {
let arr = new Uint8Array((len || 32) / 2);
crypto.getRandomValues(arr);
return arr.map(dec => dec.toString(16).padStart(2,'0')).join('');
}
/**
* @type {number}
*/

File diff suppressed because one or more lines are too long