From b2822f353882d0d479c809da4212862091ab9665 Mon Sep 17 00:00:00 2001 From: Thomas Steiner Date: Tue, 22 Sep 2020 15:21:22 +0200 Subject: [PATCH] Make File Handling actually work (#2181) Follow-up from #1736 --- public/manifest.json | 2 +- src/actions/actionExport.tsx | 1 + src/components/App.tsx | 28 ++++++++++++++++++++++++++++ src/data/blob.ts | 1 + src/data/index.ts | 4 +--- src/data/json.ts | 1 + src/index.tsx | 14 -------------- 7 files changed, 33 insertions(+), 18 deletions(-) diff --git a/public/manifest.json b/public/manifest.json index 629b6fba..2ebc8e3c 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -14,7 +14,7 @@ "sizes": "256x256" } ], - "start_url": ".", + "start_url": "/", "display": "standalone", "theme_color": "#000000", "background_color": "#ffffff", diff --git a/src/actions/actionExport.tsx b/src/actions/actionExport.tsx index 6fcf2e7d..5e5b8106 100644 --- a/src/actions/actionExport.tsx +++ b/src/actions/actionExport.tsx @@ -66,6 +66,7 @@ export const actionChangeShouldAddWatermark = register({ export const actionSaveScene = register({ name: "saveScene", perform: (elements, appState, value) => { + // TODO: Make this part of `AppState`. saveAsJSON(elements, appState, (window as any).handle) .catch(muteFSAbortError) .catch((error) => console.error(error)); diff --git a/src/components/App.tsx b/src/components/App.tsx index 5f4e7512..82023c35 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -493,6 +493,33 @@ class App extends React.Component { } private initializeScene = async () => { + if ("launchQueue" in window && "LaunchParams" in window) { + (window as any).launchQueue.setConsumer( + async (launchParams: { files: any[] }) => { + if (!launchParams.files.length) { + return; + } + const fileHandle = launchParams.files[0]; + const blob = await fileHandle.getFile(); + blob.handle = fileHandle; + loadFromBlob(blob, this.state) + .then(({ elements, appState }) => + this.syncActionResult({ + elements, + appState: { + ...(appState || this.state), + isLoading: false, + }, + commitToHistory: true, + }), + ) + .catch((error) => { + this.setState({ isLoading: false, errorMessage: error.message }); + }); + }, + ); + } + const searchParams = new URLSearchParams(window.location.search); const id = searchParams.get("id"); const jsonMatch = window.location.hash.match( @@ -3656,6 +3683,7 @@ class App extends React.Component { // This will only work as of Chrome 86, // but can be safely ignored on older releases. const item = event.dataTransfer.items[0]; + // TODO: Make this part of `AppState`. (window as any).handle = await (item as any).getAsFileSystemHandle(); } catch (error) { console.warn(error.name, error.message); diff --git a/src/data/blob.ts b/src/data/blob.ts index 2a8ede47..87a14b78 100644 --- a/src/data/blob.ts +++ b/src/data/blob.ts @@ -29,6 +29,7 @@ const loadFileContents = async (blob: any) => { */ export const loadFromBlob = async (blob: any, appState?: AppState) => { if (blob.handle) { + // TODO: Make this part of `AppState`. (window as any).handle = blob.handle; } diff --git a/src/data/index.ts b/src/data/index.ts index 72ecf040..37c31e7f 100644 --- a/src/data/index.ts +++ b/src/data/index.ts @@ -66,9 +66,7 @@ export type SocketUpdateDataIncoming = type: "INVALID_RESPONSE"; }; -// TODO: Defined globally, since file handles aren't yet serializable. -// Once `FileSystemFileHandle` can be serialized, make this -// part of `AppState`. +// TODO: Make this part of `AppState`. (window as any).handle = null; const byteToHex = (byte: number): string => `0${byte.toString(16)}`.slice(-2); diff --git a/src/data/json.ts b/src/data/json.ts index 9098cd46..f64131fd 100644 --- a/src/data/json.ts +++ b/src/data/json.ts @@ -33,6 +33,7 @@ export const saveAsJSON = async ( type: "application/json", }); const name = `${appState.name}.excalidraw`; + // TODO: Make this part of `AppState`. (window as any).handle = await fileSave( blob, { diff --git a/src/index.tsx b/src/index.tsx index 614ef5cd..09bdac2c 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -8,7 +8,6 @@ import { TopErrorBoundary } from "./components/TopErrorBoundary"; import Excalidraw from "./excalidraw-embed/index"; import { register as registerServiceWorker } from "./serviceWorker"; -import { loadFromBlob } from "./data"; import { debounce } from "./utils"; import { importFromLocalStorage, @@ -182,16 +181,3 @@ registerServiceWorker({ } }, }); - -if ("launchQueue" in window && "LaunchParams" in window) { - (window as any).launchQueue.setConsumer( - async (launchParams: { files: any[] }) => { - if (!launchParams.files.length) { - return; - } - const fileHandle = launchParams.files[0]; - const blob = await fileHandle.getFile(); - loadFromBlob(blob); - }, - ); -}