import {Component, ElementRef, HostListener, Input, OnInit, ViewChild} from '@angular/core'; import {EditorNodeContract} from '../EditorNode.contract'; import {EditorService} from '../../../service/editor.service'; import {v4} from 'uuid'; import {EditorComponent} from 'ngx-monaco-editor'; @Component({ selector: 'editor-markdown', templateUrl: './markdown.component.html', styleUrls: ['./markdown.component.scss'], }) export class MarkdownComponent extends EditorNodeContract implements OnInit { // @ViewChild('editable') editable; @Input() nodeId: string; @Input() editorUUID?: string; @ViewChild('editor') editor: EditorComponent; @ViewChild('editorContainer') editorContainer: ElementRef; // public isFocused = false; public initialValue = 'Double-click to edit...'; protected savedValue = 'Double-click to edit...'; public contents = ''; private dirtyOverride = false; public showEditor = false; protected hadOneFocusOut = false; public singleColumn = false; public containerHeight = 540; public editorOptions = { theme: this.isDark() ? 'vs-dark' : 'vs', language: 'markdown', uri: v4(), readOnly: false, automaticLayout: true, wordWrap: 'on', scrollBeyondLastLine: false, scrollbar: { alwaysConsumeMouseWheel: false, }, }; constructor( public editorService: EditorService, ) { super(); this.contents = this.initialValue; this.savedValue = this.initialValue; } public isDark() { return document.body.classList.contains('dark'); } ngOnInit() { this.editorService = this.editorService.getEditor(this.editorUUID); this.editorService.registerNodeEditor(this.nodeId, this).then(() => { if ( !this.node.Value ) { this.node.Value = {}; } if ( this.node.Value.Value ) { this.initialValue = this.node.Value.Value; this.savedValue = this.node.Value.Value; } this.contents = this.initialValue; }); } onMonacoEditorInit(editor) { let ignoreEvent = false; const updateHeight = () => { const contentHeight = Math.max(540, editor.getContentHeight()); this.containerHeight = contentHeight; try { ignoreEvent = true; editor.layout({ width: this.editorContainer.nativeElement.offsetWidth, height: contentHeight }); } finally { ignoreEvent = false; } }; editor.onDidContentSizeChange(updateHeight); updateHeight(); } public isDirty(): boolean | Promise { return this.dirtyOverride || this.contents !== this.savedValue; } public writeChangesToNode(): void | Promise { this.node.Value.Mode = 'markdown'; this.node.Value.Value = this.contents; this.node.value = this.contents; this.savedValue = this.contents; } onContentsChanged(event) { if ( event !== this.savedValue ) { this.editorService.triggerSave(); } } onFocusIn() { this.showEditor = this.editorService.canEdit(); } @HostListener('document:keyup.escape', ['$event']) onFocusOut(event) { if ( !this.hadOneFocusOut ) { this.hadOneFocusOut = true; setTimeout(() => { this.hadOneFocusOut = false; }, 500); } else { this.hadOneFocusOut = false; this.showEditor = false; } } onEditorHostResize($event) { if ( $event.newWidth < 700 && !this.singleColumn ) { this.singleColumn = true; } else if ( $event.newWidth > 700 && this.singleColumn ) { this.singleColumn = false; } } }