diff --git a/src/components/App.tsx b/src/components/App.tsx index 89eb963d0..b8c4d73f3 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -924,7 +924,7 @@ class App extends React.Component { ?.classList.toggle("theme--dark", this.state.theme === "dark"); if (this.state.autosave && this.state.fileHandle && supported) { - this.saveLocalSceneDebounced( + this.autosaveLocalSceneDebounced( this.scene.getElementsIncludingDeleted(), this.state, ); @@ -1062,18 +1062,31 @@ class App extends React.Component { }); }, SCROLL_TIMEOUT); - private saveLocalSceneDebounced = debounce( + private autosaveLocalSceneDebounced = debounce( async (elements: readonly ExcalidrawElement[], state: AppState) => { if (this.state.autosave && this.state.fileHandle && supported) { try { - await saveAsJSON(elements, state); + await saveAsJSON( + elements, + state, + // only if fileHandle valid + true, + ); } catch (error) { - // shouldn't (almost) ever happen, so let's log it - console.error(error); this.setState({ autosave: false, - errorMessage: t("toast.autosaveFailed"), + toastMessage: + error.name === "NotAllowedError" + ? t("toast.autosaveFailed_notAllowed") + : error.name === "NotFoundError" + ? t("toast.autosaveFailed_notFound") + : t("toast.autosaveFailed"), }); + + // shouldn't happen, so let's log it + if (!["NotAllowedError", "NotFoundError"].includes(error.name)) { + console.error(error); + } } } }, diff --git a/src/components/Toast.scss b/src/components/Toast.scss index 63d949a6b..100ad59e2 100644 --- a/src/components/Toast.scss +++ b/src/components/Toast.scss @@ -10,7 +10,7 @@ cursor: default; left: 50%; margin-left: -150px; - padding: 4px 0; + padding: 8px; position: absolute; text-align: center; width: 300px; diff --git a/src/data/json.ts b/src/data/json.ts index 59ac5eb3e..058021089 100644 --- a/src/data/json.ts +++ b/src/data/json.ts @@ -27,6 +27,7 @@ export const serializeAsJSON = ( export const saveAsJSON = async ( elements: readonly ExcalidrawElement[], appState: AppState, + onlyIfFileHandleValid = false, ) => { const serialized = serializeAsJSON(elements, appState); const blob = new Blob([serialized], { @@ -41,6 +42,7 @@ export const saveAsJSON = async ( extensions: [".excalidraw"], }, appState.fileHandle, + onlyIfFileHandleValid, ); return { fileHandle }; }; diff --git a/src/locales/en.json b/src/locales/en.json index 87ff17f65..ba7ef89bd 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -251,6 +251,8 @@ "width": "Width" }, "toast": { + "autosaveFailed_notAllowed": "Autosave was disabled.", + "autosaveFailed_notFound": "Autosave failed.\nIt seems the file no longer exists.", "autosaveFailed": "Autosave failed.", "copyStyles": "Copied styles.", "copyToClipboard": "Copied to clipboard.",