diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/invocationComplete.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/invocationComplete.ts index 3755b38d41..0222eea93c 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/invocationComplete.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/invocationComplete.ts @@ -5,6 +5,7 @@ import { imageUrlsReceived, } from 'services/thunks/image'; import { startAppListening } from '..'; +import { addImageToStagingArea } from 'features/canvas/store/canvasSlice'; const nodeDenylist = ['dataURL_image']; @@ -24,7 +25,7 @@ export const addImageResultReceivedListener = () => { return; } - const { data, shouldFetchImages } = action.payload; + const { data } = action.payload; const { result, node, graph_execution_state_id } = data; if (isImageOutput(result) && !nodeDenylist.includes(node.type)) { @@ -41,63 +42,20 @@ export const addImageResultReceivedListener = () => { }) ); - // const [x] = await take( - // ( - // action - // ): action is ReturnType => - // imageMetadataReceived.fulfilled.match(action) && - // action.payload.image_name === name - // ); - - // console.log(x); - - // const state = getState(); - - // // if we need to refetch, set URLs to placeholder for now - // const { url, thumbnail } = shouldFetchImages - // ? { url: '', thumbnail: '' } - // : buildImageUrls(type, name); - - // const timestamp = extractTimestampFromImageName(name); - - // const image: Image = { - // name, - // type, - // url, - // thumbnail, - // metadata: { - // created: timestamp, - // width: result.width, - // height: result.height, - // invokeai: { - // session_id: graph_execution_state_id, - // ...(node ? { node } : {}), - // }, - // }, - // }; - - // dispatch(resultAdded(image)); - - // if (state.gallery.shouldAutoSwitchToNewImages) { - // dispatch(imageSelected(image)); - // } - - // if (state.config.shouldFetchImages) { - // dispatch(imageReceived({ imageName: name, imageType: type })); - // dispatch( - // thumbnailReceived({ - // thumbnailName: name, - // thumbnailType: type, - // }) - // ); - // } - - // if ( - // graph_execution_state_id === - // state.canvas.layerState.stagingArea.sessionId - // ) { - // dispatch(addImageToStagingArea(image)); - // } + // Handle canvas image + if ( + graph_execution_state_id === + getState().canvas.layerState.stagingArea.sessionId + ) { + const [{ payload: image }] = await take( + ( + action + ): action is ReturnType => + imageMetadataReceived.fulfilled.match(action) && + action.payload.image_name === image_name + ); + dispatch(addImageToStagingArea(image)); + } } }, }); diff --git a/invokeai/frontend/web/src/app/types/invokeai.ts b/invokeai/frontend/web/src/app/types/invokeai.ts index 9cd2028984..68f7568779 100644 --- a/invokeai/frontend/web/src/app/types/invokeai.ts +++ b/invokeai/frontend/web/src/app/types/invokeai.ts @@ -346,7 +346,6 @@ export type AppConfig = { /** * Whether or not we need to re-fetch images */ - shouldFetchImages: boolean; disabledTabs: InvokeTabName[]; disabledFeatures: AppFeature[]; disabledSDFeatures: SDFeature[]; diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasObjectRenderer.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasObjectRenderer.tsx index 32d2b36324..c99465cf40 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasObjectRenderer.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasObjectRenderer.tsx @@ -46,7 +46,7 @@ const IAICanvasObjectRenderer = () => { key={i} x={obj.x} y={obj.y} - url={getUrl(obj.image.url)} + url={getUrl(obj.image.image_url)} /> ); } else if (isCanvasBaseLine(obj)) { diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingArea.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingArea.tsx index f84a5b0e49..e6a8a82ed2 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingArea.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingArea.tsx @@ -62,7 +62,7 @@ const IAICanvasStagingArea = (props: Props) => { {shouldShowStagingImage && currentStagingAreaImage && ( diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingAreaToolbar.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingAreaToolbar.tsx index eeb51d955b..64c752fce0 100644 --- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingAreaToolbar.tsx +++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasStagingAreaToolbar.tsx @@ -157,17 +157,19 @@ const IAICanvasStagingAreaToolbar = () => { } colorScheme="accent" /> - } onClick={() => dispatch( - saveStagingAreaImageToGallery(currentStagingAreaImage.image.url) + saveStagingAreaImageToGallery( + currentStagingAreaImage.image.image_url + ) ) } colorScheme="accent" - /> + /> */} ) => { const image = action.payload; - const { width, height } = image.metadata; + const { width, height } = image; const { stageDimensions } = state; const newBoundingBoxDimensions = { diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImageButtons.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImageButtons.tsx index f7932db0c4..f5265b54db 100644 --- a/invokeai/frontend/web/src/features/gallery/components/CurrentImageButtons.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/CurrentImageButtons.tsx @@ -195,14 +195,14 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => { } if (shouldTransformUrls) { - return getUrl(image.url); + return getUrl(image.image_url); } - if (image.url.startsWith('http')) { - return image.url; + if (image.image_url.startsWith('http')) { + return image.image_url; } - return window.location.toString() + image.url; + return window.location.toString() + image.image_url; }; const url = getImageUrl(); diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageMetaDataViewer/OLD_ImageMetadataViewer.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageMetaDataViewer/OLD_ImageMetadataViewer.tsx deleted file mode 100644 index c76ee7f078..0000000000 --- a/invokeai/frontend/web/src/features/gallery/components/ImageMetaDataViewer/OLD_ImageMetadataViewer.tsx +++ /dev/null @@ -1,470 +0,0 @@ -import { ExternalLinkIcon } from '@chakra-ui/icons'; -import { - Box, - Center, - Flex, - Heading, - IconButton, - Link, - Text, - Tooltip, -} from '@chakra-ui/react'; -import * as InvokeAI from 'app/types/invokeai'; -import { useAppDispatch } from 'app/store/storeHooks'; -import { useGetUrl } from 'common/util/getUrl'; -import promptToString from 'common/util/promptToString'; -import { seedWeightsToString } from 'common/util/seedWeightPairs'; -import useSetBothPrompts from 'features/parameters/hooks/usePrompt'; -import { - setCfgScale, - setHeight, - setImg2imgStrength, - // setInitialImage, - setMaskPath, - setPerlin, - setSampler, - setSeamless, - setSeed, - setSeedWeights, - setShouldFitToWidthHeight, - setSteps, - setThreshold, - setWidth, -} from 'features/parameters/store/generationSlice'; -import { - setCodeformerFidelity, - setFacetoolStrength, - setFacetoolType, - setHiresFix, - setUpscalingDenoising, - setUpscalingLevel, - setUpscalingStrength, -} from 'features/parameters/store/postprocessingSlice'; -import { setShouldShowImageDetails } from 'features/ui/store/uiSlice'; -import { memo } from 'react'; -import { useHotkeys } from 'react-hotkeys-hook'; -import { useTranslation } from 'react-i18next'; -import { FaCopy } from 'react-icons/fa'; -import { IoArrowUndoCircleOutline } from 'react-icons/io5'; -import * as png from '@stevebel/png'; - -type MetadataItemProps = { - isLink?: boolean; - label: string; - onClick?: () => void; - value: number | string | boolean; - labelPosition?: string; - withCopy?: boolean; -}; - -/** - * Component to display an individual metadata item or parameter. - */ -const MetadataItem = ({ - label, - value, - onClick, - isLink, - labelPosition, - withCopy = false, -}: MetadataItemProps) => { - const { t } = useTranslation(); - - return ( - - {onClick && ( - - } - size="xs" - variant="ghost" - fontSize={20} - onClick={onClick} - /> - - )} - {withCopy && ( - - } - size="xs" - variant="ghost" - fontSize={14} - onClick={() => navigator.clipboard.writeText(value.toString())} - /> - - )} - - - {label}: - - {isLink ? ( - - {value.toString()} - - ) : ( - - {value.toString()} - - )} - - - ); -}; - -type ImageMetadataViewerProps = { - image: InvokeAI.Image; -}; - -// TODO: I don't know if this is needed. -const memoEqualityCheck = ( - prev: ImageMetadataViewerProps, - next: ImageMetadataViewerProps -) => prev.image.name === next.image.name; - -// TODO: Show more interesting information in this component. - -/** - * Image metadata viewer overlays currently selected image and provides - * access to any of its metadata for use in processing. - */ -const ImageMetadataViewer = memo(({ image }: ImageMetadataViewerProps) => { - const dispatch = useAppDispatch(); - - const setBothPrompts = useSetBothPrompts(); - - useHotkeys('esc', () => { - dispatch(setShouldShowImageDetails(false)); - }); - - const metadata = image?.metadata.sd_metadata || {}; - const dreamPrompt = image?.metadata.sd_metadata?.dreamPrompt; - - const { - cfg_scale, - fit, - height, - hires_fix, - init_image_path, - mask_image_path, - orig_path, - perlin, - postprocessing, - prompt, - sampler, - seamless, - seed, - steps, - strength, - threshold, - type, - variations, - width, - model_weights, - } = metadata; - - const { t } = useTranslation(); - const { getUrl } = useGetUrl(); - - const metadataJSON = JSON.stringify(image, null, 2); - - // fetch(getUrl(image.url)) - // .then((r) => r.arrayBuffer()) - // .then((buffer) => { - // const { text } = png.decode(buffer); - // const metadata = text?.['sd-metadata'] - // ? JSON.parse(text['sd-metadata'] ?? {}) - // : {}; - // console.log(metadata); - // }); - - return ( - - - File: - - {image.url.length > 64 - ? image.url.substring(0, 64).concat('...') - : image.url} - - - - - - - } - size="xs" - variant="ghost" - fontSize={14} - onClick={() => navigator.clipboard.writeText(metadataJSON)} - /> - - Metadata JSON: - - -
{metadataJSON}
-
-
- {Object.keys(metadata).length > 0 ? ( - <> - {type && } - {model_weights && ( - - )} - {['esrgan', 'gfpgan'].includes(type) && ( - - )} - {prompt && ( - setBothPrompts(prompt)} - /> - )} - {seed !== undefined && ( - dispatch(setSeed(seed))} - /> - )} - {threshold !== undefined && ( - dispatch(setThreshold(threshold))} - /> - )} - {perlin !== undefined && ( - dispatch(setPerlin(perlin))} - /> - )} - {sampler && ( - dispatch(setSampler(sampler))} - /> - )} - {steps && ( - dispatch(setSteps(steps))} - /> - )} - {cfg_scale !== undefined && ( - dispatch(setCfgScale(cfg_scale))} - /> - )} - {variations && variations.length > 0 && ( - - dispatch(setSeedWeights(seedWeightsToString(variations))) - } - /> - )} - {seamless && ( - dispatch(setSeamless(seamless))} - /> - )} - {hires_fix && ( - dispatch(setHiresFix(hires_fix))} - /> - )} - {width && ( - dispatch(setWidth(width))} - /> - )} - {height && ( - dispatch(setHeight(height))} - /> - )} - {/* {init_image_path && ( - dispatch(setInitialImage(init_image_path))} - /> - )} */} - {mask_image_path && ( - dispatch(setMaskPath(mask_image_path))} - /> - )} - {type === 'img2img' && strength && ( - dispatch(setImg2imgStrength(strength))} - /> - )} - {fit && ( - dispatch(setShouldFitToWidthHeight(fit))} - /> - )} - {postprocessing && postprocessing.length > 0 && ( - <> - Postprocessing - {postprocessing.map( - ( - postprocess: InvokeAI.PostProcessedImageMetadata, - i: number - ) => { - if (postprocess.type === 'esrgan') { - const { scale, strength, denoise_str } = postprocess; - return ( - - {`${i + 1}: Upscale (ESRGAN)`} - dispatch(setUpscalingLevel(scale))} - /> - - dispatch(setUpscalingStrength(strength)) - } - /> - {denoise_str !== undefined && ( - - dispatch(setUpscalingDenoising(denoise_str)) - } - /> - )} - - ); - } else if (postprocess.type === 'gfpgan') { - const { strength } = postprocess; - return ( - - {`${ - i + 1 - }: Face restoration (GFPGAN)`} - - { - dispatch(setFacetoolStrength(strength)); - dispatch(setFacetoolType('gfpgan')); - }} - /> - - ); - } else if (postprocess.type === 'codeformer') { - const { strength, fidelity } = postprocess; - return ( - - {`${ - i + 1 - }: Face restoration (Codeformer)`} - - { - dispatch(setFacetoolStrength(strength)); - dispatch(setFacetoolType('codeformer')); - }} - /> - {fidelity && ( - { - dispatch(setCodeformerFidelity(fidelity)); - dispatch(setFacetoolType('codeformer')); - }} - /> - )} - - ); - } - } - )} - - )} - {dreamPrompt && ( - - )} - - ) : ( -
- - No metadata available - -
- )} -
- ); -}, memoEqualityCheck); - -ImageMetadataViewer.displayName = 'ImageMetadataViewer'; - -export default ImageMetadataViewer; diff --git a/invokeai/frontend/web/src/features/system/store/configSlice.ts b/invokeai/frontend/web/src/features/system/store/configSlice.ts index 7b3a1b1eea..f8cb3a483c 100644 --- a/invokeai/frontend/web/src/features/system/store/configSlice.ts +++ b/invokeai/frontend/web/src/features/system/store/configSlice.ts @@ -5,7 +5,6 @@ import { merge } from 'lodash-es'; export const initialConfigState: AppConfig = { shouldTransformUrls: false, - shouldFetchImages: false, disabledTabs: [], disabledFeatures: [], disabledSDFeatures: [], diff --git a/invokeai/frontend/web/src/services/events/actions.ts b/invokeai/frontend/web/src/services/events/actions.ts index 84268773a9..76bffeaa49 100644 --- a/invokeai/frontend/web/src/services/events/actions.ts +++ b/invokeai/frontend/web/src/services/events/actions.ts @@ -38,7 +38,6 @@ export const invocationStarted = createAction< export const invocationComplete = createAction< BaseSocketPayload & { data: InvocationCompleteEvent; - shouldFetchImages: boolean; } >('socket/invocationComplete'); diff --git a/invokeai/frontend/web/src/services/events/util/setEventListeners.ts b/invokeai/frontend/web/src/services/events/util/setEventListeners.ts index e9356dd271..4431a9fd8b 100644 --- a/invokeai/frontend/web/src/services/events/util/setEventListeners.ts +++ b/invokeai/frontend/web/src/services/events/util/setEventListeners.ts @@ -165,7 +165,6 @@ export const setEventListeners = (arg: SetEventListenersArg) => { const sessionId = data.graph_execution_state_id; const { cancelType, isCancelScheduled } = getState().system; - const { shouldFetchImages } = getState().config; // Handle scheduled cancelation if (cancelType === 'scheduled' && isCancelScheduled) { @@ -176,7 +175,6 @@ export const setEventListeners = (arg: SetEventListenersArg) => { invocationComplete({ data, timestamp: getTimestamp(), - shouldFetchImages, }) ); });