From 6f78c073ed3ed3f4468241a299b057ea3d8a735f Mon Sep 17 00:00:00 2001
From: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date: Tue, 23 May 2023 23:46:52 +1000
Subject: [PATCH] fix(ui): fix uploads & other bugs
---
.../listeners/canvasMerged.ts | 3 +-
.../listeners/imageUploaded.ts | 10 +++----
.../gallery/components/HoverableImage.tsx | 11 ++++---
.../ImageMetadataViewer.tsx | 4 +--
.../frontend/web/src/services/thunks/image.ts | 11 ++-----
.../frontend/web/src/services/types/guards.ts | 14 +++++----
.../services/util/deserializeImageField.ts | 27 -----------------
.../services/util/deserializeImageResponse.ts | 29 -------------------
8 files changed, 22 insertions(+), 87 deletions(-)
delete mode 100644 invokeai/frontend/web/src/services/util/deserializeImageField.ts
delete mode 100644 invokeai/frontend/web/src/services/util/deserializeImageResponse.ts
diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasMerged.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasMerged.ts
index d7a58c2050..1e2d99541c 100644
--- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasMerged.ts
+++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasMerged.ts
@@ -5,7 +5,6 @@ import { getBaseLayerBlob } from 'features/canvas/util/getBaseLayerBlob';
import { addToast } from 'features/system/store/systemSlice';
import { imageUploaded } from 'services/thunks/image';
import { v4 as uuidv4 } from 'uuid';
-import { deserializeImageResponse } from 'services/util/deserializeImageResponse';
import { setMergedCanvas } from 'features/canvas/store/canvasSlice';
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
@@ -66,7 +65,7 @@ export const addCanvasMergedListener = () => {
action.meta.arg.formData.file.name === filename
);
- const mergedCanvasImage = deserializeImageResponse(payload.response);
+ const mergedCanvasImage = payload.response;
dispatch(
setMergedCanvas({
diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageUploaded.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageUploaded.ts
index de06220ecd..1d66166c12 100644
--- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageUploaded.ts
+++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imageUploaded.ts
@@ -1,4 +1,3 @@
-import { deserializeImageResponse } from 'services/util/deserializeImageResponse';
import { startAppListening } from '..';
import { uploadAdded } from 'features/gallery/store/uploadsSlice';
import { imageSelected } from 'features/gallery/store/gallerySlice';
@@ -7,6 +6,7 @@ import { addToast } from 'features/system/store/systemSlice';
import { initialImageSelected } from 'features/parameters/store/actions';
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
import { resultAdded } from 'features/gallery/store/resultsSlice';
+import { isResultsImageDTO, isUploadsImageDTO } from 'services/types/guards';
export const addImageUploadedListener = () => {
startAppListening({
@@ -14,13 +14,11 @@ export const addImageUploadedListener = () => {
imageUploaded.fulfilled.match(action) &&
action.payload.response.image_type !== 'intermediates',
effect: (action, { dispatch, getState }) => {
- const { response } = action.payload;
- const { imageType } = action.meta.arg;
+ const { response: image } = action.payload;
const state = getState();
- const image = deserializeImageResponse(response);
- if (imageType === 'uploads') {
+ if (isUploadsImageDTO(image)) {
dispatch(uploadAdded(image));
dispatch(addToast({ title: 'Image Uploaded', status: 'success' }));
@@ -38,7 +36,7 @@ export const addImageUploadedListener = () => {
}
}
- if (imageType === 'results') {
+ if (isResultsImageDTO(image)) {
dispatch(resultAdded(image));
}
},
diff --git a/invokeai/frontend/web/src/features/gallery/components/HoverableImage.tsx b/invokeai/frontend/web/src/features/gallery/components/HoverableImage.tsx
index e1e0f0458c..04fecac463 100644
--- a/invokeai/frontend/web/src/features/gallery/components/HoverableImage.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/HoverableImage.tsx
@@ -13,7 +13,6 @@ import { DragEvent, MouseEvent, memo, useCallback, useState } from 'react';
import { FaCheck, FaExpand, FaImage, FaShare, FaTrash } from 'react-icons/fa';
import DeleteImageModal from './DeleteImageModal';
import { ContextMenu } from 'chakra-ui-contextmenu';
-import * as InvokeAI from 'app/types/invokeai';
import {
resizeAndScaleCanvas,
setInitialCanvasImage,
@@ -168,9 +167,9 @@ const HoverableImage = memo((props: HoverableImageProps) => {
dispatch(initialImageSelected(image));
}, [dispatch, image]);
- const handleRecallInitialImage = useCallback(() => {
- recallInitialImage(image.metadata.invokeai?.node?.image);
- }, [image, recallInitialImage]);
+ // const handleRecallInitialImage = useCallback(() => {
+ // recallInitialImage(image.metadata.invokeai?.node?.image);
+ // }, [image, recallInitialImage]);
/**
* TODO: the rest of these
@@ -238,13 +237,13 @@ const HoverableImage = memo((props: HoverableImageProps) => {
>
{t('parameters.useSeed')}
- }
onClickCapture={handleRecallInitialImage}
isDisabled={image?.metadata?.type !== 'img2img'}
>
{t('parameters.useInitImg')}
-
+ */}
}
onClickCapture={handleUseAllParameters}
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageMetaDataViewer/ImageMetadataViewer.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageMetaDataViewer/ImageMetadataViewer.tsx
index 3ec820ade7..b87fdcb90e 100644
--- a/invokeai/frontend/web/src/features/gallery/components/ImageMetaDataViewer/ImageMetadataViewer.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/ImageMetaDataViewer/ImageMetadataViewer.tsx
@@ -164,9 +164,7 @@ const ImageMetadataViewer = memo(({ image }: ImageMetadataViewerProps) => {
isExternal
maxW="calc(100% - 3rem)"
>
- {image.image_url.length > 64
- ? image.image_url.substring(0, 64).concat('...')
- : image.image_url}
+ {image.image_name}
diff --git a/invokeai/frontend/web/src/services/thunks/image.ts b/invokeai/frontend/web/src/services/thunks/image.ts
index bf6cc40e2e..6831eb647d 100644
--- a/invokeai/frontend/web/src/services/thunks/image.ts
+++ b/invokeai/frontend/web/src/services/thunks/image.ts
@@ -1,4 +1,3 @@
-import { AnyAction } from '@reduxjs/toolkit';
import { log } from 'app/logging/useLogger';
import { createAppAsyncThunk } from 'app/store/storeUtils';
import { InvokeTabName } from 'features/ui/store/tabMap';
@@ -56,10 +55,7 @@ export const imageUploaded = createAppAsyncThunk(
const response = await ImagesService.uploadImage(rest);
const { location } = getHeaders(response);
- imagesLog.info(
- { arg: '', response, location },
- `Image uploaded (${response.image_name})`
- );
+ imagesLog.debug({ arg: '', response, location }, 'Image uploaded');
return { response, location };
}
@@ -75,10 +71,7 @@ export const imageDeleted = createAppAsyncThunk(
async (arg: ImageDeletedArg) => {
const response = await ImagesService.deleteImage(arg);
- imagesLog.info(
- { arg, response },
- `Image deleted (${arg.imageType} - ${arg.imageName})`
- );
+ imagesLog.debug({ arg, response }, 'Image deleted');
return response;
}
diff --git a/invokeai/frontend/web/src/services/types/guards.ts b/invokeai/frontend/web/src/services/types/guards.ts
index f7eba6e9d6..266e991f4d 100644
--- a/invokeai/frontend/web/src/services/types/guards.ts
+++ b/invokeai/frontend/web/src/services/types/guards.ts
@@ -1,3 +1,5 @@
+import { ResultsImageDTO } from 'features/gallery/store/resultsSlice';
+import { UploadsImageDTO } from 'features/gallery/store/uploadsSlice';
import { get, isObject, isString } from 'lodash-es';
import {
GraphExecutionState,
@@ -10,8 +12,15 @@ import {
ImageType,
ImageField,
LatentsOutput,
+ ImageDTO,
} from 'services/api';
+export const isUploadsImageDTO = (image: ImageDTO): image is UploadsImageDTO =>
+ image.image_type === 'uploads';
+
+export const isResultsImageDTO = (image: ImageDTO): image is ResultsImageDTO =>
+ image.image_type === 'results';
+
export const isImageOutput = (
output: GraphExecutionState['results'][string]
): output is ImageOutput => output.type === 'image_output';
@@ -43,11 +52,6 @@ export const isCollectOutput = (
export const isImageType = (t: unknown): t is ImageType =>
isString(t) && ['results', 'uploads', 'intermediates'].includes(t);
-export const isImage = (image: unknown): image is Image =>
- isObject(image) &&
- isString(get(image, 'name')) &&
- isImageType(get(image, 'type'));
-
export const isImageField = (imageField: unknown): imageField is ImageField =>
isObject(imageField) &&
isString(get(imageField, 'image_name')) &&
diff --git a/invokeai/frontend/web/src/services/util/deserializeImageField.ts b/invokeai/frontend/web/src/services/util/deserializeImageField.ts
deleted file mode 100644
index 74d63117a4..0000000000
--- a/invokeai/frontend/web/src/services/util/deserializeImageField.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { ImageType } from 'services/api';
-
-export const buildImageUrls = (
- imageType: ImageType,
- imageName: string
-): { url: string; thumbnail: string } => {
- const url = `api/v1/images/${imageType}/${imageName}`;
-
- const thumbnail = `api/v1/images/${imageType}/thumbnails/${
- imageName.split('.')[0]
- }.webp`;
-
- return {
- url,
- thumbnail,
- };
-};
-
-export const extractTimestampFromImageName = (imageName: string) => {
- const timestamp = imageName.split('_')?.pop()?.split('.')[0];
-
- if (timestamp === undefined) {
- return 0;
- }
-
- return Number(timestamp);
-};
diff --git a/invokeai/frontend/web/src/services/util/deserializeImageResponse.ts b/invokeai/frontend/web/src/services/util/deserializeImageResponse.ts
deleted file mode 100644
index 8d2a6df49e..0000000000
--- a/invokeai/frontend/web/src/services/util/deserializeImageResponse.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { Image } from 'app/types/invokeai';
-import { parseInvokeAIMetadata } from 'common/util/parseMetadata';
-import { ImageResponse } from 'services/api';
-
-/**
- * Process ImageReponse objects, which we get from the `list_images` endpoint.
- */
-export const deserializeImageResponse = (
- imageResponse: ImageResponse
-): Image => {
- const { image_name, image_type, image_url, metadata, thumbnail_url } =
- imageResponse;
-
- // TODO: parse metadata - just leaving it as-is for now
- const { invokeai, ...rest } = metadata;
-
- const parsedMetadata = parseInvokeAIMetadata(invokeai);
-
- return {
- name: image_name,
- type: image_type,
- url: image_url,
- thumbnail: thumbnail_url,
- metadata: {
- ...rest,
- ...(invokeai ? { invokeai: parsedMetadata } : {}),
- },
- };
-};