snappymail/dev/Knoin/AbstractViews.js

185 lines
4.4 KiB
JavaScript
Raw Permalink Normal View History

import ko from 'ko';
2022-02-17 16:36:29 +08:00
import { addObservablesTo, addComputablesTo, addSubscribablesTo } from 'External/ko';
import { keyScope, addShortcut, SettingsGet, toggleLeftPanel, elementById } from 'Common/Globals';
2022-03-08 19:28:16 +08:00
import { ViewTypePopup, showScreenPopup } from 'Knoin/Knoin';
import { SaveSettingStatus } from 'Common/Enums';
2022-02-28 17:38:47 +08:00
class AbstractView {
constructor(templateID, type)
{
// Object.defineProperty(this, 'viewModelTemplateID', { value: templateID });
2022-03-08 19:28:16 +08:00
this.viewModelTemplateID = templateID || this.constructor.name.replace('UserView', '');
this.viewType = type;
this.viewModelDom = null;
this.keyScope = {
2022-03-07 20:47:03 +08:00
scope: 'none',
previous: 'none',
set: function() {
this.previous = keyScope();
keyScope(this.scope);
},
unset: function() {
keyScope(this.previous);
}
};
}
/*
onBuild() {}
beforeShow() {} // Happens before: hidden = false
2022-02-25 19:11:32 +08:00
onShow() {} // Happens after: hidden = false
onHide() {}
*/
querySelector(selectors) {
return this.viewModelDom.querySelector(selectors);
}
addObservables(observables) {
addObservablesTo(this, observables);
}
addComputables(computables) {
addComputablesTo(this, computables);
}
addSubscribables(subscribables) {
addSubscribablesTo(this, subscribables);
}
}
export class AbstractViewPopup extends AbstractView
{
constructor(name)
{
2022-03-08 19:28:16 +08:00
super('Popups' + name, ViewTypePopup);
this.keyScope.scope = name;
2022-02-26 08:06:18 +08:00
this.modalVisible = ko.observable(false).extend({ rateLimit: 0 });
2023-02-15 02:04:14 +08:00
this.close = () => this.modalVisible(false);
2024-08-07 03:41:52 +08:00
this.tryToClose = () => (false === this.onClose()) || this.close();
2022-11-05 19:07:26 +08:00
addShortcut('escape,close', '', name, () => {
2024-08-07 03:41:52 +08:00
this.modalVisible() && this.tryToClose();
return false;
// return true; Issue with supported modal close
});
}
2022-02-25 20:13:09 +08:00
// Happens when user hits Escape or Close key
2022-02-26 17:33:11 +08:00
// return false to prevent closing
onClose() {}
/*
beforeShow() {} // Happens before showModal()
2022-04-05 17:06:22 +08:00
onShow() {} // Happens after showModal()
afterShow() {} // Happens after showModal() animation transitionend
onHide() {} // Happens before animation transitionend
afterHide() {} // Happens after animation transitionend
*/
}
AbstractViewPopup.showModal = function(params = []) {
showScreenPopup(this, params);
}
AbstractViewPopup.hidden = function() {
2022-02-26 08:06:18 +08:00
return !this.__vm || !this.__vm.modalVisible();
}
export class AbstractViewLeft extends AbstractView
{
constructor(templateID)
{
2022-10-10 19:52:56 +08:00
super(templateID, 'left');
this.toggleLeftPanel = toggleLeftPanel;
}
}
export class AbstractViewRight extends AbstractView
{
constructor(templateID)
{
2022-10-10 19:52:56 +08:00
super(templateID, 'right');
}
}
export class AbstractViewSettings
{
2022-02-28 17:38:47 +08:00
/*
onBuild(viewModelDom) {}
beforeShow() {}
onShow() {}
onHide() {}
viewModelDom
*/
2024-03-26 19:26:35 +08:00
/**
* When this[name] does not exists, create as observable with value of SettingsGet(name)
* When this[name+'Trigger'] does not exists, create as observable
* Subscribe to this[name], and handle saving the setting
*/
2022-02-28 17:38:47 +08:00
addSetting(name, valueCb)
{
2022-02-28 23:10:23 +08:00
let prop = name[0].toLowerCase() + name.slice(1),
2022-02-28 17:38:47 +08:00
trigger = prop + 'Trigger';
addObservablesTo(this, {
[prop]: SettingsGet(name),
[trigger]: SaveSettingStatus.Idle,
2022-02-28 17:38:47 +08:00
});
addSubscribablesTo(this, {
[prop]: (value => {
this[trigger](SaveSettingStatus.Saving);
2022-09-02 17:52:07 +08:00
valueCb?.(value);
2022-02-28 17:38:47 +08:00
rl.app.Remote.saveSetting(name, value,
iError => {
this[trigger](iError ? SaveSettingStatus.Failed : SaveSettingStatus.Success);
2024-03-26 19:26:35 +08:00
// iError || Settings.set(name, value);
setTimeout(() => this[trigger](SaveSettingStatus.Idle), 1000);
2022-02-28 17:38:47 +08:00
}
);
}).debounce(999),
});
}
2022-03-01 17:18:12 +08:00
2024-03-26 19:26:35 +08:00
/**
* Foreach name if this[name] does not exists, create as observable with value of SettingsGet(name)
* Subscribe to this[name], for saving the setting
*/
2022-03-01 17:18:12 +08:00
addSettings(names)
{
names.forEach(name => {
let prop = name[0].toLowerCase() + name.slice(1);
this[prop] || (this[prop] = ko.observable(SettingsGet(name)));
this[prop].subscribe(value => rl.app.Remote.saveSetting(name, value));
});
}
2022-02-28 17:38:47 +08:00
}
2022-03-08 19:28:16 +08:00
export class AbstractViewLogin extends AbstractView {
constructor(templateID) {
2022-10-10 19:52:56 +08:00
super(templateID, 'content');
this.formError = ko.observable(false).extend({ falseTimeout: 500 });
}
onBuild(dom) {
dom.classList.add('LoginView');
}
onShow() {
2022-05-20 03:16:00 +08:00
elementById('rl-left').hidden = true;
elementById('rl-right').hidden = true;
rl.route.off();
}
2022-05-20 03:16:00 +08:00
onHide() {
elementById('rl-left').hidden = false;
elementById('rl-right').hidden = false;
}
submitForm() {
// return false;
}
}