From c0550fc97c96fb5e2f9246a66d9da83141ae8c1f Mon Sep 17 00:00:00 2001 From: undefined Date: Thu, 29 Sep 2022 17:02:51 +0800 Subject: [PATCH] ui: scratchpad: allow reuse existing models --- .../ui-default/components/monaco/loader.ts | 2 +- ...iner.jsx => ScratchpadEditorContainer.tsx} | 39 ++++++++++++------- packages/ui-default/package.json | 2 +- packages/ui-default/types.ts | 18 ++++++--- 4 files changed, 39 insertions(+), 22 deletions(-) rename packages/ui-default/components/scratchpad/{ScratchpadEditorContainer.jsx => ScratchpadEditorContainer.tsx} (75%) diff --git a/packages/ui-default/components/monaco/loader.ts b/packages/ui-default/components/monaco/loader.ts index 1cc7a0b5e..15161eaa1 100644 --- a/packages/ui-default/components/monaco/loader.ts +++ b/packages/ui-default/components/monaco/loader.ts @@ -66,7 +66,7 @@ export async function load(features = ['markdown']) { } await res.loadThemePromise; resolve(); - return { monaco: res.default, registerAction: res.registerAction }; + return { monaco: res.default, registerAction: res.registerAction, customOptions: {} }; } export default load; diff --git a/packages/ui-default/components/scratchpad/ScratchpadEditorContainer.jsx b/packages/ui-default/components/scratchpad/ScratchpadEditorContainer.tsx similarity index 75% rename from packages/ui-default/components/scratchpad/ScratchpadEditorContainer.jsx rename to packages/ui-default/components/scratchpad/ScratchpadEditorContainer.tsx index ebf27871c..c7632ad9f 100644 --- a/packages/ui-default/components/scratchpad/ScratchpadEditorContainer.jsx +++ b/packages/ui-default/components/scratchpad/ScratchpadEditorContainer.tsx @@ -1,25 +1,36 @@ +import type * as monaco from 'monaco-editor'; import React from 'react'; import { connect } from 'react-redux'; import { load } from 'vj/components/monaco/loader'; -const mapStateToProps = (state) => ({ +interface ScratchpadOptions { + value?: string; + language?: string; + handleUpdateCode?: (str: string, event: monaco.editor.IModelContentChangedEvent) => void; + mainSize?: number; + recordSize?: number; + pretestSize?: number; +} + +export default connect((state: any) => ({ value: state.editor.code, language: window.LANGS[state.editor.lang]?.monaco, mainSize: state.ui.main.size, pretestSize: state.ui.pretest.size, recordSize: state.ui.records.size, -}); -const mapDispatchToProps = (dispatch) => ({ - handleUpdateCode: (code) => { +}), (dispatch) => ({ + handleUpdateCode: (code: string) => { dispatch({ type: 'SCRATCHPAD_EDITOR_UPDATE_CODE', payload: code, }); }, -}); - -export default connect(mapStateToProps, mapDispatchToProps)(class MonacoEditor extends React.PureComponent { +}))(class MonacoEditor extends React.PureComponent { disposable = []; + __prevent_trigger_change_event = false; + model: monaco.editor.ITextModel; + editor: monaco.editor.IStandaloneCodeEditor; + containerElement: HTMLElement; async componentDidMount() { const value = this.props.value || ''; @@ -28,12 +39,11 @@ export default connect(mapStateToProps, mapDispatchToProps)(class MonacoEditor e const uri = monaco.Uri.parse(`hydro://${UiContext.pdoc.pid || UiContext.pdoc.docId}.${language}`); this.model = monaco.editor.createModel(value, language, uri); if (this.containerElement) { - /** @type {monaco.editor.IStandaloneEditorConstructionOptions} */ - const config = { + const config: monaco.editor.IStandaloneEditorConstructionOptions = { theme: 'vs-light', ...customOptions, fontFamily: UserContext.codeFontFamily, - lineNumbers: true, + lineNumbers: 'on', glyphMargin: true, lightbulb: { enabled: true }, model: this.model, @@ -43,12 +53,12 @@ export default connect(mapStateToProps, mapDispatchToProps)(class MonacoEditor e this.disposable.push( this.editor.onDidChangeModelContent((event) => { if (!this.__prevent_trigger_change_event) { - this.props.handleUpdateCode(this.editor.getValue({ lineEnding: '\n', preserveBOM: false }), event); + this.props.handleUpdateCode?.(this.editor.getValue({ lineEnding: '\n', preserveBOM: false }), event); } }), ); - window.editor = this.editor; - window.monaco = monaco; + (window as any).editor = this.editor; + (window as any).monaco = monaco; window.Hydro.bus.emit('scratchpadEditorCreate', this.editor, monaco); } } @@ -71,6 +81,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(class MonacoEditor e text: value, }, ], + () => null, ); editor.pushUndoStop(); this.__prevent_trigger_change_event = false; @@ -79,7 +90,7 @@ export default connect(mapStateToProps, mapDispatchToProps)(class MonacoEditor e const val = model.getValue(LF, false); model.dispose(); const uri = monaco.Uri.parse(`hydro://${UiContext.pdoc.pid || UiContext.pdoc.docId}.${language}`); - this.model = monaco.editor.createModel(val, language, uri); + this.model = monaco.editor.getModel(uri) || monaco.editor.createModel(val, language, uri); editor.setModel(this.model); } if (editor) { diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 8a67d88cc..6800c215a 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.40.9", + "version": "4.40.10", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/types.ts b/packages/ui-default/types.ts index 207c28c12..b1b674758 100644 --- a/packages/ui-default/types.ts +++ b/packages/ui-default/types.ts @@ -1,6 +1,12 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -declare let UserContext: any; -declare let UiContext: any; -// eslint-disable-next-line -declare let node_modules: any; -declare let LANGS: Record; +declare global { + interface Window { + node_modules: any; + LANGS: Record; + + } + + let UserContext: Record; + let UiContext: Record; +} + +export { };