import { LitElement, html, nothing } from 'lit'; import { when } from 'lit/directives/when.js'; import { choose } from 'lit/directives/choose.js'; import { isEmptyObject } from './helpers.js'; import { settings } from './settings.js'; import { t } from './translate.js'; import { baseStyles, flexboxStyles, overlaysStyles, buttonInputStyles, iconStyles } from './styles.js'; export class BaseView extends LitElement { static properties = { isOffline: { state: true }, isUpdating: { state: true }, overlayState: { state: true }, settingsState: { state: true }, }; static styles = [ baseStyles, flexboxStyles, overlaysStyles, buttonInputStyles, iconStyles ]; constructor () { super(); this.isOffline = !navigator.onLine; this.isUpdating = false; this.settingsState = settings.getState(); this.overlayState = { type: 'plain', visible: false, content: null, }; } connectedCallback () { super.connectedCallback(); this.hideOverlay(); this._unsubscribeSettingsState = settings.subscribe(state => { this.settingsState = state; this.performUpdate(); }); window.addEventListener('online', this.connectionHandler); window.addEventListener('offline', this.connectionHandler); } disconnectedCallback () { super.disconnectedCallback(); if (typeof this._unsubscribeSettingsState === 'function') { this._unsubscribeSettingsState(); this._unsubscribeSettingsState = undefined; } window.removeEventListener('online', this.connectionHandler); window.removeEventListener('offline', this.connectionHandler); } updated (previous, viewName) { if (isDevServer) { const globalState = {}; if (previous.has('isUpdating')) globalState['isUpdating'] = this.isUpdating; if (previous.has('isOffline')) globalState['isOffline'] = this.isUpdating; if (!isEmptyObject(globalState)) console.info(`${viewName}(globalState):`, globalState); } if (isDevServer && previous.has('overlayState')) console.info(`${viewName}(overlayState):`, this.overlayState); if (isDevServer && previous.has('settingsState')) console.info(`${viewName}(settingsState):`, this.settingsState); } connectionHandler = event => { this.isOffline = event.type === 'offline'; }; showLoaderOverlay = () => this.showOverlay('loader'); showDialogOverlay = (title, body) => this.showOverlay('dialog', { title, body }); showAlertOverlay = (message, callback) => this.showOverlay('alert', { message, callback }); showSelectOverlay = items => this.showOverlay('select', items); hideOverlay = () => { this.overlayState = { type: 'plain', visible: false, content: null, }; }; showOverlay = (type, content) => { this.overlayState = { type, content, visible: true, } }; overlayHandler = event => event.target === event.currentTarget && ![ 'loader', 'alert' ].includes(this.overlayState.type) ? this.hideOverlay() : true; keyClickHandler = event => { if ([ 'Enter', 'Space' ].includes(event.code)) { event.preventDefault(); event.target.click(); } }; render = () => { let overlayContent; if (this.overlayState.visible) { overlayContent = choose(this.overlayState.type, [ [ 'plain', () => this.overlayState.content ], [ 'loader', () => html`
` ], [ 'dialog', () => html`