ui: monaco: better auto-resize

This commit is contained in:
undefined committed 2022-01-19 20:27:55 +08:00
1 parent 6419215d91
commit 6b5b3e68d0
4 files changed
+62 -16

No files matched your search

@@ -24,12 +24,29 @@ export const config = {
},
};
interface MonacoOptions {
language?: string;
onChange?: (val: string) => any;
theme?: string;
model?: string;
autoResize?: boolean;
autoLayout?: boolean;
value?: string;
}
interface VditorOptions {
theme?: 'classic' | 'dark'
}
type Options = MonacoOptions & VditorOptions;
export default class Editor extends DOMAttachedObject {
static DOMAttachKey = 'vjEditorInstance';
model: import('../monaco').default.editor.IModel;
editor: import('../monaco').default.editor.IStandaloneCodeEditor;
vditor: import('vditor').default;
isValid: boolean;
constructor($dom, options = {}) {
constructor($dom, public options: Options = {}) {
super($dom);
this.options = options;
if (UserContext.preferredEditorType === 'monaco') this.initMonaco();
else if (options.language && options.language !== 'markdown') this.initMonaco();
else this.initVditor();
@@ -59,10 +76,9 @@ export default class Editor extends DOMAttachedObject {
|| monaco.editor.createModel(value, language, monaco.Uri.parse(model))
: model;
this.model.setValue(value);
this.model.updateOptions({ language });
const cfg = {
const cfg: import('../monaco').default.editor.IStandaloneEditorConstructionOptions = {
theme,
lineNumbers: true,
lineNumbers: 'on',
glyphMargin: true,
lightbulb: { enabled: true },
model: this.model,
@@ -79,19 +95,31 @@ export default class Editor extends DOMAttachedObject {
const lineHeight = this.editor.getOption(monaco.editor.EditorOption.lineHeight);
const lineCount = this.editor.getModel()?.getLineCount() || 1;
let height = this.editor.getTopForLineNumber(lineCount + 1) + lineHeight;
if (window.innerHeight < height) height = window.innerHeight;
if (prevHeight !== height) {
if (window.innerHeight * 1.5 < height) {
height = window.innerHeight;
this.editor.updateOptions({
scrollbar: {
vertical: 'auto',
horizontal: 'auto',
handleMouseWheel: true,
},
});
} else {
this.editor.updateOptions({
scrollbar: {
vertical: 'hidden',
horizontal: 'hidden',
handleMouseWheel: false,
},
});
}
prevHeight = height;
editorElement.style.height = `${height}px`;
this.editor.layout();
}
};
if (autoResize) {
cfg.scrollbar = {
vertical: 'hidden',
horizontal: 'hidden',
handleMouseWheel: false,
};
cfg.wordWrap = 'bounded';
cfg.scrollBeyondLastLine = false;
}
@@ -103,7 +131,7 @@ export default class Editor extends DOMAttachedObject {
requestAnimationFrame(updateEditorHeight); // folding
});
}
this._subscription = this.editor.onDidChangeModelContent(() => {
this.editor.onDidChangeModelContent(() => {
const val = this.editor.getValue();
$dom.val(val);
$dom.text(val);
@@ -112,7 +140,9 @@ export default class Editor extends DOMAttachedObject {
this.isValid = true;
if (hasFocus) this.focus();
if (autoResize) updateEditorHeight();
// @ts-ignore
window.model = this.model;
// @ts-ignore
window.editor = this.editor;
}
@@ -125,10 +155,10 @@ export default class Editor extends DOMAttachedObject {
const value = $dom.val();
const { onChange } = this.options;
await new Promise((resolve) => {
this.editor = new Vditor(ele, {
this.vditor = new Vditor(ele, {
...config,
...this.options,
after: resolve,
after: () => resolve(null),
input(v) {
$dom.val(v);
$dom.text(v);
@@ -147,7 +177,7 @@ export default class Editor extends DOMAttachedObject {
destory() {
this.detach();
if (this.editor?.destory) this.editor.destory();
if (this.vditor?.destroy) this.vditor.destroy();
else if (this.editor?.dispose) this.editor.dispose();
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@hydrooj/ui-default",
"version": "4.30.1",
"version": "4.30.2",
"author": "undefined <i@undefined.moe>",
"license": "AGPL-3.0",
"main": "hydro.js",
@@ -50,9 +50,11 @@ const page = new NamedPage('domain_group', () => {
createGroupDialogContent.find('[name="create_group_users"]'),
{ multi: true, height: 'auto' },
);
const targets = {};
$('input[data-gid]').get().forEach((ele) => {
const input = UserSelectAutoComplete.getOrConstruct<UserSelectAutoComplete<true>>($(ele), { multi: true, height: 'auto' });
const gid = ele.getAttribute('data-gid');
targets[gid] = input;
let loaded = false;
input.onChange(() => {
if (input.value().length && !loaded) {
@@ -123,8 +125,21 @@ const page = new NamedPage('domain_group', () => {
}
}
async function handleClickSaveAll() {
for (const gid of Object.keys(targets)) {
const uids = targets[gid].value();
try {
await update(gid, uids);
} catch (error) {
Notification.error(error.message);
}
}
Notification.success(i18n('Saved.'));
}
$('[name="create_group"]').click(() => handleClickCreateGroup());
$('[name="delete_selected"]').click(() => handleClickDeleteSelected());
$('[name="save_all"]').on('click', () => handleClickSaveAll());
});
export default page;
@@ -43,6 +43,7 @@
</div>
<div class="section__body">
<button class="rounded button" name="remove_selected">{{ _('Remove Selected Group') }}</button>
<button class="rounded button" name="save_all">{{ _('Save All Changes') }}</button>
</div>
</div>
{% endblock %}