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
This commit is contained in:
Dmitry Parnas 2023-09-21 15:08:12 +03:00 committed by psychedelicious
parent 5aefa49d7d
commit aa82f9360c
7 changed files with 35 additions and 28 deletions

View File

@ -3,7 +3,7 @@ import { startAppListening } from '..';
import { $logger } from 'app/logging/logger'; import { $logger } from 'app/logging/logger';
import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob'; import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
import { addToast } from 'features/system/store/systemSlice'; 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'; import { t } from 'i18next';
export const addCanvasCopiedToClipboardListener = () => { export const addCanvasCopiedToClipboardListener = () => {
@ -15,10 +15,12 @@ export const addCanvasCopiedToClipboardListener = () => {
.child({ namespace: 'canvasCopiedToClipboardListener' }); .child({ namespace: 'canvasCopiedToClipboardListener' });
const state = getState(); const state = getState();
const blob = await getBaseLayerBlob(state); try {
const blob = getBaseLayerBlob(state);
if (!blob) { copyBlobToClipboard(blob);
moduleLog.error('Problem getting base layer blob'); } catch (err) {
moduleLog.error(String(err));
dispatch( dispatch(
addToast({ addToast({
title: t('toast.problemCopyingCanvas'), title: t('toast.problemCopyingCanvas'),
@ -29,8 +31,6 @@ export const addCanvasCopiedToClipboardListener = () => {
return; return;
} }
copyBlobToClipboard(blob);
dispatch( dispatch(
addToast({ addToast({
title: t('toast.canvasCopiedClipboard'), title: t('toast.canvasCopiedClipboard'),

View File

@ -15,10 +15,11 @@ export const addCanvasDownloadedAsImageListener = () => {
.child({ namespace: 'canvasSavedToGalleryListener' }); .child({ namespace: 'canvasSavedToGalleryListener' });
const state = getState(); const state = getState();
const blob = await getBaseLayerBlob(state); let blob;
try {
if (!blob) { blob = await getBaseLayerBlob(state);
moduleLog.error('Problem getting base layer blob'); } catch (err) {
moduleLog.error(String(err));
dispatch( dispatch(
addToast({ addToast({
title: t('toast.problemDownloadingCanvas'), title: t('toast.problemDownloadingCanvas'),

View File

@ -14,10 +14,11 @@ export const addCanvasImageToControlNetListener = () => {
const log = logger('canvas'); const log = logger('canvas');
const state = getState(); const state = getState();
const blob = await getBaseLayerBlob(state); let blob;
try {
if (!blob) { blob = await getBaseLayerBlob(state);
log.error('Problem getting base layer blob'); } catch (err) {
log.error(String(err));
dispatch( dispatch(
addToast({ addToast({
title: t('toast.problemSavingCanvas'), title: t('toast.problemSavingCanvas'),

View File

@ -13,10 +13,11 @@ export const addCanvasSavedToGalleryListener = () => {
const log = logger('canvas'); const log = logger('canvas');
const state = getState(); const state = getState();
const blob = await getBaseLayerBlob(state); let blob;
try {
if (!blob) { blob = await getBaseLayerBlob(state);
log.error('Problem getting base layer blob'); } catch (err) {
log.error(String(err));
dispatch( dispatch(
addToast({ addToast({
title: t('toast.problemSavingCanvas'), title: t('toast.problemSavingCanvas'),

View File

@ -9,7 +9,7 @@ export const getBaseLayerBlob = async (state: RootState) => {
const canvasBaseLayer = getCanvasBaseLayer(); const canvasBaseLayer = getCanvasBaseLayer();
if (!canvasBaseLayer) { if (!canvasBaseLayer) {
return; throw new Error('Problem getting base layer blob');
} }
const { const {

View File

@ -1,10 +1,13 @@
/** /**
* Copies a blob to the clipboard by calling navigator.clipboard.write(). * Copies a blob to the clipboard by calling navigator.clipboard.write().
*/ */
export const copyBlobToClipboard = (blob: Blob) => { export const copyBlobToClipboard = (
blob: Promise<Blob>,
type = 'image/png'
) => {
navigator.clipboard.write([ navigator.clipboard.write([
new ClipboardItem({ new ClipboardItem({
[blob.type]: blob, [type]: blob,
}), }),
]); ]);
}; };

View File

@ -1,6 +1,7 @@
import { useAppToaster } from 'app/components/Toaster'; import { useAppToaster } from 'app/components/Toaster';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { copyBlobToClipboard } from 'features/system/util/copyBlobToClipboard';
export const useCopyImageToClipboard = () => { export const useCopyImageToClipboard = () => {
const toaster = useAppToaster(); const toaster = useAppToaster();
@ -22,13 +23,13 @@ export const useCopyImageToClipboard = () => {
}); });
} }
try { try {
const getImageBlob = async () => {
const response = await fetch(image_url); const response = await fetch(image_url);
const blob = await response.blob(); return await response.blob();
await navigator.clipboard.write([ };
new ClipboardItem({
[blob.type]: blob, copyBlobToClipboard(getImageBlob());
}),
]);
toaster({ toaster({
title: t('toast.imageCopied'), title: t('toast.imageCopied'),
status: 'success', status: 'success',