Skip to content

Commit 9c6c86e

Browse files
fix(ui): image field collection dnd adds instead of replaces
1 parent 6b53a48 commit 9c6c86e

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

invokeai/frontend/web/src/features/dnd/dnd.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ export const addImagesToNodeImageFieldCollectionDndTarget: DndTarget<
262262
}
263263
return false;
264264
},
265-
handler: ({ sourceData, targetData, dispatch }) => {
265+
handler: ({ sourceData, targetData, dispatch, getState }) => {
266266
if (!singleImageDndSource.typeGuard(sourceData) && !multipleImageDndSource.typeGuard(sourceData)) {
267267
return;
268268
}
@@ -276,7 +276,7 @@ export const addImagesToNodeImageFieldCollectionDndTarget: DndTarget<
276276
imageDTOs.push(...sourceData.payload.imageDTOs);
277277
}
278278

279-
addImagesToNodeImageFieldCollectionAction({ fieldIdentifer, imageDTOs, dispatch });
279+
addImagesToNodeImageFieldCollectionAction({ fieldIdentifer, imageDTOs, dispatch, getState });
280280
},
281281
};
282282
//#endregion

invokeai/frontend/web/src/features/imageActions/actions.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { logger } from 'app/logging/logger';
12
import type { AppDispatch, RootState } from 'app/store/store';
23
import { deepClone } from 'common/util/deepClone';
34
import { selectDefaultIPAdapter } from 'features/controlLayers/hooks/addLayerHooks';
@@ -30,14 +31,18 @@ import { calculateNewSize } from 'features/controlLayers/util/getScaledBoundingB
3031
import { imageToCompareChanged, selectionChanged } from 'features/gallery/store/gallerySlice';
3132
import type { BoardId } from 'features/gallery/store/types';
3233
import { fieldImageCollectionValueChanged, fieldImageValueChanged } from 'features/nodes/store/nodesSlice';
33-
import type { FieldIdentifier } from 'features/nodes/types/field';
34+
import { selectFieldInputInstance, selectNodesSlice } from 'features/nodes/store/selectors';
35+
import { type FieldIdentifier, isImageFieldCollectionInputInstance } from 'features/nodes/types/field';
3436
import { upscaleInitialImageChanged } from 'features/parameters/store/upscaleSlice';
3537
import { getOptimalDimension } from 'features/parameters/util/optimalDimension';
38+
import { uniqBy } from 'lodash-es';
3639
import { imagesApi } from 'services/api/endpoints/images';
3740
import type { ImageDTO } from 'services/api/types';
3841
import type { Equals } from 'tsafe';
3942
import { assert } from 'tsafe';
4043

44+
const log = logger('system');
45+
4146
export const setGlobalReferenceImage = (arg: {
4247
imageDTO: ImageDTO;
4348
entityIdentifier: CanvasEntityIdentifier<'reference_image'>;
@@ -75,9 +80,24 @@ export const addImagesToNodeImageFieldCollectionAction = (arg: {
7580
imageDTOs: ImageDTO[];
7681
fieldIdentifer: FieldIdentifier;
7782
dispatch: AppDispatch;
83+
getState: () => RootState;
7884
}) => {
79-
const { imageDTOs, fieldIdentifer, dispatch } = arg;
80-
dispatch(fieldImageCollectionValueChanged({ ...fieldIdentifer, value: imageDTOs }));
85+
const { imageDTOs, fieldIdentifer, dispatch, getState } = arg;
86+
const fieldInputInstance = selectFieldInputInstance(
87+
selectNodesSlice(getState()),
88+
fieldIdentifer.nodeId,
89+
fieldIdentifer.fieldName
90+
);
91+
92+
if (!isImageFieldCollectionInputInstance(fieldInputInstance)) {
93+
log.warn({ fieldIdentifer }, 'Attempted to add images to a non-image field collection');
94+
return;
95+
}
96+
97+
const images = fieldInputInstance.value ? [...fieldInputInstance.value] : [];
98+
images.push(...imageDTOs.map(({ image_name }) => ({ image_name })));
99+
const uniqueImages = uniqBy(images, 'image_name');
100+
dispatch(fieldImageCollectionValueChanged({ ...fieldIdentifer, value: uniqueImages }));
81101
};
82102

83103
export const setComparisonImage = (arg: { imageDTO: ImageDTO; dispatch: AppDispatch }) => {

0 commit comments

Comments
 (0)