mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
fix(ui): fix uploads & other bugs
This commit is contained in:
parent
c406be6f4f
commit
6f78c073ed
@ -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({
|
||||
|
@ -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));
|
||||
}
|
||||
},
|
||||
|
@ -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')}
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
{/* <MenuItem
|
||||
icon={<IoArrowUndoCircleOutline />}
|
||||
onClickCapture={handleRecallInitialImage}
|
||||
isDisabled={image?.metadata?.type !== 'img2img'}
|
||||
>
|
||||
{t('parameters.useInitImg')}
|
||||
</MenuItem>
|
||||
</MenuItem> */}
|
||||
<MenuItem
|
||||
icon={<IoArrowUndoCircleOutline />}
|
||||
onClickCapture={handleUseAllParameters}
|
||||
|
@ -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}
|
||||
<ExternalLinkIcon mx="2px" />
|
||||
</Link>
|
||||
</Flex>
|
||||
|
@ -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: '<Blob>', response, location },
|
||||
`Image uploaded (${response.image_name})`
|
||||
);
|
||||
imagesLog.debug({ arg: '<Blob>', 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;
|
||||
}
|
||||
|
@ -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')) &&
|
||||
|
@ -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);
|
||||
};
|
@ -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 } : {}),
|
||||
},
|
||||
};
|
||||
};
|
Loading…
Reference in New Issue
Block a user