import ko from 'ko'; import { addObservablesTo, addComputablesTo, addSubscribablesTo } from 'External/ko'; import { keyScope, addShortcut, SettingsGet, toggleLeftPanel, elementById } from 'Common/Globals'; import { ViewTypePopup, showScreenPopup } from 'Knoin/Knoin'; import { SaveSettingStatus } from 'Common/Enums'; class AbstractView { constructor(templateID, type) { // Object.defineProperty(this, 'viewModelTemplateID', { value: templateID }); this.viewModelTemplateID = templateID || this.constructor.name.replace('UserView', ''); this.viewType = type; this.viewModelDom = null; this.keyScope = { scope: 'none', previous: 'none', set: function() { this.previous = keyScope(); keyScope(this.scope); }, unset: function() { keyScope(this.previous); } }; } /* onBuild() {} beforeShow() {} // Happens before: hidden = false 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) { super('Popups' + name, ViewTypePopup); this.keyScope.scope = name; this.modalVisible = ko.observable(false).extend({ rateLimit: 0 }); this.close = () => this.modalVisible(false); this.tryToClose = () => (false === this.onClose()) || this.close(); addShortcut('escape,close', '', name, () => { this.modalVisible() && this.tryToClose(); return false; // return true; Issue with supported modal close }); } // Happens when user hits Escape or Close key // return false to prevent closing onClose() {} /* beforeShow() {} // Happens before showModal() 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() { return !this.__vm || !this.__vm.modalVisible(); } export class AbstractViewLeft extends AbstractView { constructor(templateID) { super(templateID, 'left'); this.toggleLeftPanel = toggleLeftPanel; } } export class AbstractViewRight extends AbstractView { constructor(templateID) { super(templateID, 'right'); } } export class AbstractViewSettings { /* onBuild(viewModelDom) {} beforeShow() {} onShow() {} onHide() {} viewModelDom */ /** * 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 */ addSetting(name, valueCb) { let prop = name[0].toLowerCase() + name.slice(1), trigger = prop + 'Trigger'; addObservablesTo(this, { [prop]: SettingsGet(name), [trigger]: SaveSettingStatus.Idle, }); addSubscribablesTo(this, { [prop]: (value => { this[trigger](SaveSettingStatus.Saving); valueCb?.(value); rl.app.Remote.saveSetting(name, value, iError => { this[trigger](iError ? SaveSettingStatus.Failed : SaveSettingStatus.Success); // iError || Settings.set(name, value); setTimeout(() => this[trigger](SaveSettingStatus.Idle), 1000); } ); }).debounce(999), }); } /** * Foreach name if this[name] does not exists, create as observable with value of SettingsGet(name) * Subscribe to this[name], for saving the setting */ 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)); }); } } export class AbstractViewLogin extends AbstractView { constructor(templateID) { super(templateID, 'content'); this.formError = ko.observable(false).extend({ falseTimeout: 500 }); } onBuild(dom) { dom.classList.add('LoginView'); } onShow() { elementById('rl-left').hidden = true; elementById('rl-right').hidden = true; rl.route.off(); } onHide() { elementById('rl-left').hidden = false; elementById('rl-right').hidden = false; } submitForm() { // return false; } }