From 6c0c2c5bf1f1ac80c6ca4e4fd4034473aaaff197 Mon Sep 17 00:00:00 2001 From: undefined Date: Wed, 5 May 2021 18:10:18 +0800 Subject: [PATCH] ui: editor auto-resize --- .../ui-default/components/editor/index.js | 50 ++++++++++++++----- packages/ui-default/package.json | 2 +- .../partials/discussion_edit_form.html | 3 +- .../ui-default/templates/problem_edit.html | 4 +- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/packages/ui-default/components/editor/index.js b/packages/ui-default/components/editor/index.js index 3ec3cc9aa..515dbf743 100644 --- a/packages/ui-default/components/editor/index.js +++ b/packages/ui-default/components/editor/index.js @@ -40,7 +40,6 @@ export default class Editor extends DOMAttachedObject { const hasFocus = $dom.is(':focus'); const origin = $dom.get(0); const ele = document.createElement('div'); - $(ele).height(550); $(ele).width('100%'); $(ele).addClass('textbox'); $dom.hide(); @@ -50,20 +49,25 @@ export default class Editor extends DOMAttachedObject { onChange, language = 'markdown', theme = UserContext.monacoTheme || 'vs-light', model = `file://model-${Math.random().toString(16)}`, + autoResize = $dom.hasClass('auto-resize'), } = this.options; this.model = typeof model === 'string' ? monaco.editor.createModel(value, language, monaco.Uri.parse(model)) : model; - this.editor = monaco.editor.create( - ele, - { - theme, - lineNumbers: true, - glyphMargin: true, - lightbulb: { - enabled: true, - }, - model: this.model, - } - ); + const cfg = { + theme, + lineNumbers: true, + glyphMargin: true, + lightbulb: { enabled: true }, + model: this.model, + automaticLayout: true, + }; + if (autoResize) { + cfg.scrollbar = { + vertical: 'hidden', + handleMouseWheel: false, + }; + cfg.scrollBeyondLastLine = false; + } + this.editor = monaco.editor.create(ele, cfg); this.editor.addAction({ id: 'theme-dark', label: 'Use dark theme', @@ -74,6 +78,26 @@ export default class Editor extends DOMAttachedObject { label: 'Use light theme', run: () => monaco.editor.setTheme('vs-light'), }); + + let prevHeight = 0; + const updateEditorHeight = () => { + const editorElement = this.editor.getDomNode(); + if (!editorElement) return; + const lineHeight = this.editor.getOption(monaco.editor.EditorOption.lineHeight); + const lineCount = this.editor.getModel()?.getLineCount() || 1; + const height = this.editor.getTopForLineNumber(lineCount + 1) + lineHeight; + if (prevHeight !== height) { + prevHeight = height; + editorElement.style.height = `${height}px`; + this.editor.layout(); + } + }; + + this.editor.onDidChangeModelDecorations(() => { + updateEditorHeight(); // typing + requestAnimationFrame(updateEditorHeight); // folding + }); + this._subscription = this.editor.onDidChangeModelContent(() => { const val = this.editor.getValue(); $dom.val(val); diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 68d188391..71874150a 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.6.32", + "version": "4.6.33", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/templates/partials/discussion_edit_form.html b/packages/ui-default/templates/partials/discussion_edit_form.html index 5ef1e4587..66be2623a 100644 --- a/packages/ui-default/templates/partials/discussion_edit_form.html +++ b/packages/ui-default/templates/partials/discussion_edit_form.html @@ -42,5 +42,6 @@ hotkeys:'ctrl+enter:submit', markdown:true, required:true, - extra_style:'height: 500px' + extra_style:'height: 500px', + extra_class:'auto-resize' }) }} diff --git a/packages/ui-default/templates/problem_edit.html b/packages/ui-default/templates/problem_edit.html index c93c38e1a..7d7599c1c 100644 --- a/packages/ui-default/templates/problem_edit.html +++ b/packages/ui-default/templates/problem_edit.html @@ -9,7 +9,7 @@
@@ -49,7 +49,7 @@
-
+