mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Replaced tricky delegateRunOnDestroy() with koArrayWithDestroy()
koArrayWithDestroy creates ko.observableArray and calls the desired onDestroy() on entry delete.
This commit is contained in:
parent
f4bc796fb1
commit
e324e2f6b6
13 changed files with 32 additions and 55 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
import 'External/User/ko';
|
import 'External/User/ko';
|
||||||
|
|
||||||
import { isArray, arrayLength, pString, forEachObjectValue } from 'Common/Utils';
|
import { isArray, arrayLength, pString, forEachObjectValue } from 'Common/Utils';
|
||||||
import { delegateRunOnDestroy, mailToHelper, setLayoutResizer } from 'Common/UtilsUser';
|
import { mailToHelper, setLayoutResizer } from 'Common/UtilsUser';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Notification,
|
Notification,
|
||||||
|
|
@ -333,8 +333,6 @@ class AppUser extends AbstractApp {
|
||||||
if (isArray(accounts)) {
|
if (isArray(accounts)) {
|
||||||
// AccountUserStore.accounts.forEach(oAccount => counts[oAccount.email] = oAccount.count());
|
// AccountUserStore.accounts.forEach(oAccount => counts[oAccount.email] = oAccount.count());
|
||||||
|
|
||||||
delegateRunOnDestroy(AccountUserStore.accounts());
|
|
||||||
|
|
||||||
AccountUserStore.accounts(
|
AccountUserStore.accounts(
|
||||||
accounts.map(
|
accounts.map(
|
||||||
sValue => new AccountModel(sValue/*, counts[sValue]*/)
|
sValue => new AccountModel(sValue/*, counts[sValue]*/)
|
||||||
|
|
@ -345,8 +343,6 @@ class AppUser extends AbstractApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isArray(oData.Result.Identities)) {
|
if (isArray(oData.Result.Identities)) {
|
||||||
delegateRunOnDestroy(IdentityUserStore());
|
|
||||||
|
|
||||||
IdentityUserStore(
|
IdentityUserStore(
|
||||||
oData.Result.Identities.map(identityData => {
|
oData.Result.Identities.map(identityData => {
|
||||||
const identity = new IdentityModel(
|
const identity = new IdentityModel(
|
||||||
|
|
|
||||||
|
|
@ -102,17 +102,6 @@ folderListOptionsBuilder = (
|
||||||
return aResult;
|
return aResult;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Call the Model/CollectionModel onDestroy() to clear knockout functions/objects
|
|
||||||
* @param {Object|Array} objectOrObjects
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
delegateRunOnDestroy = (objectOrObjects) => {
|
|
||||||
objectOrObjects && (isArray(objectOrObjects) ? objectOrObjects : [objectOrObjects]).forEach(
|
|
||||||
obj => obj.onDestroy && obj.onDestroy()
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns {function}
|
* @returns {function}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
13
dev/External/ko.js
vendored
13
dev/External/ko.js
vendored
|
|
@ -21,7 +21,18 @@ export const
|
||||||
addSubscribablesTo = (target, subscribables) =>
|
addSubscribablesTo = (target, subscribables) =>
|
||||||
forEachObjectEntry(subscribables, (key, fn) => target[key].subscribe(fn)),
|
forEachObjectEntry(subscribables, (key, fn) => target[key].subscribe(fn)),
|
||||||
|
|
||||||
dispose = disposable => disposable && isFunction(disposable.dispose) && disposable.dispose();
|
dispose = disposable => disposable && isFunction(disposable.dispose) && disposable.dispose(),
|
||||||
|
|
||||||
|
// With this we don't need delegateRunOnDestroy
|
||||||
|
koArrayWithDestroy = data => {
|
||||||
|
data = ko.observableArray(data);
|
||||||
|
data.subscribe(changes =>
|
||||||
|
changes.forEach(item =>
|
||||||
|
'deleted' === item.status && null == item.moved && item.value.onDestroy && item.value.onDestroy()
|
||||||
|
)
|
||||||
|
, data, 'arrayChange');
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
ko.bindingHandlers.tooltipErrorTip = {
|
ko.bindingHandlers.tooltipErrorTip = {
|
||||||
init: (element, fValueAccessor) => {
|
init: (element, fValueAccessor) => {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import ko from 'ko';
|
import { koArrayWithDestroy } from 'External/ko';
|
||||||
|
|
||||||
import { arrayLength, pString } from 'Common/Utils';
|
import { arrayLength, pString } from 'Common/Utils';
|
||||||
import { delegateRunOnDestroy } from 'Common/UtilsUser';
|
|
||||||
import { i18n } from 'Common/Translator';
|
import { i18n } from 'Common/Translator';
|
||||||
import { getFolderFromCacheList } from 'Common/Cache';
|
import { getFolderFromCacheList } from 'Common/Cache';
|
||||||
|
|
||||||
|
|
@ -65,7 +64,7 @@ export class FilterModel extends AbstractModel {
|
||||||
actionType: FilterAction.MoveTo
|
actionType: FilterAction.MoveTo
|
||||||
});
|
});
|
||||||
|
|
||||||
this.conditions = ko.observableArray();
|
this.conditions = koArrayWithDestroy();
|
||||||
|
|
||||||
const fGetRealFolderName = (folderFullName) => {
|
const fGetRealFolderName = (folderFullName) => {
|
||||||
const folder = getFolderFromCacheList(folderFullName);
|
const folder = getFolderFromCacheList(folderFullName);
|
||||||
|
|
@ -211,7 +210,6 @@ export class FilterModel extends AbstractModel {
|
||||||
|
|
||||||
removeCondition(oConditionToDelete) {
|
removeCondition(oConditionToDelete) {
|
||||||
this.conditions.remove(oConditionToDelete);
|
this.conditions.remove(oConditionToDelete);
|
||||||
delegateRunOnDestroy(oConditionToDelete);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setRecipients() {
|
setRecipients() {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
import ko from 'ko';
|
|
||||||
|
|
||||||
import { AbstractModel } from 'Knoin/AbstractModel';
|
import { AbstractModel } from 'Knoin/AbstractModel';
|
||||||
import { FilterModel } from 'Model/Filter';
|
import { FilterModel } from 'Model/Filter';
|
||||||
import { arrayLength, pString, b64EncodeJSON } from 'Common/Utils';
|
import { arrayLength, pString, b64EncodeJSON } from 'Common/Utils';
|
||||||
|
import { koArrayWithDestroy } from 'External/ko';
|
||||||
|
|
||||||
const SIEVE_FILE_NAME = 'rainloop.user';
|
const SIEVE_FILE_NAME = 'rainloop.user';
|
||||||
|
|
||||||
|
|
@ -275,7 +274,7 @@ export class SieveScriptModel extends AbstractModel
|
||||||
hasChanges: false
|
hasChanges: false
|
||||||
});
|
});
|
||||||
|
|
||||||
this.filters = ko.observableArray();
|
this.filters = koArrayWithDestroy();
|
||||||
// this.saving = ko.observable(false).extend({ debounce: 200 });
|
// this.saving = ko.observable(false).extend({ debounce: 200 });
|
||||||
|
|
||||||
this.addSubscribables({
|
this.addSubscribables({
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
import ko from 'ko';
|
|
||||||
|
|
||||||
import { getNotification } from 'Common/Translator';
|
import { getNotification } from 'Common/Translator';
|
||||||
import { forEachObjectValue } from 'Common/Utils';
|
import { forEachObjectValue } from 'Common/Utils';
|
||||||
import { addObservablesTo } from 'External/ko';
|
import { addObservablesTo } from 'External/ko';
|
||||||
import { delegateRunOnDestroy } from 'Common/UtilsUser';
|
|
||||||
|
|
||||||
import { SieveUserStore } from 'Stores/User/Sieve';
|
import { SieveUserStore } from 'Stores/User/Sieve';
|
||||||
import Remote from 'Remote/User/Fetch';
|
import Remote from 'Remote/User/Fetch';
|
||||||
|
|
@ -76,7 +73,6 @@ export class FiltersUserSettings /*extends AbstractViewSettings*/ {
|
||||||
this.setError((data && data.ErrorMessageAdditional) || getNotification(iError));
|
this.setError((data && data.ErrorMessageAdditional) || getNotification(iError));
|
||||||
} else {
|
} else {
|
||||||
this.scripts.remove(script);
|
this.scripts.remove(script);
|
||||||
delegateRunOnDestroy(script);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{name:script.name()}
|
{name:script.name()}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
import ko from 'ko';
|
import { addObservablesTo, koArrayWithDestroy } from 'External/ko';
|
||||||
import { addObservablesTo } from 'External/ko';
|
|
||||||
|
|
||||||
export const AccountUserStore = {
|
export const AccountUserStore = {
|
||||||
accounts: ko.observableArray(),
|
accounts: koArrayWithDestroy(),
|
||||||
loading: ko.observable(false).extend({ debounce: 100 }),
|
loading: ko.observable(false).extend({ debounce: 100 }),
|
||||||
|
|
||||||
getEmailAddresses: () => AccountUserStore.accounts.map(item => item.email)
|
getEmailAddresses: () => AccountUserStore.accounts.map(item => item.email)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import ko from 'ko';
|
import ko from 'ko';
|
||||||
import { SettingsGet } from 'Common/Globals';
|
import { SettingsGet } from 'Common/Globals';
|
||||||
import { pInt } from 'Common/Utils';
|
import { pInt } from 'Common/Utils';
|
||||||
import { addObservablesTo } from 'External/ko';
|
import { addObservablesTo, koArrayWithDestroy } from 'External/ko';
|
||||||
import Remote from 'Remote/User/Fetch';
|
import Remote from 'Remote/User/Fetch';
|
||||||
|
|
||||||
export const ContactUserStore = ko.observableArray();
|
export const ContactUserStore = koArrayWithDestroy();
|
||||||
|
|
||||||
ContactUserStore.loading = ko.observable(false).extend({ debounce: 200 });
|
ContactUserStore.loading = ko.observable(false).extend({ debounce: 200 });
|
||||||
ContactUserStore.importing = ko.observable(false).extend({ debounce: 200 });
|
ContactUserStore.importing = ko.observable(false).extend({ debounce: 200 });
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import ko from 'ko';
|
import { koArrayWithDestroy } from 'External/ko';
|
||||||
|
|
||||||
export const IdentityUserStore = ko.observableArray();
|
export const IdentityUserStore = koArrayWithDestroy();
|
||||||
|
|
||||||
IdentityUserStore.getIDS = () => IdentityUserStore.map(item => (item ? item.id() : null))
|
IdentityUserStore.getIDS = () => IdentityUserStore.map(item => (item ? item.id() : null))
|
||||||
.filter(value => null !== value);
|
.filter(value => null !== value);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import ko from 'ko';
|
import { koArrayWithDestroy } from 'External/ko';
|
||||||
|
|
||||||
export const SieveUserStore = {
|
export const SieveUserStore = {
|
||||||
// capabilities
|
// capabilities
|
||||||
capa: ko.observableArray(),
|
capa: ko.observableArray(),
|
||||||
// Sieve scripts SieveScriptModel
|
// Sieve scripts SieveScriptModel
|
||||||
scripts: ko.observableArray()
|
scripts: koArrayWithDestroy()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,9 @@ import {
|
||||||
} from 'Common/EnumsUser';
|
} from 'Common/EnumsUser';
|
||||||
|
|
||||||
import { inFocus, pInt, isArray, arrayLength, forEachObjectEntry } from 'Common/Utils';
|
import { inFocus, pInt, isArray, arrayLength, forEachObjectEntry } from 'Common/Utils';
|
||||||
import { delegateRunOnDestroy, initFullscreen } from 'Common/UtilsUser';
|
import { initFullscreen } from 'Common/UtilsUser';
|
||||||
import { encodeHtml, HtmlEditor, htmlToPlain } from 'Common/Html';
|
import { encodeHtml, HtmlEditor, htmlToPlain } from 'Common/Html';
|
||||||
|
import { koArrayWithDestroy } from 'External/ko';
|
||||||
|
|
||||||
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
|
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
|
||||||
import { serverRequest } from 'Common/Links';
|
import { serverRequest } from 'Common/Links';
|
||||||
|
|
@ -237,7 +238,7 @@ class ComposePopupView extends AbstractViewPopup {
|
||||||
this.bcc.focused = ko.observable(false);
|
this.bcc.focused = ko.observable(false);
|
||||||
this.bcc.focused.subscribe(value => value && (this.sLastFocusedField = 'bcc'));
|
this.bcc.focused.subscribe(value => value && (this.sLastFocusedField = 'bcc'));
|
||||||
|
|
||||||
this.attachments = ko.observableArray();
|
this.attachments = koArrayWithDestroy();
|
||||||
|
|
||||||
this.dragAndDropOver = ko.observable(false).extend({ debounce: 1 });
|
this.dragAndDropOver = ko.observable(false).extend({ debounce: 1 });
|
||||||
this.dragAndDropVisible = ko.observable(false).extend({ debounce: 1 });
|
this.dragAndDropVisible = ko.observable(false).extend({ debounce: 1 });
|
||||||
|
|
@ -1380,7 +1381,6 @@ class ComposePopupView extends AbstractViewPopup {
|
||||||
const attachment = this.getAttachmentById(id);
|
const attachment = this.getAttachmentById(id);
|
||||||
if (attachment) {
|
if (attachment) {
|
||||||
this.attachments.remove(attachment);
|
this.attachments.remove(attachment);
|
||||||
delegateRunOnDestroy(attachment);
|
|
||||||
oJua && oJua.cancel(id);
|
oJua && oJua.cancel(id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1535,7 +1535,6 @@ class ComposePopupView extends AbstractViewPopup {
|
||||||
this.pgpSign(false);
|
this.pgpSign(false);
|
||||||
this.pgpEncrypt(false);
|
this.pgpEncrypt(false);
|
||||||
|
|
||||||
delegateRunOnDestroy(this.attachments());
|
|
||||||
this.attachments([]);
|
this.attachments([]);
|
||||||
|
|
||||||
this.dragAndDropOver(false);
|
this.dragAndDropOver(false);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import ko from 'ko';
|
import { koArrayWithDestroy } from 'External/ko';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
SaveSettingsStep,
|
SaveSettingsStep,
|
||||||
|
|
@ -8,7 +8,7 @@ import {
|
||||||
import { ComposeType } from 'Common/EnumsUser';
|
import { ComposeType } from 'Common/EnumsUser';
|
||||||
|
|
||||||
import { arrayLength, pInt } from 'Common/Utils';
|
import { arrayLength, pInt } from 'Common/Utils';
|
||||||
import { download, delegateRunOnDestroy, computedPaginatorHelper, showMessageComposer } from 'Common/UtilsUser';
|
import { download, computedPaginatorHelper, showMessageComposer } from 'Common/UtilsUser';
|
||||||
|
|
||||||
import { Selector } from 'Common/Selector';
|
import { Selector } from 'Common/Selector';
|
||||||
import { serverRequestRaw, serverRequest } from 'Common/Links';
|
import { serverRequestRaw, serverRequest } from 'Common/Links';
|
||||||
|
|
@ -66,7 +66,7 @@ class ContactsPopupView extends AbstractViewPopup {
|
||||||
|
|
||||||
this.contacts = ContactUserStore;
|
this.contacts = ContactUserStore;
|
||||||
|
|
||||||
this.viewProperties = ko.observableArray();
|
this.viewProperties = koArrayWithDestroy();
|
||||||
|
|
||||||
this.useCheckboxesInList = SettingsUserStore.useCheckboxesInList;
|
this.useCheckboxesInList = SettingsUserStore.useCheckboxesInList;
|
||||||
|
|
||||||
|
|
@ -346,10 +346,7 @@ class ContactsPopupView extends AbstractViewPopup {
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
contacts.forEach(contact => {
|
contacts.forEach(contact => ContactUserStore.remove(contact));
|
||||||
ContactUserStore.remove(contact);
|
|
||||||
delegateRunOnDestroy(contact);
|
|
||||||
});
|
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -373,7 +370,6 @@ class ContactsPopupView extends AbstractViewPopup {
|
||||||
|
|
||||||
removeProperty(oProp) {
|
removeProperty(oProp) {
|
||||||
this.viewProperties.remove(oProp);
|
this.viewProperties.remove(oProp);
|
||||||
delegateRunOnDestroy(oProp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -397,7 +393,6 @@ class ContactsPopupView extends AbstractViewPopup {
|
||||||
|
|
||||||
this.viewID(id);
|
this.viewID(id);
|
||||||
|
|
||||||
// delegateRunOnDestroy(this.viewProperties());
|
|
||||||
// this.viewProperties([]);
|
// this.viewProperties([]);
|
||||||
this.viewProperties(contact.properties);
|
this.viewProperties(contact.properties);
|
||||||
|
|
||||||
|
|
@ -436,7 +431,6 @@ class ContactsPopupView extends AbstractViewPopup {
|
||||||
|
|
||||||
this.contactsCount(count);
|
this.contactsCount(count);
|
||||||
|
|
||||||
delegateRunOnDestroy(ContactUserStore());
|
|
||||||
ContactUserStore(list);
|
ContactUserStore(list);
|
||||||
|
|
||||||
ContactUserStore.loading(false);
|
ContactUserStore.loading(false);
|
||||||
|
|
@ -516,7 +510,6 @@ class ContactsPopupView extends AbstractViewPopup {
|
||||||
this.search('');
|
this.search('');
|
||||||
this.contactsCount(0);
|
this.contactsCount(0);
|
||||||
|
|
||||||
delegateRunOnDestroy(ContactUserStore());
|
|
||||||
ContactUserStore([]);
|
ContactUserStore([]);
|
||||||
|
|
||||||
this.sLastComposeFocusedField = '';
|
this.sLastComposeFocusedField = '';
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import ko from 'ko';
|
||||||
|
|
||||||
import { getNotification, i18nToNodes } from 'Common/Translator';
|
import { getNotification, i18nToNodes } from 'Common/Translator';
|
||||||
import { addObservablesTo } from 'External/ko';
|
import { addObservablesTo } from 'External/ko';
|
||||||
import { delegateRunOnDestroy } from 'Common/UtilsUser';
|
|
||||||
|
|
||||||
import Remote from 'Remote/User/Fetch';
|
import Remote from 'Remote/User/Fetch';
|
||||||
import { FilterModel } from 'Model/Filter';
|
import { FilterModel } from 'Model/Filter';
|
||||||
|
|
@ -78,7 +77,6 @@ class SieveScriptPopupView extends AbstractViewPopup {
|
||||||
|
|
||||||
deleteFilter(filter) {
|
deleteFilter(filter) {
|
||||||
this.script().filters.remove(filter);
|
this.script().filters.remove(filter);
|
||||||
delegateRunOnDestroy(filter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addFilter() {
|
addFilter() {
|
||||||
|
|
@ -103,7 +101,6 @@ class SieveScriptPopupView extends AbstractViewPopup {
|
||||||
filters = script.filters(),
|
filters = script.filters(),
|
||||||
index = filters.indexOf(filter);
|
index = filters.indexOf(filter);
|
||||||
if (-1 < index) {
|
if (-1 < index) {
|
||||||
delegateRunOnDestroy(filters[index]);
|
|
||||||
filters[index] = clonedFilter;
|
filters[index] = clonedFilter;
|
||||||
script.filters(filters);
|
script.filters(filters);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue