159 lines
No EOL
4.2 KiB
JavaScript
159 lines
No EOL
4.2 KiB
JavaScript
// src/nodes/NoteNode/NoteNode.tsx
|
|
import React, { useEffect, useRef } from "react";
|
|
import { useCreateBlockNote, useEditorChange } from "@blocknote/react";
|
|
import { BlockNoteView } from "@blocknote/shadcn";
|
|
import { en } from "@blocknote/core/locales";
|
|
|
|
// src/utils/debug.ts
|
|
import debugFactory from "debug";
|
|
var NAMESPACE = "canvas";
|
|
function createDebug(module) {
|
|
const base = debugFactory(`${NAMESPACE}:${module}`);
|
|
const warn = debugFactory(`${NAMESPACE}:${module}:warn`);
|
|
const error = debugFactory(`${NAMESPACE}:${module}:error`);
|
|
warn.enabled = true;
|
|
error.enabled = true;
|
|
warn.log = console.warn.bind(console);
|
|
error.log = console.error.bind(console);
|
|
const debugFn = Object.assign(base, {
|
|
warn,
|
|
error
|
|
});
|
|
return debugFn;
|
|
}
|
|
var debug = {
|
|
graph: {
|
|
node: createDebug("graph:node"),
|
|
edge: createDebug("graph:edge"),
|
|
sync: createDebug("graph:sync")
|
|
},
|
|
ui: {
|
|
selection: createDebug("ui:selection"),
|
|
drag: createDebug("ui:drag"),
|
|
resize: createDebug("ui:resize")
|
|
},
|
|
sync: {
|
|
status: createDebug("sync:status"),
|
|
mutations: createDebug("sync:mutations"),
|
|
queue: createDebug("sync:queue")
|
|
},
|
|
viewport: createDebug("viewport")
|
|
};
|
|
|
|
// src/nodes/NoteNode/NoteNode.tsx
|
|
import "@blocknote/core/fonts/inter.css";
|
|
import "@blocknote/shadcn/style.css";
|
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
var debug2 = createDebug("note-node");
|
|
function NoteNode({
|
|
nodeData,
|
|
storage,
|
|
theme = "light",
|
|
placeholder = "Start typing...",
|
|
isResizing
|
|
}) {
|
|
const isSyncingFromStorage = useRef(false);
|
|
const isSyncingToStorage = useRef(false);
|
|
const lastStorageContent = useRef("");
|
|
const editor = useCreateBlockNote({
|
|
initialContent: [{
|
|
id: crypto.randomUUID(),
|
|
type: "paragraph",
|
|
content: ""
|
|
}],
|
|
dictionary: {
|
|
...en,
|
|
placeholders: {
|
|
...en.placeholders,
|
|
emptyDocument: placeholder,
|
|
default: placeholder,
|
|
heading: "Enter a heading"
|
|
}
|
|
}
|
|
}, []);
|
|
useEditorChange(() => {
|
|
if (isSyncingFromStorage.current) {
|
|
return;
|
|
}
|
|
try {
|
|
isSyncingToStorage.current = true;
|
|
const html = editor.blocksToFullHTML(editor.document);
|
|
if (html !== lastStorageContent.current) {
|
|
lastStorageContent.current = html;
|
|
storage.onChange(html);
|
|
}
|
|
} catch (err) {
|
|
debug2.error("Failed to sync to storage: %O", err);
|
|
} finally {
|
|
isSyncingToStorage.current = false;
|
|
}
|
|
}, editor);
|
|
useEffect(() => {
|
|
if (!editor) return;
|
|
const handleStorageChange = (newContent) => {
|
|
if (isSyncingToStorage.current) {
|
|
return;
|
|
}
|
|
queueMicrotask(() => {
|
|
if (newContent === lastStorageContent.current) return;
|
|
lastStorageContent.current = newContent;
|
|
if (newContent && newContent.trim()) {
|
|
try {
|
|
isSyncingFromStorage.current = true;
|
|
const blocks = editor.tryParseHTMLToBlocks(newContent);
|
|
editor.replaceBlocks(editor.document, blocks);
|
|
} catch (err_0) {
|
|
debug2.error("Failed to parse HTML from storage: %O", err_0);
|
|
} finally {
|
|
isSyncingFromStorage.current = false;
|
|
}
|
|
}
|
|
});
|
|
};
|
|
const unsubscribe = storage.subscribe?.(handleStorageChange);
|
|
if (storage.content && storage.content !== lastStorageContent.current) {
|
|
handleStorageChange(storage.content);
|
|
}
|
|
return () => {
|
|
unsubscribe?.();
|
|
};
|
|
}, [editor, storage]);
|
|
if (storage.isLoading) {
|
|
return /* @__PURE__ */ _jsx("div", {
|
|
className: "note-node note-node--loading",
|
|
style: styles.loading,
|
|
children: "Loading..."
|
|
});
|
|
}
|
|
return /* @__PURE__ */ _jsx("div", {
|
|
className: "note-node",
|
|
style: styles.container,
|
|
"data-no-drag": "true",
|
|
onClick: (e) => {
|
|
e.stopPropagation();
|
|
},
|
|
children: /* @__PURE__ */ _jsx(BlockNoteView, {
|
|
editor,
|
|
theme
|
|
})
|
|
});
|
|
}
|
|
var styles = {
|
|
container: {
|
|
height: "100%",
|
|
width: "100%",
|
|
overflow: "auto",
|
|
touchAction: "auto"
|
|
},
|
|
loading: {
|
|
display: "flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
height: "100%",
|
|
color: "#666"
|
|
}
|
|
};
|
|
export {
|
|
NoteNode
|
|
};
|
|
//# sourceMappingURL=index.mjs.map
|