Add a new note type drawio

This commit is contained in:
Lowkey 2023-08-09 06:08:15 +00:00
parent 4240da349d
commit 8964e2ad67
8 changed files with 109 additions and 3 deletions

View File

@ -19,6 +19,7 @@ const NOTE_TYPE_ICONS = {
"noteMap": "bx bx-map-alt",
"mermaid": "bx bx-selection",
"canvas": "bx bx-pen",
"drawio": "bx bx-vector",
"webView": "bx bx-globe-alt",
"launcher": "bx bx-link",
"doc": "bx bxs-file-doc",

View File

@ -12,6 +12,7 @@ async function getNoteTypeItems(command) {
{ title: "Book", command: command, type: "book", uiIcon: "bx bx-book" },
{ title: "Mermaid Diagram", command: command, type: "mermaid", uiIcon: "bx bx-selection" },
{ title: "Canvas", command: command, type: "canvas", uiIcon: "bx bx-pen" },
{ title: "Drawio", command: command, type: "drawio", uiIcon: "bx bx-vector" },
{ title: "Web View", command: command, type: "webView", uiIcon: "bx bx-globe-alt" },
];

View File

@ -17,6 +17,7 @@ import ImageTypeWidget from "./type_widgets/image.js";
import RenderTypeWidget from "./type_widgets/render.js";
import RelationMapTypeWidget from "./type_widgets/relation_map.js";
import CanvasTypeWidget from "./type_widgets/canvas.js";
import DrawioTypeWidget from "./type_widgets/drawio.js"
import ProtectedSessionTypeWidget from "./type_widgets/protected_session.js";
import BookTypeWidget from "./type_widgets/book.js";
import ReadOnlyTextTypeWidget from "./type_widgets/read_only_text.js";
@ -56,6 +57,7 @@ const typeWidgetClasses = {
'render': RenderTypeWidget,
'relationMap': RelationMapTypeWidget,
'canvas': CanvasTypeWidget,
'drawio': DrawioTypeWidget,
'protectedSession': ProtectedSessionTypeWidget,
'book': BookTypeWidget,
'noteMap': NoteMapTypeWidget,
@ -142,7 +144,7 @@ export default class NoteDetailWidget extends NoteContextAwareWidget {
this.$widget.toggleClass("full-height",
(
!this.noteContext.hasNoteList()
&& ['editableText', 'editableCode', 'canvas', 'webView', 'noteMap'].includes(this.type)
&& ['editableText', 'editableCode', 'canvas', 'drawio', 'webView', 'noteMap'].includes(this.type)
&& this.mime !== 'text/x-sqlite;schema=trilium'
)
|| this.noteContext.viewScope.viewMode === 'attachments'

View File

@ -16,6 +16,7 @@ const NOTE_TYPES = [
{ type: "relationMap", mime: "application/json", title: "Relation Map", selectable: true },
{ type: "render", mime: '', title: "Render Note", selectable: true },
{ type: "canvas", mime: 'application/json', title: "Canvas", selectable: true },
{ type: "drawio", mime: 'application/xml', title: "Drawio", selectable: true },
{ type: "mermaid", mime: 'text/mermaid', title: "Mermaid Diagram", selectable: true },
{ type: "book", mime: '', title: "Book", selectable: true },
{ type: "webView", mime: '', title: "Web View", selectable: true },

View File

@ -43,7 +43,7 @@ export default class NoteWrapperWidget extends FlexContainer {
}
this.$widget.toggleClass("full-content-width",
['image', 'mermaid', 'book', 'render', 'canvas', 'webView'].includes(note.type)
['image', 'mermaid', 'book', 'render', 'canvas', 'drawio', 'webView'].includes(note.type)
|| !!note?.isLabelTruthy('fullContentWidth')
);

View File

@ -0,0 +1,100 @@
import TypeWidget from "./type_widget.js";
const TPL = `
<div class="drawio-widget note-detail full-height" style="overflow: hidden">
<style>
.note-detail-drawio {
width: 100%;
height: 100%;
border: 0;
}
</style>
<iframe class="note-detail-drawio" src="https://embed.diagrams.net/?embed=1&noExitBtn=1&proto=json&configure=1"></iframe>
</div>`;
export default class DrawioTypeWidget extends TypeWidget {
constructor() {
super();
this.lastApprovedOrigin = "https://embed.diagrams.net"; // allow domain
this.finishLoad = false; // determine whether the iframe is loaded
}
static getType() {
return "drawio";
}
doRender() {
this.$widget = $(TPL);
this.$noteDetailDrawio = this.$widget.find('.note-detail-drawio').get(0);
this.$noteDetailDrawio.onload = () => {
this.finishLoad = true
}
window.addEventListener('message', (e) => this.drawReceive(e));
super.doRender();
}
async doRefresh(note) {
const blob = await note.getBlob();
this.content = blob.content
if (this.finishLoad) {
this.drawEventInit()
}
}
drawReceive(event) {
if (!event.data || event.data.length < 1) return;
if (event.origin !== this.lastApprovedOrigin) return;
const message = JSON.parse(event.data);
switch (message.event) {
case 'init':
this.drawEventInit()
break;
case 'save':
case 'autosave':
this.drawEventSave(message.xml)
break;
case 'configure':
this.drawPostMessage({action: 'configure', config: {}});
break;
default:
break;
}
}
// send message
drawPostMessage (data) {
this.$noteDetailDrawio.contentWindow.postMessage(JSON.stringify(data), this.lastApprovedOrigin);
}
// init
drawEventInit() {
this.drawPostMessage({action: 'load', xml: this.content, autosave: 1});
}
// save content
drawEventSave(xml) {
this.drawContent = xml
this.saveData()
}
async getData() {
return {
content: this.drawContent || this.content
};
}
/**
* save content to backend
* spacedUpdate is kind of a debouncer.
*/
saveData() {
this.spacedUpdate.scheduleUpdate();
}
}

View File

@ -10,6 +10,7 @@ const noteTypes = [
{ type: 'noteMap', defaultMime: '' },
{ type: 'mermaid', defaultMime: 'text/plain' },
{ type: 'canvas', defaultMime: 'application/json' },
{ type: 'drawio', defaultMime: 'application/xml' },
{ type: 'webView', defaultMime: '' },
{ type: 'launcher', defaultMime: '' },
{ type: 'doc', defaultMime: '' },

View File

@ -155,7 +155,7 @@ const STRING_MIME_TYPES = [
function isStringNote(type, mime) {
// render and book are string note in the sense that they are expected to contain empty string
return ["text", "code", "relationMap", "search", "render", "book", "mermaid", "canvas"].includes(type)
return ["text", "code", "relationMap", "search", "render", "book", "mermaid", "canvas", "drawio"].includes(type)
|| mime.startsWith('text/')
|| STRING_MIME_TYPES.includes(mime);
}