From aa82f9360c09be004233086648055ed354fdada8 Mon Sep 17 00:00:00 2001 From: Dmitry Parnas Date: Thu, 21 Sep 2023 15:08:12 +0300 Subject: [PATCH] fix(ui): passing Promise into ClipboardItem to make it work in Safari throwing Error in getBaseLayerBlob, instead of returning nil using copyBlobToClipboard for both Canvas and Text2Image clipboard functionality --- .../listeners/canvasCopiedToClipboard.ts | 12 ++++++------ .../listeners/canvasDownloadedAsImage.ts | 9 +++++---- .../listeners/canvasImageToControlNet.ts | 9 +++++---- .../listeners/canvasSavedToGallery.ts | 9 +++++---- .../src/features/canvas/util/getBaseLayerBlob.ts | 2 +- .../util/copyBlobToClipboard.ts | 7 +++++-- .../features/ui/hooks/useCopyImageToClipboard.ts | 15 ++++++++------- 7 files changed, 35 insertions(+), 28 deletions(-) rename invokeai/frontend/web/src/features/{canvas => system}/util/copyBlobToClipboard.ts (58%) diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasCopiedToClipboard.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasCopiedToClipboard.ts index c328aceedf..1ac80d219b 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasCopiedToClipboard.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasCopiedToClipboard.ts @@ -3,7 +3,7 @@ import { startAppListening } from '..'; import { $logger } from 'app/logging/logger'; import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob'; import { addToast } from 'features/system/store/systemSlice'; -import { copyBlobToClipboard } from 'features/canvas/util/copyBlobToClipboard'; +import { copyBlobToClipboard } from 'features/system/util/copyBlobToClipboard'; import { t } from 'i18next'; export const addCanvasCopiedToClipboardListener = () => { @@ -15,10 +15,12 @@ export const addCanvasCopiedToClipboardListener = () => { .child({ namespace: 'canvasCopiedToClipboardListener' }); const state = getState(); - const blob = await getBaseLayerBlob(state); + try { + const blob = getBaseLayerBlob(state); - if (!blob) { - moduleLog.error('Problem getting base layer blob'); + copyBlobToClipboard(blob); + } catch (err) { + moduleLog.error(String(err)); dispatch( addToast({ title: t('toast.problemCopyingCanvas'), @@ -29,8 +31,6 @@ export const addCanvasCopiedToClipboardListener = () => { return; } - copyBlobToClipboard(blob); - dispatch( addToast({ title: t('toast.canvasCopiedClipboard'), diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasDownloadedAsImage.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasDownloadedAsImage.ts index 23faf4a356..cfaf20b64c 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasDownloadedAsImage.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasDownloadedAsImage.ts @@ -15,10 +15,11 @@ export const addCanvasDownloadedAsImageListener = () => { .child({ namespace: 'canvasSavedToGalleryListener' }); const state = getState(); - const blob = await getBaseLayerBlob(state); - - if (!blob) { - moduleLog.error('Problem getting base layer blob'); + let blob; + try { + blob = await getBaseLayerBlob(state); + } catch (err) { + moduleLog.error(String(err)); dispatch( addToast({ title: t('toast.problemDownloadingCanvas'), diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasImageToControlNet.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasImageToControlNet.ts index 5181df134f..835b8246f1 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasImageToControlNet.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasImageToControlNet.ts @@ -14,10 +14,11 @@ export const addCanvasImageToControlNetListener = () => { const log = logger('canvas'); const state = getState(); - const blob = await getBaseLayerBlob(state); - - if (!blob) { - log.error('Problem getting base layer blob'); + let blob; + try { + blob = await getBaseLayerBlob(state); + } catch (err) { + log.error(String(err)); dispatch( addToast({ title: t('toast.problemSavingCanvas'), diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasSavedToGallery.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasSavedToGallery.ts index 0bb8ad8550..23e2cebe53 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasSavedToGallery.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasSavedToGallery.ts @@ -13,10 +13,11 @@ export const addCanvasSavedToGalleryListener = () => { const log = logger('canvas'); const state = getState(); - const blob = await getBaseLayerBlob(state); - - if (!blob) { - log.error('Problem getting base layer blob'); + let blob; + try { + blob = await getBaseLayerBlob(state); + } catch (err) { + log.error(String(err)); dispatch( addToast({ title: t('toast.problemSavingCanvas'), diff --git a/invokeai/frontend/web/src/features/canvas/util/getBaseLayerBlob.ts b/invokeai/frontend/web/src/features/canvas/util/getBaseLayerBlob.ts index 20ac482710..3667acc79b 100644 --- a/invokeai/frontend/web/src/features/canvas/util/getBaseLayerBlob.ts +++ b/invokeai/frontend/web/src/features/canvas/util/getBaseLayerBlob.ts @@ -9,7 +9,7 @@ export const getBaseLayerBlob = async (state: RootState) => { const canvasBaseLayer = getCanvasBaseLayer(); if (!canvasBaseLayer) { - return; + throw new Error('Problem getting base layer blob'); } const { diff --git a/invokeai/frontend/web/src/features/canvas/util/copyBlobToClipboard.ts b/invokeai/frontend/web/src/features/system/util/copyBlobToClipboard.ts similarity index 58% rename from invokeai/frontend/web/src/features/canvas/util/copyBlobToClipboard.ts rename to invokeai/frontend/web/src/features/system/util/copyBlobToClipboard.ts index e944e766b5..cf59f2a687 100644 --- a/invokeai/frontend/web/src/features/canvas/util/copyBlobToClipboard.ts +++ b/invokeai/frontend/web/src/features/system/util/copyBlobToClipboard.ts @@ -1,10 +1,13 @@ /** * Copies a blob to the clipboard by calling navigator.clipboard.write(). */ -export const copyBlobToClipboard = (blob: Blob) => { +export const copyBlobToClipboard = ( + blob: Promise, + type = 'image/png' +) => { navigator.clipboard.write([ new ClipboardItem({ - [blob.type]: blob, + [type]: blob, }), ]); }; diff --git a/invokeai/frontend/web/src/features/ui/hooks/useCopyImageToClipboard.ts b/invokeai/frontend/web/src/features/ui/hooks/useCopyImageToClipboard.ts index 314abad081..cefbf3d14e 100644 --- a/invokeai/frontend/web/src/features/ui/hooks/useCopyImageToClipboard.ts +++ b/invokeai/frontend/web/src/features/ui/hooks/useCopyImageToClipboard.ts @@ -1,6 +1,7 @@ import { useAppToaster } from 'app/components/Toaster'; import { useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; +import { copyBlobToClipboard } from 'features/system/util/copyBlobToClipboard'; export const useCopyImageToClipboard = () => { const toaster = useAppToaster(); @@ -22,13 +23,13 @@ export const useCopyImageToClipboard = () => { }); } try { - const response = await fetch(image_url); - const blob = await response.blob(); - await navigator.clipboard.write([ - new ClipboardItem({ - [blob.type]: blob, - }), - ]); + const getImageBlob = async () => { + const response = await fetch(image_url); + return await response.blob(); + }; + + copyBlobToClipboard(getImageBlob()); + toaster({ title: t('toast.imageCopied'), status: 'success',