From f639d44a954385e846edda12ca66916d7e47aaa6 Mon Sep 17 00:00:00 2001 From: Aakansha Doshi Date: Fri, 23 Feb 2024 15:05:46 +0530 Subject: [PATCH] fix: remove dependency of t in blob.ts (#7717) * remove dependency of t in blob.ts * fix --- packages/excalidraw/components/App.tsx | 75 +++++++++++++------ .../components/ImageExportDialog.tsx | 13 +++- .../excalidraw/components/TTDDialog/common.ts | 10 ++- packages/excalidraw/data/blob.ts | 30 ++++---- packages/excalidraw/data/index.ts | 2 +- 5 files changed, 86 insertions(+), 44 deletions(-) diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index c9985c88d..97ce14662 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -3214,7 +3214,13 @@ class App extends React.Component { try { return { file: await ImageURLToFile(url) }; } catch (error: any) { - return { errorMessage: error.message as string }; + let errorMessage = error.message; + if (error.cause === "FETCH_ERROR") { + errorMessage = t("errors.failedToFetchImage"); + } else if (error.cause === "UNSUPPORTED") { + errorMessage = t("errors.unsupportedFileType"); + } + return { errorMessage }; } }), ); @@ -8478,10 +8484,18 @@ class App extends React.Component { // mustn't be larger than 128 px // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property const cursorImageSizePx = 96; + let imagePreview; - const imagePreview = await resizeImageFile(imageFile, { - maxWidthOrHeight: cursorImageSizePx, - }); + try { + imagePreview = await resizeImageFile(imageFile, { + maxWidthOrHeight: cursorImageSizePx, + }); + } catch (e: any) { + if (e.cause === "UNSUPPORTED") { + throw new Error(t("errors.unsupportedFileType")); + } + throw e; + } let previewDataURL = await getDataURL(imagePreview); @@ -8870,8 +8884,9 @@ class App extends React.Component { }); return; } catch (error: any) { + // Don't throw for image scene daa if (error.name !== "EncodingError") { - throw error; + throw new Error(t("alerts.couldNotLoadInvalidFile")); } } } @@ -8945,12 +8960,39 @@ class App extends React.Component { ) => { file = await normalizeFile(file); try { - const ret = await loadSceneOrLibraryFromBlob( - file, - this.state, - this.scene.getElementsIncludingDeleted(), - fileHandle, - ); + let ret; + try { + ret = await loadSceneOrLibraryFromBlob( + file, + this.state, + this.scene.getElementsIncludingDeleted(), + fileHandle, + ); + } catch (error: any) { + const imageSceneDataError = error instanceof ImageSceneDataError; + if ( + imageSceneDataError && + error.code === "IMAGE_NOT_CONTAINS_SCENE_DATA" && + !this.isToolSupported("image") + ) { + this.setState({ + isLoading: false, + errorMessage: t("errors.imageToolNotSupported"), + }); + return; + } + const errorMessage = imageSceneDataError + ? t("alerts.cannotRestoreFromImage") + : t("alerts.couldNotLoadInvalidFile"); + this.setState({ + isLoading: false, + errorMessage, + }); + } + if (!ret) { + return; + } + if (ret.type === MIME_TYPES.excalidraw) { this.setState({ isLoading: true }); this.syncActionResult({ @@ -8975,17 +9017,6 @@ class App extends React.Component { }); } } catch (error: any) { - if ( - error instanceof ImageSceneDataError && - error.code === "IMAGE_NOT_CONTAINS_SCENE_DATA" && - !this.isToolSupported("image") - ) { - this.setState({ - isLoading: false, - errorMessage: t("errors.imageToolNotSupported"), - }); - return; - } this.setState({ isLoading: false, errorMessage: error.message }); } }; diff --git a/packages/excalidraw/components/ImageExportDialog.tsx b/packages/excalidraw/components/ImageExportDialog.tsx index cecdfa79a..73c9a0def 100644 --- a/packages/excalidraw/components/ImageExportDialog.tsx +++ b/packages/excalidraw/components/ImageExportDialog.tsx @@ -124,9 +124,16 @@ const ImageExportModal = ({ setRenderError(null); // if converting to blob fails, there's some problem that will // likely prevent preview and export (e.g. canvas too big) - return canvasToBlob(canvas).then(() => { - previewNode.replaceChildren(canvas); - }); + return canvasToBlob(canvas) + .then(() => { + previewNode.replaceChildren(canvas); + }) + .catch((e) => { + if (e.name === "CANVAS_POSSIBLY_TOO_BIG") { + throw new Error(t("canvasError.canvasTooBig")); + } + throw e; + }); }) .catch((error) => { console.error(error); diff --git a/packages/excalidraw/components/TTDDialog/common.ts b/packages/excalidraw/components/TTDDialog/common.ts index 636d160a8..2389b841e 100644 --- a/packages/excalidraw/components/TTDDialog/common.ts +++ b/packages/excalidraw/components/TTDDialog/common.ts @@ -10,6 +10,7 @@ import { NonDeletedExcalidrawElement } from "../../element/types"; import { AppClassProperties, BinaryFiles } from "../../types"; import { canvasToBlob } from "../../data/blob"; import { EditorLocalStorage } from "../../data/EditorLocalStorage"; +import { t } from "../../i18n"; const resetPreview = ({ canvasRef, @@ -108,7 +109,14 @@ export const convertMermaidToExcalidraw = async ({ }); // if converting to blob fails, there's some problem that will // likely prevent preview and export (e.g. canvas too big) - await canvasToBlob(canvas); + try { + await canvasToBlob(canvas); + } catch (e: any) { + if (e.name === "CANVAS_POSSIBLY_TOO_BIG") { + throw new Error(t("canvasError.canvasTooBig")); + } + throw e; + } parent.style.background = "var(--default-bg-color)"; canvasNode.replaceChildren(canvas); } catch (err: any) { diff --git a/packages/excalidraw/data/blob.ts b/packages/excalidraw/data/blob.ts index 2f8c0db96..527f1c0ea 100644 --- a/packages/excalidraw/data/blob.ts +++ b/packages/excalidraw/data/blob.ts @@ -4,7 +4,6 @@ import { IMAGE_MIME_TYPES, MIME_TYPES } from "../constants"; import { clearElementsForExport } from "../element"; import { ExcalidrawElement, FileId } from "../element/types"; import { CanvasError, ImageSceneDataError } from "../errors"; -import { t } from "../i18n"; import { calculateScrollCenter } from "../scene"; import { AppState, DataURL, LibraryItem } from "../types"; import { ValueOf } from "../utility-types"; @@ -23,11 +22,11 @@ const parseFileContents = async (blob: Blob | File) => { } catch (error: any) { if (error.message === "INVALID") { throw new ImageSceneDataError( - t("alerts.imageDoesNotContainScene"), + "Image doesn't contain scene", "IMAGE_NOT_CONTAINS_SCENE_DATA", ); } else { - throw new ImageSceneDataError(t("alerts.cannotRestoreFromImage")); + throw new ImageSceneDataError("Error: cannot restore image"); } } } else { @@ -54,11 +53,11 @@ const parseFileContents = async (blob: Blob | File) => { } catch (error: any) { if (error.message === "INVALID") { throw new ImageSceneDataError( - t("alerts.imageDoesNotContainScene"), + "Image doesn't contain scene", "IMAGE_NOT_CONTAINS_SCENE_DATA", ); } else { - throw new ImageSceneDataError(t("alerts.cannotRestoreFromImage")); + throw new ImageSceneDataError("Error: cannot restore image"); } } } @@ -130,7 +129,7 @@ export const loadSceneOrLibraryFromBlob = async ( } catch (error: any) { if (isSupportedImageFile(blob)) { throw new ImageSceneDataError( - t("alerts.imageDoesNotContainScene"), + "Image doesn't contain scene", "IMAGE_NOT_CONTAINS_SCENE_DATA", ); } @@ -163,12 +162,12 @@ export const loadSceneOrLibraryFromBlob = async ( data, }; } - throw new Error(t("alerts.couldNotLoadInvalidFile")); + throw new Error("Error: invalid file"); } catch (error: any) { if (error instanceof ImageSceneDataError) { throw error; } - throw new Error(t("alerts.couldNotLoadInvalidFile")); + throw new Error("Error: invalid file"); } }; @@ -187,7 +186,7 @@ export const loadFromBlob = async ( fileHandle, ); if (ret.type !== MIME_TYPES.excalidraw) { - throw new Error(t("alerts.couldNotLoadInvalidFile")); + throw new Error("Error: invalid file"); } return ret.data; }; @@ -222,10 +221,7 @@ export const canvasToBlob = async ( canvas.toBlob((blob) => { if (!blob) { return reject( - new CanvasError( - t("canvasError.canvasTooBig"), - "CANVAS_POSSIBLY_TOO_BIG", - ), + new CanvasError("Error: Canvas too big", "CANVAS_POSSIBLY_TOO_BIG"), ); } resolve(blob); @@ -314,7 +310,7 @@ export const resizeImageFile = async ( } if (!isSupportedImageFile(file)) { - throw new Error(t("errors.unsupportedFileType")); + throw new Error("Error: unsupported file type", { cause: "UNSUPPORTED" }); } return new File( @@ -340,11 +336,11 @@ export const ImageURLToFile = async ( try { response = await fetch(imageUrl); } catch (error: any) { - throw new Error(t("errors.failedToFetchImage")); + throw new Error("Error: failed to fetch image", { cause: "FETCH_ERROR" }); } if (!response.ok) { - throw new Error(t("errors.failedToFetchImage")); + throw new Error("Error: failed to fetch image", { cause: "FETCH_ERROR" }); } const blob = await response.blob(); @@ -354,7 +350,7 @@ export const ImageURLToFile = async ( return new File([blob], name, { type: blob.type }); } - throw new Error(t("errors.unsupportedFileType")); + throw new Error("Error: unsupported file type", { cause: "UNSUPPORTED" }); }; export const getFileFromEvent = async ( diff --git a/packages/excalidraw/data/index.ts b/packages/excalidraw/data/index.ts index ac3975696..3d0555e10 100644 --- a/packages/excalidraw/data/index.ts +++ b/packages/excalidraw/data/index.ts @@ -179,7 +179,7 @@ export const exportCanvas = async ( } catch (error: any) { console.warn(error); if (error.name === "CANVAS_POSSIBLY_TOO_BIG") { - throw error; + throw new Error(t("canvasError.canvasTooBig")); } // TypeError *probably* suggests ClipboardItem not defined, which // people on Firefox can enable through a flag, so let's tell them.