Cleanup knockout subscribables

This commit is contained in:
the-djmaze 2022-02-17 09:36:29 +01:00
parent 5748dea4bc
commit b2a492bdab
27 changed files with 73 additions and 75 deletions

View file

@ -50,16 +50,10 @@ export class AbstractApp {
viewModel: {
createViewModel: (params, componentInfo) => {
params = params || {};
if (componentInfo && componentInfo.element) {
i18nToNodes(componentInfo.element);
if (params.inline) {
componentInfo.element.style.display = 'inline-block';
}
}
return new ClassObject(params);
}
}

View file

@ -29,16 +29,6 @@ export const
domItem && item && undefined !== item.disabled
&& domItem.classList.toggle('disabled', domItem.disabled = item.disabled),
addObservablesTo = (target, observables) =>
forEachObjectEntry(observables, (key, value) =>
target[key] = /*isArray(value) ? ko.observableArray(value) :*/ ko.observable(value) ),
addComputablesTo = (target, computables) =>
forEachObjectEntry(computables, (key, fn) => target[key] = ko.computed(fn, {'pure':true})),
addSubscribablesTo = (target, subscribables) =>
forEachObjectEntry(subscribables, (key, fn) => target[key].subscribe(fn)),
inFocus = () => {
try {
return doc.activeElement && doc.activeElement.matches(

View file

@ -41,17 +41,17 @@ export class AbstractInput {
(size + ' settings-saved-trigger-input ' + classForTrigger()).trim()
);
this.disposable = [
this.disposables = [
this.trigger.subscribe(setTriggerState, this),
this.className
];
} else {
this.className = size;
this.disposable = [];
this.disposables = [];
}
}
dispose() {
this.disposable.forEach(dispose);
this.disposables.forEach(dispose);
}
}

12
dev/External/ko.js vendored
View file

@ -1,7 +1,7 @@
import { i18nToNodes } from 'Common/Translator';
import { doc, createElement } from 'Common/Globals';
import { SaveSettingsStep } from 'Common/Enums';
import { arrayLength, isFunction } from 'Common/Utils';
import { arrayLength, isFunction, forEachObjectEntry } from 'Common/Utils';
export const
/**
@ -11,6 +11,16 @@ export const
*/
koComputable = fn => ko.computed(fn, {'pure':true}),
addObservablesTo = (target, observables) =>
forEachObjectEntry(observables, (key, value) =>
target[key] = /*isArray(value) ? ko.observableArray(value) :*/ ko.observable(value) ),
addComputablesTo = (target, computables) =>
forEachObjectEntry(computables, (key, fn) => target[key] = koComputable(fn)),
addSubscribablesTo = (target, subscribables) =>
forEachObjectEntry(subscribables, (key, fn) => target[key].subscribe(fn)),
dispose = disposable => disposable && isFunction(disposable.dispose) && disposable.dispose();
ko.bindingHandlers.tooltipErrorTip = {

View file

@ -1,5 +1,5 @@
import { isArray, addObservablesTo, addComputablesTo, forEachObjectValue, forEachObjectEntry } from 'Common/Utils';
import { dispose } from 'External/ko';
import { isArray, forEachObjectValue, forEachObjectEntry } from 'Common/Utils';
import { dispose, addObservablesTo, addComputablesTo } from 'External/ko';
function typeCast(curValue, newValue) {
if (null != curValue) {
@ -26,7 +26,7 @@ export class AbstractModel {
throw new Error("Can't instantiate AbstractModel!");
}
*/
this.subscribables = [];
this.disposables = [];
}
addObservables(observables) {
@ -38,25 +38,26 @@ export class AbstractModel {
}
addSubscribables(subscribables) {
forEachObjectEntry(subscribables, (key, fn) => this.subscribables.push( this[key].subscribe(fn) ) );
// addSubscribablesTo(this, subscribables);
forEachObjectEntry(subscribables, (key, fn) => this.disposables.push( this[key].subscribe(fn) ) );
}
/** Called by delegateRunOnDestroy */
onDestroy() {
/** dispose ko subscribables */
this.subscribables.forEach(dispose);
this.disposables.forEach(dispose);
/** clear object entries */
// forEachObjectEntry(this, (key, value) => {
forEachObjectValue(this, value => {
/** clear CollectionModel */
let arr = ko.isObservableArray(value) ? value() : value;
arr && arr.onDestroy && value.onDestroy();
arr && arr.onDestroy && arr.onDestroy();
/** destroy ko.observable/ko.computed? */
dispose(value);
// dispose(value);
/** clear object value */
// this[key] = null; // TODO: issue with Contacts view
});
// this.subscribables = [];
// this.disposables = [];
}
/**

View file

@ -1,6 +1,7 @@
import ko from 'ko';
import { inFocus, addObservablesTo, addComputablesTo, addSubscribablesTo } from 'Common/Utils';
import { inFocus } from 'Common/Utils';
import { addObservablesTo, addComputablesTo, addSubscribablesTo } from 'External/ko';
import { Scope } from 'Common/Enums';
import { keyScope, Settings, leftPanelDisabled } from 'Common/Globals';
import { ViewType, showScreenPopup } from 'Knoin/Knoin';

View file

@ -1,6 +1,7 @@
import { SaveSettingsStep } from 'Common/Enums';
import { SettingsGet } from 'Common/Globals';
import { settingsSaveHelperSimpleFunction, addObservablesTo, addSubscribablesTo } from 'Common/Utils';
import { settingsSaveHelperSimpleFunction } from 'Common/Utils';
import { addObservablesTo, addSubscribablesTo } from 'External/ko';
import Remote from 'Remote/Admin/Fetch';

View file

@ -4,10 +4,9 @@ import { SaveSettingsStep } from 'Common/Enums';
import { SettingsGet } from 'Common/Globals';
import {
settingsSaveHelperSimpleFunction,
defaultOptionsAfterRender,
addObservablesTo,
addSubscribablesTo
defaultOptionsAfterRender
} from 'Common/Utils';
import { addObservablesTo, addSubscribablesTo } from 'External/ko';
import Remote from 'Remote/Admin/Fetch';
import { decorateKoCommands } from 'Knoin/Knoin';

View file

@ -5,12 +5,11 @@ import {
pInt,
settingsSaveHelperSimpleFunction,
changeTheme,
convertThemeName,
addObservablesTo,
addSubscribablesTo,
addComputablesTo
convertThemeName
} from 'Common/Utils';
import { addObservablesTo, addSubscribablesTo, addComputablesTo } from 'External/ko';
import { Capa, SaveSettingsStep } from 'Common/Enums';
import { Settings, SettingsGet, SettingsCapa } from 'Common/Globals';
import { translatorReload, convertLangName } from 'Common/Translator';

View file

@ -1,6 +1,7 @@
import { SaveSettingsStep } from 'Common/Enums';
import { Settings, SettingsGet } from 'Common/Globals';
import { settingsSaveHelperSimpleFunction, addObservablesTo, addSubscribablesTo } from 'Common/Utils';
import { settingsSaveHelperSimpleFunction } from 'Common/Utils';
import { addObservablesTo, addSubscribablesTo } from 'External/ko';
import Remote from 'Remote/Admin/Fetch';

View file

@ -9,7 +9,7 @@ import Remote from 'Remote/Admin/Fetch';
import { showScreenPopup } from 'Knoin/Knoin';
import { PluginPopupView } from 'View/Popup/Plugin';
import { SettingsGet } from 'Common/Globals';
import { addObservablesTo, addComputablesTo } from 'Common/Utils';
import { addObservablesTo, addComputablesTo } from 'External/ko';
export class PackagesAdminSettings /*extends AbstractViewSettings*/ {
constructor() {

View file

@ -1,6 +1,6 @@
import { Capa } from 'Common/Enums';
import { Settings, SettingsGet } from 'Common/Globals';
import { addObservablesTo, addSubscribablesTo } from 'Common/Utils';
import { addObservablesTo, addSubscribablesTo } from 'External/ko';
import Remote from 'Remote/Admin/Fetch';

View file

@ -1,7 +1,8 @@
import ko from 'ko';
import { getNotification } from 'Common/Translator';
import { addObservablesTo, forEachObjectValue } from 'Common/Utils';
import { forEachObjectValue } from 'Common/Utils';
import { addObservablesTo } from 'External/ko';
import { delegateRunOnDestroy } from 'Common/UtilsUser';
import { SieveUserStore } from 'Stores/User/Sieve';

View file

@ -3,7 +3,8 @@ import ko from 'ko';
import { SaveSettingsStep } from 'Common/Enums';
import { EditorDefaultType, Layout } from 'Common/EnumsUser';
import { Settings, SettingsGet } from 'Common/Globals';
import { isArray, settingsSaveHelperSimpleFunction, addObservablesTo, addSubscribablesTo, addComputablesTo } from 'Common/Utils';
import { isArray, settingsSaveHelperSimpleFunction } from 'Common/Utils';
import { addObservablesTo, addSubscribablesTo, addComputablesTo } from 'External/ko';
import { i18n, trigger as translatorTrigger, translatorReload, convertLangName } from 'Common/Translator';
import { showScreenPopup } from 'Knoin/Knoin';

View file

@ -1,5 +1,5 @@
import ko from 'ko';
import { addObservablesTo } from 'Common/Utils';
import { addObservablesTo } from 'External/ko';
export const AccountUserStore = {
accounts: ko.observableArray(),

View file

@ -1,6 +1,6 @@
import { Scope } from 'Common/Enums';
import { keyScope, leftPanelDisabled, SettingsGet, elementById } from 'Common/Globals';
import { addObservablesTo } from 'Common/Utils';
import { addObservablesTo } from 'External/ko';
import { ThemeStore } from 'Stores/Theme';
export const AppUserStore = {

View file

@ -1,6 +1,7 @@
import ko from 'ko';
import { SettingsGet } from 'Common/Globals';
import { pInt, addObservablesTo } from 'Common/Utils';
import { pInt } from 'Common/Utils';
import { addObservablesTo } from 'External/ko';
import Remote from 'Remote/User/Fetch';
export const ContactUserStore = ko.observableArray();

View file

@ -3,7 +3,8 @@ import { koComputable } from 'External/ko';
import { FolderType, FolderSortMode } from 'Common/EnumsUser';
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
import { addObservablesTo, addSubscribablesTo, addComputablesTo, forEachObjectEntry } from 'Common/Utils';
import { forEachObjectEntry } from 'Common/Utils';
import { addObservablesTo, addSubscribablesTo, addComputablesTo } from 'External/ko';
import { getFolderInboxName, getFolderFromCacheList } from 'Common/Cache';
import { Settings } from 'Common/Globals';
//import Remote from 'Remote/User/Fetch'; Circular dependency
@ -78,20 +79,22 @@ export const FolderUserStore = new class {
});
const
fRemoveSystemFolderType = (observable) => () => {
subscribeRemoveSystemFolder = observable => {
observable.subscribe(() => {
const folder = getFolderFromCacheList(observable());
folder && folder.type(FolderType.User);
}, self, 'beforeChange');
},
fSetSystemFolderType = type => value => {
const folder = getFolderFromCacheList(value);
folder && folder.type(type);
};
self.sentFolder.subscribe(fRemoveSystemFolderType(self.sentFolder), self, 'beforeChange');
self.draftsFolder.subscribe(fRemoveSystemFolderType(self.draftsFolder), self, 'beforeChange');
self.spamFolder.subscribe(fRemoveSystemFolderType(self.spamFolder), self, 'beforeChange');
self.trashFolder.subscribe(fRemoveSystemFolderType(self.trashFolder), self, 'beforeChange');
self.archiveFolder.subscribe(fRemoveSystemFolderType(self.archiveFolder), self, 'beforeChange');
subscribeRemoveSystemFolder(self.sentFolder);
subscribeRemoveSystemFolder(self.draftsFolder);
subscribeRemoveSystemFolder(self.spamFolder);
subscribeRemoveSystemFolder(self.trashFolder);
subscribeRemoveSystemFolder(self.archiveFolder);
addSubscribablesTo(self, {
sentFolder: fSetSystemFolderType(FolderType.Sent),

View file

@ -2,7 +2,6 @@ import ko from 'ko';
import { Capa } from 'Common/Enums';
import { SettingsCapa } from 'Common/Globals';
import { delegateRunOnDestroy } from 'Common/UtilsUser';
//import { EmailModel } from 'Model/Email';
//import { OpenPgpKeyModel } from 'Model/OpenPgpKey';
@ -60,7 +59,6 @@ export const GnuPGUserStore = new class {
} else {
this.publicKeys.remove(key);
}
delegateRunOnDestroy(key);
}
}, {
KeyId: key.id,

View file

@ -4,7 +4,8 @@ import { koComputable } from 'External/ko';
import { Scope, Notification } from 'Common/Enums';
import { MessageSetAction } from 'Common/EnumsUser';
import { $htmlCL, elementById } from 'Common/Globals';
import { arrayLength, pInt, pString, addObservablesTo, addComputablesTo, addSubscribablesTo } from 'Common/Utils';
import { arrayLength, pInt, pString } from 'Common/Utils';
import { addObservablesTo, addComputablesTo, addSubscribablesTo } from 'External/ko';
import {
getFolderInboxName,

View file

@ -1,6 +1,6 @@
import { SMAudio } from 'Common/Audio';
import * as Links from 'Common/Links';
import { addObservablesTo } from 'Common/Utils';
import { addObservablesTo } from 'External/ko';
import { fireEvent } from 'Common/Globals';
/**

View file

@ -5,7 +5,6 @@
import ko from 'ko';
import { arrayLength } from 'Common/Utils';
import { delegateRunOnDestroy } from 'Common/UtilsUser';
import Remote from 'Remote/User/Fetch';
@ -82,7 +81,6 @@ class OpenPgpKeyModel {
OpenPGPUserStore.publicKeys.remove(this);
storeOpenPgpKeys(OpenPGPUserStore.publicKeys, publicKeysItem);
}
delegateRunOnDestroy(this);
}
}
/*

View file

@ -2,7 +2,8 @@ import ko from 'ko';
import { koComputable } from 'External/ko';
import { Layout, EditorDefaultType } from 'Common/EnumsUser';
import { pInt, addObservablesTo } from 'Common/Utils';
import { pInt } from 'Common/Utils';
import { addObservablesTo } from 'External/ko';
import { $htmlCL, SettingsGet, fireEvent } from 'Common/Globals';
import { ThemeStore } from 'Stores/Theme';

View file

@ -1,9 +1,9 @@
import ko from 'ko';
import { koComputable } from 'External/ko';
import { koComputable, addSubscribablesTo } from 'External/ko';
import { SetSystemFoldersNotification } from 'Common/EnumsUser';
import { UNUSED_OPTION_VALUE } from 'Common/Consts';
import { defaultOptionsAfterRender, addSubscribablesTo } from 'Common/Utils';
import { defaultOptionsAfterRender } from 'Common/Utils';
import { folderListOptionsBuilder } from 'Common/UtilsUser';
import { initOnStartOrLangChange, i18n } from 'Common/Translator';

View file

@ -1,7 +1,7 @@
import ko from 'ko';
import { getNotification, i18nToNodes } from 'Common/Translator';
import { addObservablesTo } from 'Common/Utils';
import { addObservablesTo } from 'External/ko';
import { delegateRunOnDestroy } from 'Common/UtilsUser';
import Remote from 'Remote/User/Fetch';

View file

@ -4,7 +4,7 @@ import { Scope } from 'Common/Enums';
import { moveAction } from 'Common/Globals';
import { mailBox, settings } from 'Common/Links';
import { setFolderHash } from 'Common/Cache';
import { addComputablesTo } from 'Common/Utils';
import { addComputablesTo } from 'External/ko';
import { AppUserStore } from 'Stores/User/App';
import { SettingsUserStore } from 'Stores/User/Settings';

View file

@ -215,12 +215,15 @@ export class MailMessageView extends AbstractViewRight {
},
fullScreenMode: value => {
value && currentMessage() && AppUserStore.focusedState(Scope.MessageView);
if (this.oContent) {
value ? this.oContent.requestFullscreen() : exitFullscreen();
} else {
$htmlCL.toggle('rl-message-fullscreen', value);
}
}
},
showFullInfo: value => Local.set(ClientSideKeyName.MessageHeaderFullInfo, value ? '1' : '0')
});
this.lastReplyAction(Local.get(ClientSideKeyName.LastReplyAction) || ComposeType.Reply);
@ -274,11 +277,6 @@ export class MailMessageView extends AbstractViewRight {
}
onBuild(dom) {
this.fullScreenMode.subscribe(value =>
value && currentMessage() && AppUserStore.focusedState(Scope.MessageView));
this.showFullInfo.subscribe(value => Local.set(ClientSideKeyName.MessageHeaderFullInfo, value ? '1' : '0'));
const el = dom.querySelector('.b-content');
this.oContent = initFullscreen(el, () => this.fullScreenMode(getFullscreenElement() === el));
@ -334,7 +332,7 @@ export class MailMessageView extends AbstractViewRight {
}
});
AppUserStore.focusedState.subscribe((value) => {
AppUserStore.focusedState.subscribe(value => {
if (Scope.MessageView !== value) {
this.scrollMessageToTop();
this.scrollMessageToLeft();