Make File Handling actually work (#2181)

Follow-up from #1736
This commit is contained in:
Thomas Steiner 2020-09-22 15:21:22 +02:00 committed by GitHub
parent 68bdfaefbe
commit b2822f3538
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 33 additions and 18 deletions

View File

@ -14,7 +14,7 @@
"sizes": "256x256" "sizes": "256x256"
} }
], ],
"start_url": ".", "start_url": "/",
"display": "standalone", "display": "standalone",
"theme_color": "#000000", "theme_color": "#000000",
"background_color": "#ffffff", "background_color": "#ffffff",

View File

@ -66,6 +66,7 @@ export const actionChangeShouldAddWatermark = register({
export const actionSaveScene = register({ export const actionSaveScene = register({
name: "saveScene", name: "saveScene",
perform: (elements, appState, value) => { perform: (elements, appState, value) => {
// TODO: Make this part of `AppState`.
saveAsJSON(elements, appState, (window as any).handle) saveAsJSON(elements, appState, (window as any).handle)
.catch(muteFSAbortError) .catch(muteFSAbortError)
.catch((error) => console.error(error)); .catch((error) => console.error(error));

View File

@ -493,6 +493,33 @@ class App extends React.Component<ExcalidrawProps, AppState> {
} }
private initializeScene = async () => { 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 searchParams = new URLSearchParams(window.location.search);
const id = searchParams.get("id"); const id = searchParams.get("id");
const jsonMatch = window.location.hash.match( const jsonMatch = window.location.hash.match(
@ -3656,6 +3683,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
// This will only work as of Chrome 86, // This will only work as of Chrome 86,
// but can be safely ignored on older releases. // but can be safely ignored on older releases.
const item = event.dataTransfer.items[0]; const item = event.dataTransfer.items[0];
// TODO: Make this part of `AppState`.
(window as any).handle = await (item as any).getAsFileSystemHandle(); (window as any).handle = await (item as any).getAsFileSystemHandle();
} catch (error) { } catch (error) {
console.warn(error.name, error.message); console.warn(error.name, error.message);

View File

@ -29,6 +29,7 @@ const loadFileContents = async (blob: any) => {
*/ */
export const loadFromBlob = async (blob: any, appState?: AppState) => { export const loadFromBlob = async (blob: any, appState?: AppState) => {
if (blob.handle) { if (blob.handle) {
// TODO: Make this part of `AppState`.
(window as any).handle = blob.handle; (window as any).handle = blob.handle;
} }

View File

@ -66,9 +66,7 @@ export type SocketUpdateDataIncoming =
type: "INVALID_RESPONSE"; type: "INVALID_RESPONSE";
}; };
// TODO: Defined globally, since file handles aren't yet serializable. // TODO: Make this part of `AppState`.
// Once `FileSystemFileHandle` can be serialized, make this
// part of `AppState`.
(window as any).handle = null; (window as any).handle = null;
const byteToHex = (byte: number): string => `0${byte.toString(16)}`.slice(-2); const byteToHex = (byte: number): string => `0${byte.toString(16)}`.slice(-2);

View File

@ -33,6 +33,7 @@ export const saveAsJSON = async (
type: "application/json", type: "application/json",
}); });
const name = `${appState.name}.excalidraw`; const name = `${appState.name}.excalidraw`;
// TODO: Make this part of `AppState`.
(window as any).handle = await fileSave( (window as any).handle = await fileSave(
blob, blob,
{ {

View File

@ -8,7 +8,6 @@ import { TopErrorBoundary } from "./components/TopErrorBoundary";
import Excalidraw from "./excalidraw-embed/index"; import Excalidraw from "./excalidraw-embed/index";
import { register as registerServiceWorker } from "./serviceWorker"; import { register as registerServiceWorker } from "./serviceWorker";
import { loadFromBlob } from "./data";
import { debounce } from "./utils"; import { debounce } from "./utils";
import { import {
importFromLocalStorage, 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);
},
);
}