From 19cd11118cde7160cd447c81bc965007c0437479 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Tue, 16 Aug 2022 21:14:50 +0200 Subject: refactor(frondend): improve editor store and theme Also bumps frontend dependencies. --- subprojects/frontend/src/editor/PanelStore.ts | 90 +++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 subprojects/frontend/src/editor/PanelStore.ts (limited to 'subprojects/frontend/src/editor/PanelStore.ts') diff --git a/subprojects/frontend/src/editor/PanelStore.ts b/subprojects/frontend/src/editor/PanelStore.ts new file mode 100644 index 00000000..653d309c --- /dev/null +++ b/subprojects/frontend/src/editor/PanelStore.ts @@ -0,0 +1,90 @@ +import type { Command } from '@codemirror/view'; +import { action, makeObservable, observable } from 'mobx'; + +import getLogger from '../utils/getLogger'; + +import type EditorStore from './EditorStore'; + +const log = getLogger('editor.PanelStore'); + +export default class PanelStore { + state = false; + + constructor( + private readonly panelId: string, + private readonly openCommand: Command, + private readonly closeCommand: Command, + private readonly store: EditorStore, + ) { + makeObservable(this, { + state: observable, + open: action, + close: action, + toggle: action, + synchronizeStateToView: action, + }); + } + + open(): boolean { + return this.setState(true); + } + + close(): boolean { + return this.setState(false); + } + + toggle(): void { + this.setState(!this.state); + } + + private setState(newState: boolean): boolean { + if (this.state === newState) { + return false; + } + log.debug('Show', this.panelId, 'panel', newState); + if (newState) { + this.doOpen(); + } else { + this.doClose(); + } + this.state = newState; + return true; + } + + synchronizeStateToView(): void { + this.doClose(); + if (this.state) { + this.doOpen(); + } + } + + private doOpen(): void { + if (!this.store.doCommand(this.openCommand)) { + return; + } + const { view } = this.store; + if (view === undefined) { + return; + } + const buttonQuery = `.cm-${this.panelId}.cm-panel button[name="close"]`; + const closeButton = view.dom.querySelector(buttonQuery); + if (closeButton !== null) { + log.debug('Addig close button callback to', this.panelId, 'panel'); + // We must remove the event listener from the button that dispatches a transaction + // without going through `EditorStore`. This listened is added by CodeMirror, + // and we can only remove it by cloning the DOM node: https://stackoverflow.com/a/9251864 + const closeButtonWithoutListeners = closeButton.cloneNode(true); + closeButtonWithoutListeners.addEventListener('click', (event) => { + this.close(); + event.preventDefault(); + }); + closeButton.replaceWith(closeButtonWithoutListeners); + } else { + log.error('Opened', this.panelId, 'panel has no close button'); + } + } + + private doClose(): void { + this.store.doCommand(this.closeCommand); + } +} -- cgit v1.2.3-54-g00ecf