From f61af188f94bb5a57a53591d5b1e489e8ac83b8d Mon Sep 17 00:00:00 2001
From: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date: Tue, 6 Aug 2024 18:00:19 +1000
Subject: [PATCH] tidy(ui): remove unused code, initial image
---
.../middleware/listenerMiddleware/index.ts | 2 -
.../listeners/canvasSessionRequested.ts | 29 --
.../components/CanvasEntityList.tsx | 7 +-
.../components/ControlLayersToolbar.tsx | 4 +-
.../components/InitialImage/InitialImage.tsx | 25 --
.../InitialImage/InitialImageActionsMenu.tsx | 0
.../InitialImage/InitialImageHeader.tsx | 34 --
.../InitialImage/InitialImagePreview.tsx | 100 ------
.../InitialImage/InitialImageSettings.tsx | 13 -
.../components/NewSessionButton.tsx | 15 -
.../controlLayers/konva/CanvasInitialImage.ts | 65 ----
.../controlLayers/konva/CanvasManager.ts | 47 +--
.../controlLayers/konva/CanvasRegion.ts | 292 ------------------
.../controlLayers/konva/CanvasStateApi.ts | 3 -
.../controlLayers/konva/entityBbox.ts | 250 ---------------
.../controlLayers/store/canvasV2Slice.ts | 18 --
.../store/initialImageReducers.ts | 38 ---
.../controlLayers/store/sessionReducers.ts | 4 -
.../src/features/controlLayers/store/types.ts | 24 +-
19 files changed, 10 insertions(+), 960 deletions(-)
delete mode 100644 invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasSessionRequested.ts
delete mode 100644 invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImage.tsx
delete mode 100644 invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImageActionsMenu.tsx
delete mode 100644 invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImageHeader.tsx
delete mode 100644 invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImagePreview.tsx
delete mode 100644 invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImageSettings.tsx
delete mode 100644 invokeai/frontend/web/src/features/controlLayers/components/NewSessionButton.tsx
delete mode 100644 invokeai/frontend/web/src/features/controlLayers/konva/CanvasInitialImage.ts
delete mode 100644 invokeai/frontend/web/src/features/controlLayers/konva/CanvasRegion.ts
delete mode 100644 invokeai/frontend/web/src/features/controlLayers/konva/entityBbox.ts
delete mode 100644 invokeai/frontend/web/src/features/controlLayers/store/initialImageReducers.ts
diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts
index 79b90776b8..29df0bf542 100644
--- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts
+++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts
@@ -9,7 +9,6 @@ import { addBatchEnqueuedListener } from 'app/store/middleware/listenerMiddlewar
import { addDeleteBoardAndImagesFulfilledListener } from 'app/store/middleware/listenerMiddleware/listeners/boardAndImagesDeleted';
import { addBoardIdSelectedListener } from 'app/store/middleware/listenerMiddleware/listeners/boardIdSelected';
import { addBulkDownloadListeners } from 'app/store/middleware/listenerMiddleware/listeners/bulkDownload';
-import { addCanvasSessionRequestedListener } from 'app/store/middleware/listenerMiddleware/listeners/canvasSessionRequested';
import { addControlAdapterPreprocessor } from 'app/store/middleware/listenerMiddleware/listeners/controlAdapterPreprocessor';
import { addEnqueueRequestedLinear } from 'app/store/middleware/listenerMiddleware/listeners/enqueueRequestedLinear';
import { addEnqueueRequestedNodes } from 'app/store/middleware/listenerMiddleware/listeners/enqueueRequestedNodes';
@@ -90,7 +89,6 @@ addBatchEnqueuedListener(startAppListening);
// addStagingAreaImageSavedListener(startAppListening);
// addCommitStagingAreaImageListener(startAppListening);
addStagingListeners(startAppListening);
-addCanvasSessionRequestedListener(startAppListening);
// Socket.IO
addGeneratorProgressEventListener(startAppListening);
diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasSessionRequested.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasSessionRequested.ts
deleted file mode 100644
index 0e1c92dcff..0000000000
--- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/canvasSessionRequested.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
-import {
- layerAdded,
- layerImageAdded,
- sessionRequested,
- sessionStarted,
-} from 'features/controlLayers/store/canvasV2Slice';
-import { getImageDTO } from 'services/api/endpoints/images';
-import { assert } from 'tsafe';
-
-export const addCanvasSessionRequestedListener = (startAppListening: AppStartListening) => {
- startAppListening({
- actionCreator: sessionRequested,
- effect: async (action, { getState, dispatch }) => {
- const initialImageObject = getState().canvasV2.initialImage.imageObject;
- if (initialImageObject) {
- // We have an initial image that needs to be converted to a layer
- dispatch(layerAdded());
- const newLayer = getState().canvasV2.layers.entities[0];
- assert(newLayer, 'Expected new layer to be created');
- const imageDTO = await getImageDTO(initialImageObject.image.name);
- assert(imageDTO, 'Unable to fetch initial image DTO');
- dispatch(layerImageAdded({ id: newLayer.id, imageDTO }));
- }
-
- dispatch(sessionStarted());
- },
- });
-};
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/CanvasEntityList.tsx b/invokeai/frontend/web/src/features/controlLayers/components/CanvasEntityList.tsx
index d9d0255d14..e76b6ab3ed 100644
--- a/invokeai/frontend/web/src/features/controlLayers/components/CanvasEntityList.tsx
+++ b/invokeai/frontend/web/src/features/controlLayers/components/CanvasEntityList.tsx
@@ -1,9 +1,7 @@
/* eslint-disable i18next/no-literal-string */
import { Flex } from '@invoke-ai/ui-library';
-import { useAppSelector } from 'app/store/storeHooks';
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
import { CAEntityList } from 'features/controlLayers/components/ControlAdapter/CAEntityList';
-import { InitialImage } from 'features/controlLayers/components/InitialImage/InitialImage';
import { IM } from 'features/controlLayers/components/InpaintMask/IM';
import { IPAEntityList } from 'features/controlLayers/components/IPAdapter/IPAEntityList';
import { LayerEntityList } from 'features/controlLayers/components/Layer/LayerEntityList';
@@ -11,17 +9,14 @@ import { RGEntityList } from 'features/controlLayers/components/RegionalGuidance
import { memo } from 'react';
export const CanvasEntityList = memo(() => {
- const isCanvasSessionActive = useAppSelector((s) => s.canvasV2.session.isActive);
-
return (
- {isCanvasSessionActive && }
+
- {!isCanvasSessionActive && }
);
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/ControlLayersToolbar.tsx b/invokeai/frontend/web/src/features/controlLayers/components/ControlLayersToolbar.tsx
index 05a7ae638f..1b8d52585e 100644
--- a/invokeai/frontend/web/src/features/controlLayers/components/ControlLayersToolbar.tsx
+++ b/invokeai/frontend/web/src/features/controlLayers/components/ControlLayersToolbar.tsx
@@ -7,7 +7,6 @@ import { BrushWidth } from 'features/controlLayers/components/BrushWidth';
import ControlLayersSettingsPopover from 'features/controlLayers/components/ControlLayersSettingsPopover';
import { EraserWidth } from 'features/controlLayers/components/EraserWidth';
import { FillColorPicker } from 'features/controlLayers/components/FillColorPicker';
-import { NewSessionButton } from 'features/controlLayers/components/NewSessionButton';
import { ResetCanvasButton } from 'features/controlLayers/components/ResetCanvasButton';
import { ToolChooser } from 'features/controlLayers/components/ToolChooser';
import { UndoRedoButtonGroup } from 'features/controlLayers/components/UndoRedoButtonGroup';
@@ -25,7 +24,7 @@ export const ControlLayersToolbar = memo(() => {
return;
}
for (const l of canvasManager.layers.values()) {
- l.calculateBbox();
+ l.transformer.requestRectCalculation();
}
}, [canvasManager]);
const onChangeDebugging = useCallback(
@@ -61,7 +60,6 @@ export const ControlLayersToolbar = memo(() => {
-
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImage.tsx b/invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImage.tsx
deleted file mode 100644
index 00fdc673c0..0000000000
--- a/invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImage.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { useDisclosure } from '@invoke-ai/ui-library';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import { CanvasEntityContainer } from 'features/controlLayers/components/common/CanvasEntityContainer';
-import { InitialImageHeader } from 'features/controlLayers/components/InitialImage/InitialImageHeader';
-import { InitialImageSettings } from 'features/controlLayers/components/InitialImage/InitialImageSettings';
-import { entitySelected } from 'features/controlLayers/store/canvasV2Slice';
-import { memo, useCallback } from 'react';
-
-export const InitialImage = memo(() => {
- const dispatch = useAppDispatch();
- const isSelected = useAppSelector((s) => s.canvasV2.selectedEntityIdentifier?.id === 'initial_image');
- const { isOpen, onToggle } = useDisclosure({ defaultIsOpen: true });
- const onSelect = useCallback(() => {
- dispatch(entitySelected({ id: 'initial_image', type: 'initial_image' }));
- }, [dispatch]);
-
- return (
-
-
- {isOpen && }
-
- );
-});
-
-InitialImage.displayName = 'InitialImage';
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImageActionsMenu.tsx b/invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImageActionsMenu.tsx
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImageHeader.tsx b/invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImageHeader.tsx
deleted file mode 100644
index 8af3e98f40..0000000000
--- a/invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImageHeader.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Spacer } from '@invoke-ai/ui-library';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import { CanvasEntityEnabledToggle } from 'features/controlLayers/components/common/CanvasEntityEnabledToggle';
-import { CanvasEntityHeader } from 'features/controlLayers/components/common/CanvasEntityHeader';
-import { CanvasEntityTitle } from 'features/controlLayers/components/common/CanvasEntityTitle';
-import { iiIsEnabledToggled } from 'features/controlLayers/store/canvasV2Slice';
-import { memo, useCallback, useMemo } from 'react';
-import { useTranslation } from 'react-i18next';
-
-type Props = {
- onToggleVisibility: () => void;
-};
-
-export const InitialImageHeader = memo(({ onToggleVisibility }: Props) => {
- const { t } = useTranslation();
- const dispatch = useAppDispatch();
- const isEnabled = useAppSelector((s) => s.canvasV2.initialImage.isEnabled);
- const onToggleIsEnabled = useCallback(() => {
- dispatch(iiIsEnabledToggled());
- }, [dispatch]);
- const title = useMemo(() => {
- return `${t('controlLayers.initialImage')}`;
- }, [t]);
-
- return (
-
-
-
-
-
- );
-});
-
-InitialImageHeader.displayName = 'InitialImageHeader';
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImagePreview.tsx b/invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImagePreview.tsx
deleted file mode 100644
index dca1a155fa..0000000000
--- a/invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImagePreview.tsx
+++ /dev/null
@@ -1,100 +0,0 @@
-import { Flex, useShiftModifier } from '@invoke-ai/ui-library';
-import { skipToken } from '@reduxjs/toolkit/query';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAIDndImage from 'common/components/IAIDndImage';
-import IAIDndImageIcon from 'common/components/IAIDndImageIcon';
-import { bboxHeightChanged, bboxWidthChanged, iiReset } from 'features/controlLayers/store/canvasV2Slice';
-import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
-import type { ImageDraggableData, InitialImageDropData } from 'features/dnd/types';
-import { calculateNewSize } from 'features/parameters/components/DocumentSize/calculateNewSize';
-import { memo, useCallback, useEffect, useMemo } from 'react';
-import { useTranslation } from 'react-i18next';
-import { PiArrowCounterClockwiseBold, PiRulerBold } from 'react-icons/pi';
-import { useGetImageDTOQuery } from 'services/api/endpoints/images';
-
-export const InitialImagePreview = memo(() => {
- const { t } = useTranslation();
- const dispatch = useAppDispatch();
- const initialImage = useAppSelector((s) => s.canvasV2.initialImage);
- const isConnected = useAppSelector((s) => s.system.isConnected);
- const optimalDimension = useAppSelector(selectOptimalDimension);
- const shift = useShiftModifier();
-
- const { currentData: imageDTO, isError: isErrorControlImage } = useGetImageDTOQuery(
- initialImage.imageObject?.image.name ?? skipToken
- );
-
- const onReset = useCallback(() => {
- dispatch(iiReset());
- }, [dispatch]);
-
- const onUseSize = useCallback(() => {
- if (!imageDTO) {
- return;
- }
-
- const options = { updateAspectRatio: true, clamp: true };
- if (shift) {
- const { width, height } = imageDTO;
- dispatch(bboxWidthChanged({ width, ...options }));
- dispatch(bboxHeightChanged({ height, ...options }));
- } else {
- const { width, height } = calculateNewSize(imageDTO.width / imageDTO.height, optimalDimension * optimalDimension);
- dispatch(bboxWidthChanged({ width, ...options }));
- dispatch(bboxHeightChanged({ height, ...options }));
- }
- }, [imageDTO, dispatch, optimalDimension, shift]);
-
- const draggableData = useMemo(() => {
- if (imageDTO) {
- return {
- id: 'initial_image',
- payloadType: 'IMAGE_DTO',
- payload: { imageDTO },
- };
- }
- }, [imageDTO]);
-
- const droppableData = useMemo(
- () => ({ id: 'initial_image', actionType: 'SET_INITIAL_IMAGE' }),
- []
- );
-
- useEffect(() => {
- if (isConnected && isErrorControlImage) {
- onReset();
- }
- }, [onReset, isConnected, isErrorControlImage]);
-
- return (
-
-
-
-
- {imageDTO && (
-
- }
- tooltip={t('controlnet.resetControlImage')}
- />
- }
- tooltip={
- shift ? t('controlnet.setControlImageDimensionsForce') : t('controlnet.setControlImageDimensions')
- }
- />
-
- )}
-
-
- );
-});
-
-InitialImagePreview.displayName = 'InitialImagePreview';
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImageSettings.tsx b/invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImageSettings.tsx
deleted file mode 100644
index 9c9da2f536..0000000000
--- a/invokeai/frontend/web/src/features/controlLayers/components/InitialImage/InitialImageSettings.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import { CanvasEntitySettings } from 'features/controlLayers/components/common/CanvasEntitySettings';
-import { InitialImagePreview } from 'features/controlLayers/components/InitialImage/InitialImagePreview';
-import { memo } from 'react';
-
-export const InitialImageSettings = memo(() => {
- return (
-
-
-
- );
-});
-
-InitialImageSettings.displayName = 'InitialImageSettings';
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/NewSessionButton.tsx b/invokeai/frontend/web/src/features/controlLayers/components/NewSessionButton.tsx
deleted file mode 100644
index a04ce3089b..0000000000
--- a/invokeai/frontend/web/src/features/controlLayers/components/NewSessionButton.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Button } from '@invoke-ai/ui-library';
-import { useAppDispatch } from 'app/store/storeHooks';
-import { sessionRequested } from 'features/controlLayers/store/canvasV2Slice';
-import { memo, useCallback } from 'react';
-
-export const NewSessionButton = memo(() => {
- const dispatch = useAppDispatch();
- const onClick = useCallback(() => {
- dispatch(sessionRequested());
- }, [dispatch]);
-
- return ;
-});
-
-NewSessionButton.displayName = 'NewSessionButton';
diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasInitialImage.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasInitialImage.ts
deleted file mode 100644
index 52bb4a398a..0000000000
--- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasInitialImage.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { CanvasImageRenderer } from 'features/controlLayers/konva/CanvasImage';
-import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
-import type { InitialImageEntity } from 'features/controlLayers/store/types';
-import Konva from 'konva';
-
-export class CanvasInitialImage {
- static NAME_PREFIX = 'initial-image';
- static LAYER_NAME = `${CanvasInitialImage.NAME_PREFIX}_layer`;
- static GROUP_NAME = `${CanvasInitialImage.NAME_PREFIX}_group`;
- static OBJECT_GROUP_NAME = `${CanvasInitialImage.NAME_PREFIX}_object-group`;
-
- private state: InitialImageEntity;
-
- id = 'initial_image';
- manager: CanvasManager;
-
- konva: {
- layer: Konva.Layer;
- group: Konva.Group;
- objectGroup: Konva.Group;
- };
-
- image: CanvasImageRenderer | null;
-
- constructor(state: InitialImageEntity, manager: CanvasManager) {
- this.manager = manager;
- this.konva = {
- layer: new Konva.Layer({ name: CanvasInitialImage.LAYER_NAME, imageSmoothingEnabled: true, listening: false }),
- group: new Konva.Group({ name: CanvasInitialImage.GROUP_NAME, listening: false }),
- objectGroup: new Konva.Group({ name: CanvasInitialImage.OBJECT_GROUP_NAME, listening: false }),
- };
- this.konva.group.add(this.konva.objectGroup);
- this.konva.layer.add(this.konva.group);
-
- this.image = null;
- this.state = state;
- }
-
- async render(state: InitialImageEntity) {
- this.state = state;
-
- if (!this.state.imageObject) {
- this.konva.layer.visible(false);
- return;
- }
-
- if (!this.image) {
- this.image = new CanvasImageRenderer(this.state.imageObject);
- this.konva.objectGroup.add(this.image.konva.group);
- await this.image.update(this.state.imageObject, true);
- } else if (!this.image.isLoading && !this.image.isError) {
- await this.image.update(this.state.imageObject);
- }
-
- if (this.state && this.state.isEnabled && !this.image?.isLoading && !this.image?.isError) {
- this.konva.layer.visible(true);
- } else {
- this.konva.layer.visible(false);
- }
- }
-
- destroy(): void {
- this.konva.layer.destroy();
- }
-}
diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasManager.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasManager.ts
index 6cac07952c..d16f7997e7 100644
--- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasManager.ts
+++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasManager.ts
@@ -6,7 +6,6 @@ import { PubSub } from 'common/util/PubSub/PubSub';
import type { CanvasBrushLineRenderer } from 'features/controlLayers/konva/CanvasBrushLine';
import type { CanvasEraserLineRenderer } from 'features/controlLayers/konva/CanvasEraserLine';
import type { CanvasImageRenderer } from 'features/controlLayers/konva/CanvasImage';
-import { CanvasInitialImage } from 'features/controlLayers/konva/CanvasInitialImage';
import { CanvasObjectRenderer } from 'features/controlLayers/konva/CanvasObjectRenderer';
import { CanvasProgressPreview } from 'features/controlLayers/konva/CanvasProgressPreview';
import type { CanvasRectRenderer } from 'features/controlLayers/konva/CanvasRect';
@@ -15,7 +14,6 @@ import {
getCompositeLayerImage,
getControlAdapterImage,
getGenerationMode,
- getInitialImage,
getInpaintMaskImage,
getPrefixedId,
getRegionMaskImage,
@@ -48,7 +46,6 @@ import { CanvasControlAdapter } from './CanvasControlAdapter';
import { CanvasLayerAdapter } from './CanvasLayerAdapter';
import { CanvasMaskAdapter } from './CanvasMaskAdapter';
import { CanvasPreview } from './CanvasPreview';
-import type { CanvasRegion } from './CanvasRegion';
import { CanvasStagingArea } from './CanvasStagingArea';
import { CanvasStateApi } from './CanvasStateApi';
import { CanvasTool } from './CanvasTool';
@@ -120,7 +117,6 @@ export class CanvasManager {
layers: Map;
regions: Map;
inpaintMask: CanvasMaskAdapter;
- initialImage: CanvasInitialImage;
util: Util;
stateApi: CanvasStateApi;
preview: CanvasPreview;
@@ -188,9 +184,6 @@ export class CanvasManager {
this.regions = new Map();
this.controlAdapters = new Map();
- this.initialImage = new CanvasInitialImage(this.stateApi.getInitialImageState(), this);
- this.stage.add(this.initialImage.konva.layer);
-
this._worker.onmessage = (event: MessageEvent) => {
const { type, data } = event.data;
if (type === 'log') {
@@ -250,10 +243,6 @@ export class CanvasManager {
this._worker.postMessage(task, [data.buffer]);
}
- async renderInitialImage() {
- await this.initialImage.render(this.stateApi.getInitialImageState());
- }
-
async renderProgressPreview() {
await this.preview.progressPreview.render(this.stateApi.$lastProgressEvent.get());
}
@@ -286,7 +275,6 @@ export class CanvasManager {
const regions = getRegionsState().entities;
let zIndex = 0;
this.background.konva.layer.zIndex(++zIndex);
- this.initialImage.konva.layer.zIndex(++zIndex);
for (const layer of layers) {
this.layers.get(layer.id)?.konva.layer.zIndex(++zIndex);
}
@@ -322,7 +310,7 @@ export class CanvasManager {
| CanvasRegionalGuidanceState
| CanvasInpaintMaskState
| null = null;
- let entityAdapter: CanvasLayerAdapter | CanvasControlAdapter | CanvasRegion | CanvasMaskAdapter | null = null;
+ let entityAdapter: CanvasLayerAdapter | CanvasControlAdapter | CanvasMaskAdapter | null = null;
if (identifier.type === 'layer') {
entityState = state.layers.entities.find((i) => i.id === identifier.id) ?? null;
@@ -470,17 +458,6 @@ export class CanvasManager {
}
}
- if (
- this._isFirstRender ||
- state.initialImage !== this._prevState.initialImage ||
- state.bbox.rect !== this._prevState.bbox.rect ||
- state.tool.selected !== this._prevState.tool.selected ||
- state.selectedEntityIdentifier?.id !== this._prevState.selectedEntityIdentifier?.id
- ) {
- this.log.debug('Rendering initial image');
- await this.renderInitialImage();
- }
-
if (
this._isFirstRender ||
state.regions.entities !== this._prevState.regions.entities ||
@@ -546,8 +523,7 @@ export class CanvasManager {
if (
this._isFirstRender ||
state.bbox !== this._prevState.bbox ||
- state.tool.selected !== this._prevState.tool.selected ||
- state.session.isActive !== this._prevState.session.isActive
+ state.tool.selected !== this._prevState.tool.selected
) {
this.log.debug('Rendering generation bbox');
await this.preview.bbox.render();
@@ -656,18 +632,7 @@ export class CanvasManager {
}
getGenerationMode(): GenerationMode {
- const session = this.stateApi.getSession();
- if (session.isActive) {
- return getGenerationMode({ manager: this });
- }
-
- const initialImageState = this.stateApi.getInitialImageState();
-
- if (initialImageState.imageObject && initialImageState.isEnabled) {
- return 'img2img';
- }
-
- return 'txt2img';
+ return getGenerationMode({ manager: this });
}
getControlAdapterImage(arg: Omit[0], 'manager'>) {
@@ -683,11 +648,7 @@ export class CanvasManager {
}
getInitialImage(arg: Omit[0], 'manager'>) {
- if (this.stateApi.getSession().isActive) {
- return getCompositeLayerImage({ ...arg, manager: this });
- } else {
- return getInitialImage({ ...arg, manager: this });
- }
+ return getCompositeLayerImage({ ...arg, manager: this });
}
getLoggingContext() {
diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasRegion.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasRegion.ts
deleted file mode 100644
index 74a0cdd6de..0000000000
--- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasRegion.ts
+++ /dev/null
@@ -1,292 +0,0 @@
-import { rgbColorToString } from 'common/util/colorCodeTransformers';
-import { CanvasBrushLineRenderer } from 'features/controlLayers/konva/CanvasBrushLine';
-import { CanvasEraserLineRenderer } from 'features/controlLayers/konva/CanvasEraserLine';
-import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
-import { CanvasRectRenderer } from 'features/controlLayers/konva/CanvasRect';
-import { getNodeBboxFast } from 'features/controlLayers/konva/entityBbox';
-import { mapId } from 'features/controlLayers/konva/util';
-import type {
- CanvasBrushLineState,
- CanvasEraserLineState,
- CanvasRectState,
- CanvasRegionalGuidanceState,
-} from 'features/controlLayers/store/types';
-import { isDrawingTool, RGBA_RED } from 'features/controlLayers/store/types';
-import Konva from 'konva';
-import { assert } from 'tsafe';
-
-export class CanvasRegion {
- static NAME_PREFIX = 'region';
- static LAYER_NAME = `${CanvasRegion.NAME_PREFIX}_layer`;
- static TRANSFORMER_NAME = `${CanvasRegion.NAME_PREFIX}_transformer`;
- static GROUP_NAME = `${CanvasRegion.NAME_PREFIX}_group`;
- static OBJECT_GROUP_NAME = `${CanvasRegion.NAME_PREFIX}_object-group`;
- static COMPOSITING_RECT_NAME = `${CanvasRegion.NAME_PREFIX}_compositing-rect`;
- static TYPE = 'regional_guidance' as const;
-
- private drawingBuffer: CanvasBrushLineState | CanvasEraserLineState | CanvasRectState | null;
- private state: CanvasRegionalGuidanceState;
-
- id: string;
- type = CanvasRegion.TYPE;
- manager: CanvasManager;
-
- konva: {
- layer: Konva.Layer;
- group: Konva.Group;
- objectGroup: Konva.Group;
- compositingRect: Konva.Rect;
- transformer: Konva.Transformer;
- };
-
- objects: Map;
-
- constructor(state: CanvasRegionalGuidanceState, manager: CanvasManager) {
- this.id = state.id;
- this.manager = manager;
-
- this.konva = {
- layer: new Konva.Layer({ name: CanvasRegion.LAYER_NAME, listening: false }),
- group: new Konva.Group({ name: CanvasRegion.GROUP_NAME, listening: false }),
- objectGroup: new Konva.Group({ name: CanvasRegion.OBJECT_GROUP_NAME, listening: false }),
- transformer: new Konva.Transformer({
- name: CanvasRegion.TRANSFORMER_NAME,
- shouldOverdrawWholeArea: true,
- draggable: true,
- dragDistance: 0,
- enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right'],
- rotateEnabled: false,
- flipEnabled: false,
- }),
- compositingRect: new Konva.Rect({ name: CanvasRegion.COMPOSITING_RECT_NAME, listening: false }),
- };
- this.konva.group.add(this.konva.objectGroup);
- this.konva.layer.add(this.konva.group);
- this.konva.transformer.on('transformend', () => {
- this.manager.stateApi.onScaleChanged(
- {
- id: this.id,
- scale: this.konva.group.scaleX(),
- position: { x: this.konva.group.x(), y: this.konva.group.y() },
- },
- 'regional_guidance'
- );
- });
- this.konva.transformer.on('dragend', () => {
- this.manager.stateApi.setEntityPosition(
- { id: this.id, position: { x: this.konva.group.x(), y: this.konva.group.y() } },
- 'regional_guidance'
- );
- });
- this.konva.layer.add(this.konva.transformer);
- this.konva.group.add(this.konva.compositingRect);
- this.objects = new Map();
- this.drawingBuffer = null;
- this.state = state;
- }
-
- destroy(): void {
- this.konva.layer.destroy();
- }
-
- getDrawingBuffer() {
- return this.drawingBuffer;
- }
-
- async setDrawingBuffer(obj: CanvasBrushLineState | CanvasEraserLineState | CanvasRectState | null) {
- this.drawingBuffer = obj;
- if (this.drawingBuffer) {
- if (this.drawingBuffer.type === 'brush_line') {
- this.drawingBuffer.color = RGBA_RED;
- } else if (this.drawingBuffer.type === 'rect') {
- this.drawingBuffer.color = RGBA_RED;
- }
-
- await this.renderObject(this.drawingBuffer, true);
- this.updateGroup(true);
- }
- }
-
- finalizeDrawingBuffer() {
- if (!this.drawingBuffer) {
- return;
- }
- if (this.drawingBuffer.type === 'brush_line') {
- this.manager.stateApi.addBrushLine({ id: this.id, brushLine: this.drawingBuffer }, 'regional_guidance');
- } else if (this.drawingBuffer.type === 'eraser_line') {
- this.manager.stateApi.addEraserLine({ id: this.id, eraserLine: this.drawingBuffer }, 'regional_guidance');
- } else if (this.drawingBuffer.type === 'rect') {
- this.manager.stateApi.addRect({ id: this.id, rect: this.drawingBuffer }, 'regional_guidance');
- }
- this.setDrawingBuffer(null);
- }
-
- async render(state: CanvasRegionalGuidanceState) {
- this.state = state;
-
- // Update the layer's position and listening state
- this.konva.group.setAttrs({
- x: state.position.x,
- y: state.position.y,
- scaleX: 1,
- scaleY: 1,
- });
-
- let didDraw = false;
-
- const objectIds = state.objects.map(mapId);
- // Destroy any objects that are no longer in state
- for (const object of this.objects.values()) {
- if (!objectIds.includes(object.id)) {
- this.objects.delete(object.id);
- object.destroy();
- didDraw = true;
- }
- }
-
- for (const obj of state.objects) {
- if (await this.renderObject(obj)) {
- didDraw = true;
- }
- }
-
- if (this.drawingBuffer) {
- if (await this.renderObject(this.drawingBuffer)) {
- didDraw = true;
- }
- }
-
- this.updateGroup(didDraw);
- }
-
- private async renderObject(obj: CanvasRegionalGuidanceState['objects'][number], force = false): Promise {
- if (obj.type === 'brush_line') {
- let brushLine = this.objects.get(obj.id);
- assert(brushLine instanceof CanvasBrushLineRenderer || brushLine === undefined);
-
- if (!brushLine) {
- brushLine = new CanvasBrushLineRenderer(obj);
- this.objects.set(brushLine.id, brushLine);
- this.konva.objectGroup.add(brushLine.konva.group);
- return true;
- } else {
- if (brushLine.update(obj, force)) {
- return true;
- }
- }
- } else if (obj.type === 'eraser_line') {
- let eraserLine = this.objects.get(obj.id);
- assert(eraserLine instanceof CanvasEraserLineRenderer || eraserLine === undefined);
-
- if (!eraserLine) {
- eraserLine = new CanvasEraserLineRenderer(obj);
- this.objects.set(eraserLine.id, eraserLine);
- this.konva.objectGroup.add(eraserLine.konva.group);
- return true;
- } else {
- if (eraserLine.update(obj, force)) {
- return true;
- }
- }
- } else if (obj.type === 'rect') {
- let rect = this.objects.get(obj.id);
- assert(rect instanceof CanvasRectRenderer || rect === undefined);
-
- if (!rect) {
- rect = new CanvasRectRenderer(obj);
- this.objects.set(rect.id, rect);
- this.konva.objectGroup.add(rect.konva.group);
- return true;
- } else {
- if (rect.update(obj, force)) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- updateGroup(didDraw: boolean) {
- this.konva.layer.visible(this.state.isEnabled);
-
- // The user is allowed to reduce mask opacity to 0, but we need the opacity for the compositing rect to work
- this.konva.group.opacity(1);
-
- if (didDraw) {
- // Convert the color to a string, stripping the alpha - the object group will handle opacity.
- const rgbColor = rgbColorToString(this.state.fill);
- const maskOpacity = this.manager.stateApi.getMaskOpacity();
- this.konva.compositingRect.setAttrs({
- // The rect should be the size of the layer - use the fast method if we don't have a pixel-perfect bbox already
- ...getNodeBboxFast(this.konva.objectGroup),
- fill: rgbColor,
- opacity: maskOpacity,
- // Draw this rect only where there are non-transparent pixels under it (e.g. the mask shapes)
- globalCompositeOperation: 'source-in',
- // This rect must always be on top of all other shapes
- zIndex: this.objects.size + 1,
- });
- }
-
- const isSelected = this.manager.stateApi.getIsSelected(this.id);
- const selectedTool = this.manager.stateApi.getToolState().selected;
-
- if (this.objects.size === 0) {
- // If the layer is totally empty, reset the cache and bail out.
- this.konva.layer.listening(false);
- this.konva.transformer.nodes([]);
- if (this.konva.group.isCached()) {
- this.konva.group.clearCache();
- }
- return;
- }
-
- if (isSelected && selectedTool === 'move') {
- // When the layer is selected and being moved, we should always cache it.
- // We should update the cache if we drew to the layer.
- if (!this.konva.group.isCached() || didDraw) {
- this.konva.group.cache();
- }
- // Activate the transformer
- this.konva.layer.listening(true);
- this.konva.transformer.nodes([this.konva.group]);
- this.konva.transformer.forceUpdate();
- return;
- }
-
- if (isSelected && selectedTool !== 'move') {
- // If the layer is selected but not using the move tool, we don't want the layer to be listening.
- this.konva.layer.listening(false);
- // The transformer also does not need to be active.
- this.konva.transformer.nodes([]);
- if (isDrawingTool(selectedTool)) {
- // We are using a drawing tool (brush, eraser, rect). These tools change the layer's rendered appearance, so we
- // should never be cached.
- if (this.konva.group.isCached()) {
- this.konva.group.clearCache();
- }
- } else {
- // We are using a non-drawing tool (move, view, bbox), so we should cache the layer.
- // We should update the cache if we drew to the layer.
- if (!this.konva.group.isCached() || didDraw) {
- this.konva.group.cache();
- }
- }
- return;
- }
-
- if (!isSelected) {
- // Unselected layers should not be listening
- this.konva.layer.listening(false);
- // The transformer also does not need to be active.
- this.konva.transformer.nodes([]);
- // Update the layer's cache if it's not already cached or we drew to it.
- if (!this.konva.group.isCached() || didDraw) {
- this.konva.group.cache();
- }
-
- return;
- }
- }
-}
diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts
index 8f9a664aa1..6d6b236855 100644
--- a/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts
+++ b/invokeai/frontend/web/src/features/controlLayers/konva/CanvasStateApi.ts
@@ -188,9 +188,6 @@ export class CanvasStateApi {
getInpaintMaskState = () => {
return this.getState().inpaintMask;
};
- getInitialImageState = () => {
- return this.getState().initialImage;
- };
getMaskOpacity = () => {
return this.getState().settings.maskOpacity;
};
diff --git a/invokeai/frontend/web/src/features/controlLayers/konva/entityBbox.ts b/invokeai/frontend/web/src/features/controlLayers/konva/entityBbox.ts
deleted file mode 100644
index 8e8763460b..0000000000
--- a/invokeai/frontend/web/src/features/controlLayers/konva/entityBbox.ts
+++ /dev/null
@@ -1,250 +0,0 @@
-import openBase64ImageInTab from 'common/util/openBase64ImageInTab';
-import { getLayerBboxId } from 'features/controlLayers/konva/naming';
-import { imageDataToDataURL } from 'features/controlLayers/konva/util';
-import type {
- BboxChangedArg,
- CanvasControlAdapterState,
- CanvasEntityState,
- CanvasLayerState,
- CanvasRegionalGuidanceState,
-} from 'features/controlLayers/store/types';
-import Konva from 'konva';
-import type { IRect } from 'konva/lib/types';
-import { assert } from 'tsafe';
-
-/**
- * Creates a bounding box rect for a layer.
- * @param entity The layer state for the layer to create the bounding box for
- * @param konvaLayer The konva layer to attach the bounding box to
- */
-export const createBboxRect = (entity: CanvasEntityState, konvaLayer: Konva.Layer): Konva.Rect => {
- const rect = new Konva.Rect({
- id: getLayerBboxId(entity.id),
- name: 'bbox',
- strokeWidth: 1,
- visible: false,
- });
- konvaLayer.add(rect);
- return rect;
-};
-
-/**
- * Logic to create and render bounding boxes for layers.
- * Some utils are included for calculating bounding boxes.
- */
-
-type Extents = {
- minX: number;
- minY: number;
- maxX: number;
- maxY: number;
-};
-
-const GET_CLIENT_RECT_CONFIG = { skipTransform: true };
-
-/**
- * Get the bounding box of an image.
- * @param imageData The ImageData object to get the bounding box of.
- * @returns The minimum and maximum x and y values of the image's bounding box, or null if the image has no pixels.
- */
-export const getImageDataBbox = (imageData: ImageData): Extents | null => {
- const { data, width, height } = imageData;
- let minX = width;
- let minY = height;
- let maxX = -1;
- let maxY = -1;
- let alpha = 0;
- let isEmpty = true;
-
- for (let y = 0; y < height; y++) {
- for (let x = 0; x < width; x++) {
- alpha = data[(y * width + x) * 4 + 3] ?? 0;
- if (alpha > 0) {
- isEmpty = false;
- if (x < minX) {
- minX = x;
- }
- if (x > maxX) {
- maxX = x;
- }
- if (y < minY) {
- minY = y;
- }
- if (y > maxY) {
- maxY = y;
- }
- }
- }
- }
-
- return isEmpty ? null : { minX, minY, maxX: maxX + 1, maxY: maxY + 1 };
-};
-
-/**
- * Clones a regional guidance konva layer onto an offscreen stage/canvas. This allows the pixel data for a given layer
- * to be captured, manipulated or analyzed without interference from other layers.
- * @param layer The konva layer to clone.
- * @param filterChildren A callback to filter out unwanted children
- * @returns The cloned stage and layer.
- */
-const getIsolatedLayerClone = (
- layer: Konva.Layer,
- filterChildren: (node: Konva.Node) => boolean
-): { stageClone: Konva.Stage; layerClone: Konva.Layer } => {
- const stage = layer.getStage();
-
- // Construct an offscreen canvas with the same dimensions as the layer's stage.
- const offscreenStageContainer = document.createElement('div');
- const stageClone = new Konva.Stage({
- container: offscreenStageContainer,
- x: stage.x(),
- y: stage.y(),
- width: stage.width(),
- height: stage.height(),
- });
-
- // Clone the layer and filter out unwanted children.
- const layerClone = layer.clone();
- stageClone.add(layerClone);
-
- for (const child of layerClone.getChildren()) {
- if (filterChildren(child) && child.hasChildren()) {
- // We need to cache the group to ensure it composites out eraser strokes correctly
- child.opacity(1);
- child.cache();
- } else {
- // Filter out unwanted children.
- child.destroy();
- }
- }
-
- return { stageClone, layerClone };
-};
-
-/**
- * Get the bounding box of a regional prompt konva layer. This function has special handling for regional prompt layers.
- * @param layer The konva layer to get the bounding box of.
- * @param preview Whether to open a new tab displaying the rendered layer, which is used to calculate the bbox.
- */
-const getLayerBboxPixels = (
- layer: Konva.Layer,
- filterChildren: (node: Konva.Node) => boolean,
- preview: boolean = false
-): IRect | null => {
- // To calculate the layer's bounding box, we must first export it to a pixel array, then do some math.
- //
- // Though it is relatively fast, we can't use Konva's `getClientRect`. It programmatically determines the rect
- // by calculating the extents of individual shapes from their "vector" shape data.
- //
- // This doesn't work when some shapes are drawn with composite operations that "erase" pixels, like eraser lines.
- // These shapes' extents are still calculated as if they were solid, leading to a bounding box that is too large.
- const { stageClone, layerClone } = getIsolatedLayerClone(layer, filterChildren);
-
- // Get a worst-case rect using the relatively fast `getClientRect`.
- const layerRect = layerClone.getClientRect();
- if (layerRect.width === 0 || layerRect.height === 0) {
- return null;
- }
- // Capture the image data with the above rect.
- const layerImageData = stageClone
- .toCanvas(layerRect)
- .getContext('2d')
- ?.getImageData(0, 0, layerRect.width, layerRect.height);
- assert(layerImageData, "Unable to get layer's image data");
-
- if (preview) {
- openBase64ImageInTab([{ base64: imageDataToDataURL(layerImageData), caption: layer.id() }]);
- }
-
- // Calculate the layer's bounding box.
- const layerBbox = getImageDataBbox(layerImageData);
-
- if (!layerBbox) {
- return null;
- }
-
- // Correct the bounding box to be relative to the layer's position.
- const correctedLayerBbox = {
- x: layerBbox.minX - Math.floor(stageClone.x()) + layerRect.x - Math.floor(layer.x()),
- y: layerBbox.minY - Math.floor(stageClone.y()) + layerRect.y - Math.floor(layer.y()),
- width: layerBbox.maxX - layerBbox.minX,
- height: layerBbox.maxY - layerBbox.minY,
- };
-
- return correctedLayerBbox;
-};
-
-/**
- * Get the bounding box of a konva node. This function is faster than `getLayerBboxPixels` but less accurate. It
- * should only be used when there are no eraser strokes or shapes in the node.
- * @param node The konva node to get the bounding box of.
- * @returns The bounding box of the node.
- */
-export const getNodeBboxFast = (node: Konva.Node): IRect => {
- const bbox = node.getClientRect(GET_CLIENT_RECT_CONFIG);
- return bbox;
-};
-
-// TODO(psyche): fix this
-const filterRGChildren = (node: Konva.Node): boolean => true;
-const filterLayerChildren = (node: Konva.Node): boolean => true;
-const filterCAChildren = (node: Konva.Node): boolean => true;
-
-/**
- * Calculates the bbox of each regional guidance layer. Only calculates if the mask has changed.
- * @param stage The konva stage
- * @param entityStates An array of layers to calculate bboxes for
- * @param onBboxChanged Callback for when the bounding box changes
- */
-export const updateBboxes = (
- stage: Konva.Stage,
- layers: CanvasLayerState[],
- controlAdapters: CanvasControlAdapterState[],
- regions: CanvasRegionalGuidanceState[],
- onBboxChanged: (arg: BboxChangedArg, entityType: CanvasEntityState['type']) => void
-): void => {
- for (const entityState of [...layers, ...controlAdapters, ...regions]) {
- const konvaLayer = stage.findOne(`#${entityState.id}`);
- assert(konvaLayer, `Layer ${entityState.id} not found in stage`);
- // We only need to recalculate the bbox if the layer has changed
- if (entityState.bboxNeedsUpdate) {
- const bboxRect = konvaLayer.findOne('.bbox') ?? createBboxRect(entityState, konvaLayer);
-
- // Hide the bbox while we calculate the new bbox, else the bbox will be included in the calculation
- const visible = bboxRect.visible();
- bboxRect.visible(false);
-
- if (entityState.type === 'layer') {
- if (entityState.objects.length === 0) {
- // No objects - no bbox to calculate
- onBboxChanged({ id: entityState.id, bbox: null }, 'layer');
- } else {
- onBboxChanged({ id: entityState.id, bbox: getLayerBboxPixels(konvaLayer, filterLayerChildren) }, 'layer');
- }
- } else if (entityState.type === 'control_adapter') {
- if (!entityState.imageObject && !entityState.processedImageObject) {
- // No objects - no bbox to calculate
- onBboxChanged({ id: entityState.id, bbox: null }, 'control_adapter');
- } else {
- onBboxChanged(
- { id: entityState.id, bbox: getLayerBboxPixels(konvaLayer, filterCAChildren) },
- 'control_adapter'
- );
- }
- } else if (entityState.type === 'regional_guidance') {
- if (entityState.objects.length === 0) {
- // No objects - no bbox to calculate
- onBboxChanged({ id: entityState.id, bbox: null }, 'regional_guidance');
- } else {
- onBboxChanged(
- { id: entityState.id, bbox: getLayerBboxPixels(konvaLayer, filterRGChildren) },
- 'regional_guidance'
- );
- }
- }
-
- // Restore the visibility of the bbox
- bboxRect.visible(visible);
- }
- }
-};
diff --git a/invokeai/frontend/web/src/features/controlLayers/store/canvasV2Slice.ts b/invokeai/frontend/web/src/features/controlLayers/store/canvasV2Slice.ts
index 6e8fd2e3fb..8252f4627f 100644
--- a/invokeai/frontend/web/src/features/controlLayers/store/canvasV2Slice.ts
+++ b/invokeai/frontend/web/src/features/controlLayers/store/canvasV2Slice.ts
@@ -5,7 +5,6 @@ import { deepClone } from 'common/util/deepClone';
import { bboxReducers } from 'features/controlLayers/store/bboxReducers';
import { compositingReducers } from 'features/controlLayers/store/compositingReducers';
import { controlAdaptersReducers } from 'features/controlLayers/store/controlAdaptersReducers';
-import { initialImageReducers } from 'features/controlLayers/store/initialImageReducers';
import { inpaintMaskReducers } from 'features/controlLayers/store/inpaintMaskReducers';
import { ipAdaptersReducers } from 'features/controlLayers/store/ipAdaptersReducers';
import { layersReducers } from 'features/controlLayers/store/layersReducers';
@@ -33,14 +32,6 @@ const initialState: CanvasV2State = {
ipAdapters: { entities: [] },
regions: { entities: [] },
loras: [],
- initialImage: {
- id: 'initial_image',
- type: 'initial_image',
- bbox: null,
- bboxNeedsUpdate: false,
- isEnabled: true,
- imageObject: null,
- },
inpaintMask: {
id: 'inpaint_mask',
type: 'inpaint_mask',
@@ -125,7 +116,6 @@ const initialState: CanvasV2State = {
refinerStart: 0.8,
},
session: {
- isActive: false,
isStaging: false,
stagedImages: [],
selectedStagedImageIndex: 0,
@@ -148,7 +138,6 @@ export const canvasV2Slice = createSlice({
...bboxReducers,
...inpaintMaskReducers,
...sessionReducers,
- ...initialImageReducers,
entitySelected: (state, action: PayloadAction) => {
state.selectedEntityIdentifier = action.payload;
},
@@ -175,7 +164,6 @@ export const canvasV2Slice = createSlice({
state.session = deepClone(initialState.session);
state.tool = deepClone(initialState.tool);
state.inpaintMask = deepClone(initialState.inpaintMask);
- state.initialImage = deepClone(initialState.initialImage);
},
},
});
@@ -342,18 +330,12 @@ export const {
imRectAdded,
inpaintMaskRasterized,
// Staging
- sessionStarted,
sessionStartedStaging,
sessionImageStaged,
sessionStagedImageDiscarded,
sessionStagingAreaReset,
sessionNextStagedImageSelected,
sessionPrevStagedImageSelected,
- // Initial image
- iiRecalled,
- iiIsEnabledToggled,
- iiReset,
- iiImageChanged,
} = canvasV2Slice.actions;
export const selectCanvasV2Slice = (state: RootState) => state.canvasV2;
diff --git a/invokeai/frontend/web/src/features/controlLayers/store/initialImageReducers.ts b/invokeai/frontend/web/src/features/controlLayers/store/initialImageReducers.ts
deleted file mode 100644
index f50edeefaa..0000000000
--- a/invokeai/frontend/web/src/features/controlLayers/store/initialImageReducers.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import type { PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
-import { isEqual } from 'lodash-es';
-import type { ImageDTO } from 'services/api/types';
-
-import type { CanvasV2State, InitialImageEntity } from './types';
-import { imageDTOToImageObject } from './types';
-
-export const initialImageReducers = {
- iiRecalled: (state, action: PayloadAction<{ data: InitialImageEntity }>) => {
- const { data } = action.payload;
- state.initialImage = data;
- state.selectedEntityIdentifier = { type: 'initial_image', id: 'initial_image' };
- },
- iiIsEnabledToggled: (state) => {
- if (!state.initialImage) {
- return;
- }
- state.initialImage.isEnabled = !state.initialImage.isEnabled;
- },
- iiReset: (state) => {
- state.initialImage.imageObject = null;
- },
- iiImageChanged: (state, action: PayloadAction<{ imageDTO: ImageDTO }>) => {
- const { imageDTO } = action.payload;
- if (!state.initialImage) {
- return;
- }
- const newImageObject = imageDTOToImageObject(imageDTO);
- if (isEqual(newImageObject, state.initialImage.imageObject)) {
- return;
- }
- state.initialImage.bbox = null;
- state.initialImage.bboxNeedsUpdate = true;
- state.initialImage.isEnabled = true;
- state.initialImage.imageObject = newImageObject;
- state.selectedEntityIdentifier = { type: 'initial_image', id: 'initial_image' };
- },
-} satisfies SliceCaseReducers;
diff --git a/invokeai/frontend/web/src/features/controlLayers/store/sessionReducers.ts b/invokeai/frontend/web/src/features/controlLayers/store/sessionReducers.ts
index 03236aeaa2..7b21cb12c6 100644
--- a/invokeai/frontend/web/src/features/controlLayers/store/sessionReducers.ts
+++ b/invokeai/frontend/web/src/features/controlLayers/store/sessionReducers.ts
@@ -2,10 +2,6 @@ import type { PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
import type { CanvasV2State, StagingAreaImage } from 'features/controlLayers/store/types';
export const sessionReducers = {
- sessionStarted: (state) => {
- state.session.isActive = true;
- state.selectedEntityIdentifier = { id: 'inpaint_mask', type: 'inpaint_mask' };
- },
sessionStartedStaging: (state) => {
state.session.isStaging = true;
state.session.selectedStagedImageIndex = 0;
diff --git a/invokeai/frontend/web/src/features/controlLayers/store/types.ts b/invokeai/frontend/web/src/features/controlLayers/store/types.ts
index 993294832a..e1a32fd22e 100644
--- a/invokeai/frontend/web/src/features/controlLayers/store/types.ts
+++ b/invokeai/frontend/web/src/features/controlLayers/store/types.ts
@@ -2,7 +2,6 @@ import type { JSONObject } from 'common/types';
import type { CanvasControlAdapter } from 'features/controlLayers/konva/CanvasControlAdapter';
import { CanvasLayerAdapter } from 'features/controlLayers/konva/CanvasLayerAdapter';
import { CanvasMaskAdapter } from 'features/controlLayers/konva/CanvasMaskAdapter';
-import { CanvasRegion } from 'features/controlLayers/konva/CanvasRegion';
import { getObjectId } from 'features/controlLayers/konva/util';
import { zModelIdentifierField } from 'features/nodes/types/common';
import type { AspectRatioState } from 'features/parameters/components/DocumentSize/types';
@@ -686,16 +685,6 @@ const zCanvasInpaintMaskState = z.object({
});
export type CanvasInpaintMaskState = z.infer;
-const zInitialImageEntity = z.object({
- id: z.literal('initial_image'),
- type: z.literal('initial_image'),
- isEnabled: z.boolean(),
- bbox: zRect.nullable(),
- bboxNeedsUpdate: z.boolean(),
- imageObject: zCanvasImageState.nullable(),
-});
-export type InitialImageEntity = z.infer;
-
const zCanvasControlAdapterStateBase = z.object({
id: zId,
type: z.literal('control_adapter'),
@@ -818,8 +807,7 @@ export type CanvasEntityState =
| CanvasControlAdapterState
| CanvasRegionalGuidanceState
| CanvasInpaintMaskState
- | CanvasIPAdapterState
- | InitialImageEntity;
+ | CanvasIPAdapterState;
export type CanvasEntityIdentifier = Pick;
export type LoRA = {
@@ -847,7 +835,6 @@ export type CanvasV2State = {
ipAdapters: { entities: CanvasIPAdapterState[] };
regions: { entities: CanvasRegionalGuidanceState[] };
loras: LoRA[];
- initialImage: InitialImageEntity;
tool: {
selected: Tool;
selectedBuffer: Tool | null;
@@ -920,7 +907,6 @@ export type CanvasV2State = {
refinerStart: number;
};
session: {
- isActive: boolean;
isStaging: boolean;
stagedImages: StagingAreaImage[];
selectedStagedImageIndex: number;
@@ -969,11 +955,9 @@ export function isDrawableEntity(
}
export function isDrawableEntityAdapter(
- adapter: CanvasLayerAdapter | CanvasRegion | CanvasControlAdapter | CanvasMaskAdapter
-): adapter is CanvasLayerAdapter | CanvasRegion | CanvasMaskAdapter {
- return (
- adapter instanceof CanvasLayerAdapter || adapter instanceof CanvasRegion || adapter instanceof CanvasMaskAdapter
- );
+ adapter: CanvasLayerAdapter | CanvasControlAdapter | CanvasMaskAdapter
+): adapter is CanvasLayerAdapter | CanvasMaskAdapter {
+ return adapter instanceof CanvasLayerAdapter || adapter instanceof CanvasMaskAdapter;
}
export function isDrawableEntityType(