From 8ab9ffbe28a2c63f66120a833f664a5d7b3b24a1 Mon Sep 17 00:00:00 2001 From: Pete Hunt Date: Thu, 1 Oct 2020 10:12:43 -0700 Subject: [PATCH] One-click installable libraries (#2179) Co-authored-by: dwelle --- src/components/App.tsx | 32 ++++++++++++++++++++++++++++++++ src/data/json.ts | 9 +++++++++ src/locales/en.json | 4 +++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index 784c391e..b388aa8b 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -175,6 +175,7 @@ import { } from "../element/binding"; import { MaybeTransformHandleType } from "../element/transformHandles"; import { renderSpreadsheet } from "../charts"; +import { isValidLibrary } from "../data/json"; /** * @param func handler taking at most single parameter (event). @@ -492,6 +493,31 @@ class App extends React.Component { return false; } + private addToLibrary = async (url: string) => { + window.history.replaceState({}, "Excalidraw", window.location.origin); + try { + const request = await fetch(url); + const blob = await request.blob(); + const json = JSON.parse(await blob.text()); + if (!isValidLibrary(json)) { + throw new Error(); + } + if ( + window.confirm( + t("alerts.confirmAddLibrary", { numShapes: json.library.length }), + ) + ) { + await Library.importLibrary(blob); + this.setState({ + isLibraryOpen: true, + }); + } + } catch (error) { + window.alert(t("alerts.errorLoadingLibrary")); + console.error(error); + } + }; + private initializeScene = async () => { if ("launchQueue" in window && "LaunchParams" in window) { (window as any).launchQueue.setConsumer( @@ -590,6 +616,12 @@ class App extends React.Component { commitToHistory: true, }); } + + const addToLibraryUrl = searchParams.get("addLibrary"); + + if (addToLibraryUrl) { + await this.addToLibrary(addToLibraryUrl); + } }; public async componentDidMount() { diff --git a/src/data/json.ts b/src/data/json.ts index f64131fd..7f56c0d3 100644 --- a/src/data/json.ts +++ b/src/data/json.ts @@ -54,6 +54,15 @@ export const loadFromJSON = async (appState: AppState) => { return loadFromBlob(blob, appState); }; +export const isValidLibrary = (json: any) => { + return ( + typeof json === "object" && + json && + json.type === "excalidrawlib" && + json.version === 1 + ); +}; + export const saveLibraryAsJSON = async () => { const library = await loadLibrary(); const serialized = JSON.stringify( diff --git a/src/locales/en.json b/src/locales/en.json index 02483e79..4e637d5a 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -112,7 +112,9 @@ "couldNotCopyToClipboard": "Couldn't copy to clipboard. Try using Chrome browser.", "decryptFailed": "Couldn't decrypt data.", "uploadedSecurly": "The upload has been secured with end-to-end encryption, which means that Excalidraw server and third parties can't read the content.", - "loadSceneOverridePrompt": "Loading external drawing will replace your existing content. Do you wish to continue?" + "loadSceneOverridePrompt": "Loading external drawing will replace your existing content. Do you wish to continue?", + "errorLoadingLibrary": "There was an error loading the third party library.", + "confirmAddLibrary": "This will add {{numShapes}} shape(s) to your library. Are you sure?" }, "toolBar": { "selection": "Selection",