diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlAdapterPreprocessor.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlAdapterPreprocessor.ts index ba04947a2d..a1eb917ebb 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlAdapterPreprocessor.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/controlAdapterPreprocessor.ts @@ -22,7 +22,13 @@ import type { BatchConfig } from 'services/api/types'; import { socketInvocationComplete } from 'services/events/actions'; import { assert } from 'tsafe'; -const matcher = isAnyOf(caLayerImageChanged, caLayerProcessorConfigChanged, caLayerModelChanged, caLayerRecalled); +const matcher = isAnyOf( + caLayerImageChanged, + caLayerProcessedImageChanged, + caLayerProcessorConfigChanged, + caLayerModelChanged, + caLayerRecalled +); const DEBOUNCE_MS = 300; const log = logger('session'); @@ -73,9 +79,10 @@ export const addControlAdapterPreprocessor = (startAppListening: AppStartListeni const originalConfig = originalLayer?.controlAdapter.processorConfig; const image = layer.controlAdapter.image; + const processedImage = layer.controlAdapter.processedImage; const config = layer.controlAdapter.processorConfig; - if (isEqual(config, originalConfig) && isEqual(image, originalImage)) { + if (isEqual(config, originalConfig) && isEqual(image, originalImage) && processedImage) { // Neither config nor image have changed, we can bail return; } diff --git a/invokeai/frontend/web/src/features/controlLayers/components/CALayer/CALayerControlAdapterWrapper.tsx b/invokeai/frontend/web/src/features/controlLayers/components/CALayer/CALayerControlAdapterWrapper.tsx index 8ff1f9711f..a44ae32c13 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/CALayer/CALayerControlAdapterWrapper.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/CALayer/CALayerControlAdapterWrapper.tsx @@ -4,6 +4,7 @@ import { caLayerControlModeChanged, caLayerImageChanged, caLayerModelChanged, + caLayerProcessedImageChanged, caLayerProcessorConfigChanged, caOrIPALayerBeginEndStepPctChanged, caOrIPALayerWeightChanged, @@ -84,6 +85,14 @@ export const CALayerControlAdapterWrapper = memo(({ layerId }: Props) => { [dispatch, layerId] ); + const onErrorLoadingImage = useCallback(() => { + dispatch(caLayerImageChanged({ layerId, imageDTO: null })); + }, [dispatch, layerId]); + + const onErrorLoadingProcessedImage = useCallback(() => { + dispatch(caLayerProcessedImageChanged({ layerId, imageDTO: null })); + }, [dispatch, layerId]); + const droppableData = useMemo( () => ({ actionType: 'SET_CA_LAYER_IMAGE', @@ -114,6 +123,8 @@ export const CALayerControlAdapterWrapper = memo(({ layerId }: Props) => { onChangeImage={onChangeImage} droppableData={droppableData} postUploadAction={postUploadAction} + onErrorLoadingImage={onErrorLoadingImage} + onErrorLoadingProcessedImage={onErrorLoadingProcessedImage} /> ); }); diff --git a/invokeai/frontend/web/src/features/controlLayers/components/ControlAndIPAdapter/ControlAdapter.tsx b/invokeai/frontend/web/src/features/controlLayers/components/ControlAndIPAdapter/ControlAdapter.tsx index c28c40ecc1..2a7b21352e 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/ControlAndIPAdapter/ControlAdapter.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/ControlAndIPAdapter/ControlAdapter.tsx @@ -28,6 +28,8 @@ type Props = { onChangeProcessorConfig: (processorConfig: ProcessorConfig | null) => void; onChangeModel: (modelConfig: ControlNetModelConfig | T2IAdapterModelConfig) => void; onChangeImage: (imageDTO: ImageDTO | null) => void; + onErrorLoadingImage: () => void; + onErrorLoadingProcessedImage: () => void; droppableData: TypesafeDroppableData; postUploadAction: PostUploadAction; }; @@ -41,6 +43,8 @@ export const ControlAdapter = memo( onChangeProcessorConfig, onChangeModel, onChangeImage, + onErrorLoadingImage, + onErrorLoadingProcessedImage, droppableData, postUploadAction, }: Props) => { @@ -91,6 +95,8 @@ export const ControlAdapter = memo( onChangeImage={onChangeImage} droppableData={droppableData} postUploadAction={postUploadAction} + onErrorLoadingImage={onErrorLoadingImage} + onErrorLoadingProcessedImage={onErrorLoadingProcessedImage} /> diff --git a/invokeai/frontend/web/src/features/controlLayers/components/ControlAndIPAdapter/ControlAdapterImagePreview.tsx b/invokeai/frontend/web/src/features/controlLayers/components/ControlAndIPAdapter/ControlAdapterImagePreview.tsx index 4d93eb12ec..c61cdda4a3 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/ControlAndIPAdapter/ControlAdapterImagePreview.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/ControlAndIPAdapter/ControlAdapterImagePreview.tsx @@ -27,10 +27,19 @@ type Props = { onChangeImage: (imageDTO: ImageDTO | null) => void; droppableData: TypesafeDroppableData; postUploadAction: PostUploadAction; + onErrorLoadingImage: () => void; + onErrorLoadingProcessedImage: () => void; }; export const ControlAdapterImagePreview = memo( - ({ controlAdapter, onChangeImage, droppableData, postUploadAction }: Props) => { + ({ + controlAdapter, + onChangeImage, + droppableData, + postUploadAction, + onErrorLoadingImage, + onErrorLoadingProcessedImage, + }: Props) => { const { t } = useTranslation(); const dispatch = useAppDispatch(); const autoAddBoardId = useAppSelector((s) => s.gallery.autoAddBoardId); @@ -128,10 +137,23 @@ export const ControlAdapterImagePreview = memo( controlAdapter.processorConfig !== null; useEffect(() => { - if (isConnected && (isErrorControlImage || isErrorProcessedControlImage)) { - handleResetControlImage(); + if (!isConnected) { + return; } - }, [handleResetControlImage, isConnected, isErrorControlImage, isErrorProcessedControlImage]); + if (isErrorControlImage) { + onErrorLoadingImage(); + } + if (isErrorProcessedControlImage) { + onErrorLoadingProcessedImage(); + } + }, [ + handleResetControlImage, + isConnected, + isErrorControlImage, + isErrorProcessedControlImage, + onErrorLoadingImage, + onErrorLoadingProcessedImage, + ]); return (