diff --git a/package-lock.json b/package-lock.json index cfd52a3c5..fa416711f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "dependencies": { "@braintree/sanitize-url": "6.0.4", "@electron/remote": "2.1.0", - "@excalidraw/excalidraw": "0.16.1", + "@excalidraw/excalidraw": "0.17.3", "archiver": "6.0.1", "async-mutex": "0.4.0", "axios": "1.6.2", @@ -485,9 +485,9 @@ } }, "node_modules/@excalidraw/excalidraw": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@excalidraw/excalidraw/-/excalidraw-0.16.1.tgz", - "integrity": "sha512-4zirHk7dNx6SVq2jQmYOLliqAa1h3WPVqHM5qtJyhD769VsOqwlkopAcnZMb3G1PeIMm6cf2F31quS5MVqvoOQ==", + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@excalidraw/excalidraw/-/excalidraw-0.17.3.tgz", + "integrity": "sha512-t+0sR30AboKcINt0WUJmSAC1cJy6npO37j/zONvuWvSh6XDOGoL1E0L+WYKJMBzp4wnOQhRIghQJmdfktQlO8w==", "peerDependencies": { "react": "^17.0.2 || ^18.2.0", "react-dom": "^17.0.2 || ^18.2.0" diff --git a/package.json b/package.json index 74c65ad65..3a370b947 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "dependencies": { "@braintree/sanitize-url": "6.0.4", "@electron/remote": "2.1.0", - "@excalidraw/excalidraw": "0.16.1", + "@excalidraw/excalidraw": "0.17.3", "archiver": "6.0.1", "async-mutex": "0.4.0", "axios": "1.6.2", diff --git a/src/public/app/widgets/type_widgets/canvas.js b/src/public/app/widgets/type_widgets/canvas.js index 628b6116a..08f7128e3 100644 --- a/src/public/app/widgets/type_widgets/canvas.js +++ b/src/public/app/widgets/type_widgets/canvas.js @@ -1,10 +1,7 @@ -import libraryLoader from "../../services/library_loader.js"; -import TypeWidget from "./type_widget.js"; +import libraryLoader from '../../services/library_loader.js'; +import TypeWidget from './type_widget.js'; import utils from '../../services/utils.js'; import linkService from '../../services/link.js'; -import debounce from "../../services/debounce.js"; - -const {sleep} = utils; const TPL = `
@@ -105,8 +102,6 @@ export default class ExcalidrawTypeWidget extends TypeWidget { this.SCENE_VERSION_INITIAL = -1; // -1 indicates that it is fresh. excalidraw scene version is always >0 this.SCENE_VERSION_ERROR = -2; // -2 indicates error - // config - this.DEBOUNCE_TIME_ONCHANGEHANDLER = 750; // ms // ensure that assets are loaded from trilium window.EXCALIDRAW_ASSET_PATH = `${window.location.origin}/node_modules/@excalidraw/excalidraw/dist/`; @@ -115,16 +110,10 @@ export default class ExcalidrawTypeWidget extends TypeWidget { this.currentSceneVersion = this.SCENE_VERSION_INITIAL; // will be overwritten - this.excalidrawRef; this.$render; this.$widget; this.reactHandlers; // used to control react state - // binds - this.createExcalidrawReactApp = this.createExcalidrawReactApp.bind(this); - this.onChangeHandler = this.onChangeHandler.bind(this); - this.isNewSceneVersion = this.isNewSceneVersion.bind(this); - this.libraryChanged = false; } @@ -155,7 +144,8 @@ export default class ExcalidrawTypeWidget extends TypeWidget { const renderElement = this.$render.get(0); ReactDOM.unmountComponentAtNode(renderElement); - ReactDOM.render(React.createElement(this.createExcalidrawReactApp), renderElement); + const root = ReactDOM.createRoot(renderElement); + root.render(React.createElement(() => this.createExcalidrawReactApp())); }); return this.$widget; @@ -179,9 +169,9 @@ export default class ExcalidrawTypeWidget extends TypeWidget { const blob = await note.getBlob(); // before we load content into excalidraw, make sure excalidraw has loaded - while (!this.excalidrawRef?.current) { - console.log("excalidrawRef not yet loaded, sleep 200ms..."); - await sleep(200); + while (!this.excalidrawApi) { + console.log("excalidrawApi not yet loaded, sleep 200ms..."); + await utils.sleep(200); } /** @@ -199,7 +189,7 @@ export default class ExcalidrawTypeWidget extends TypeWidget { collaborators: [] }; - this.excalidrawRef.current.updateScene(sceneData); + this.excalidrawApi.updateScene(sceneData); } else if (blob.content) { // load saved content into excalidraw canvas @@ -246,9 +236,9 @@ export default class ExcalidrawTypeWidget extends TypeWidget { fileArray.push(file); } - this.excalidrawRef.current.updateScene(sceneData); - this.excalidrawRef.current.addFiles(fileArray); - this.excalidrawRef.current.history.clear(); + this.excalidrawApi.updateScene(sceneData); + this.excalidrawApi.addFiles(fileArray); + this.excalidrawApi.history.clear(); } Promise.all( @@ -261,7 +251,7 @@ export default class ExcalidrawTypeWidget extends TypeWidget { } const libraryItems = blobs.map(blob => blob.getJsonContentSafely()).filter(item => !!item); - this.excalidrawRef.current.updateLibrary({libraryItems, merge: false}); + this.excalidrawApi.updateLibrary({libraryItems, merge: false}); }); // set initial scene version @@ -275,17 +265,17 @@ export default class ExcalidrawTypeWidget extends TypeWidget { * this is automatically called after this.saveData(); */ async getData() { - const elements = this.excalidrawRef.current.getSceneElements(); - const appState = this.excalidrawRef.current.getAppState(); + const elements = this.excalidrawApi.getSceneElements(); + const appState = this.excalidrawApi.getAppState(); /** * A file is not deleted, even though removed from canvas. Therefore, we only keep * files that are referenced by an element. Maybe this will change with a new excalidraw version? */ - const files = this.excalidrawRef.current.getFiles(); + const files = this.excalidrawApi.getFiles(); // parallel svg export to combat bitrot and enable rendering image for note inclusion, preview, and share - const svg = await window.ExcalidrawLib.exportToSvg({ + const svg = await ExcalidrawLib.exportToSvg({ elements, appState, exportPadding: 5, // 5 px padding @@ -321,7 +311,7 @@ export default class ExcalidrawTypeWidget extends TypeWidget { // this.libraryChanged is unset in dataSaved() // there's no separate method to get library items, so have to abuse this one - const libraryItems = await this.excalidrawRef.current.updateLibrary({merge: true}); + const libraryItems = await this.excalidrawApi.updateLibrary({merge: true}); let position = 10; @@ -379,9 +369,6 @@ export default class ExcalidrawTypeWidget extends TypeWidget { createExcalidrawReactApp() { const React = window.React; const { Excalidraw } = window.ExcalidrawLib; - - const excalidrawRef = React.useRef(null); - this.excalidrawRef = excalidrawRef; const excalidrawWrapperRef = React.useRef(null); this.excalidrawWrapperRef = excalidrawWrapperRef; const [dimensions, setDimensions] = React.useState({ @@ -439,7 +426,7 @@ export default class ExcalidrawTypeWidget extends TypeWidget { React.createElement(Excalidraw, { // this makes sure that 1) manual theme switch button is hidden 2) theme stays as it should after opening menu theme: this.themeStyle, - ref: excalidrawRef, + excalidrawAPI: api => { this.excalidrawApi = api; }, width: dimensions.width, height: dimensions.height, onPaste: (data, event) => { @@ -450,7 +437,7 @@ export default class ExcalidrawTypeWidget extends TypeWidget { this.saveData(); }, - onChange: debounce(this.onChangeHandler, this.DEBOUNCE_TIME_ONCHANGEHANDLER), + onChange: () => this.onChangeHandler(), viewModeEnabled: false, zenModeEnabled: false, gridModeEnabled: false, @@ -483,8 +470,8 @@ export default class ExcalidrawTypeWidget extends TypeWidget { } getSceneVersion() { - if (this.excalidrawRef) { - const elements = this.excalidrawRef.current.getSceneElements(); + if (this.excalidrawApi) { + const elements = this.excalidrawApi.getSceneElements(); return window.ExcalidrawLib.getSceneVersion(elements); } else { return this.SCENE_VERSION_ERROR;