Skip to content

Commit 03b85da

Browse files
author
Attila Cseh
committed
staging area multi-canvas support
1 parent b1ea45d commit 03b85da

File tree

72 files changed

+698
-508
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+698
-508
lines changed

invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/boardAndImagesDeleted.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { AppStartListening } from 'app/store/store';
22
import { selectRefImagesSlice } from 'features/controlLayers/store/refImagesSlice';
3-
import { selectSelectedCanvas } from 'features/controlLayers/store/selectors';
3+
import { selectCanvases } from 'features/controlLayers/store/selectors';
44
import { getImageUsage } from 'features/deleteImageModal/store/state';
55
import { nodeEditorReset } from 'features/nodes/store/nodesSlice';
66
import { selectNodesSlice } from 'features/nodes/store/selectors';
@@ -19,12 +19,12 @@ export const addDeleteBoardAndImagesFulfilledListener = (startAppListening: AppS
1919

2020
const state = getState();
2121
const nodes = selectNodesSlice(state);
22-
const canvas = selectSelectedCanvas(state);
22+
const canvases = selectCanvases(state);
2323
const upscale = selectUpscaleSlice(state);
2424
const refImages = selectRefImagesSlice(state);
2525

2626
deleted_images.forEach((image_name) => {
27-
const imageUsage = getImageUsage(nodes, canvas, upscale, refImages, image_name);
27+
const imageUsage = getImageUsage(nodes, canvases, upscale, refImages, image_name);
2828

2929
if (imageUsage.isNodesImage && !wasNodeEditorReset) {
3030
dispatch(nodeEditorReset());

invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { logger } from 'app/logging/logger';
22
import type { AppStartListening } from 'app/store/store';
33
import { bboxSyncedToOptimalDimension, rgRefImageModelChanged } from 'features/controlLayers/store/canvasSlice';
4-
import { buildSelectIsStaging, selectCanvasSessionId } from 'features/controlLayers/store/canvasStagingAreaSlice';
4+
import {
5+
buildSelectIsStagingBySessionId,
6+
selectSelectedCanvasSessionId,
7+
} from 'features/controlLayers/store/canvasStagingAreaSlice';
58
import { loraIsEnabledChanged } from 'features/controlLayers/store/lorasSlice';
69
import { modelChanged, syncedToOptimalDimension, vaeSelected } from 'features/controlLayers/store/paramsSlice';
710
import { refImageModelChanged, selectReferenceImageEntities } from 'features/controlLayers/store/refImagesSlice';
@@ -159,7 +162,9 @@ export const addModelSelectedListener = (startAppListening: AppStartListening) =
159162
if (modelBase !== state.params.model?.base) {
160163
// Sync generate tab settings whenever the model base changes
161164
dispatch(syncedToOptimalDimension());
162-
const isStaging = buildSelectIsStaging(selectCanvasSessionId(state))(state);
165+
const sessionId = selectSelectedCanvasSessionId(state);
166+
const selectIsStaging = buildSelectIsStagingBySessionId(sessionId);
167+
const isStaging = selectIsStaging(state);
163168
if (!isStaging) {
164169
// Canvas tab only syncs if not staging
165170
dispatch(bboxSyncedToOptimalDimension());

invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/setDefaultSettings.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import type { AppStartListening } from 'app/store/store';
22
import { isNil } from 'es-toolkit';
33
import { bboxHeightChanged, bboxWidthChanged } from 'features/controlLayers/store/canvasSlice';
4-
import { buildSelectIsStaging, selectCanvasSessionId } from 'features/controlLayers/store/canvasStagingAreaSlice';
4+
import {
5+
buildSelectIsStagingBySessionId,
6+
selectSelectedCanvasSessionId,
7+
} from 'features/controlLayers/store/canvasStagingAreaSlice';
58
import {
69
heightChanged,
710
setCfgRescaleMultiplier,
@@ -115,7 +118,9 @@ export const addSetDefaultSettingsListener = (startAppListening: AppStartListeni
115118
}
116119
const setSizeOptions = { updateAspectRatio: true, clamp: true };
117120

118-
const isStaging = buildSelectIsStaging(selectCanvasSessionId(state))(state);
121+
const sessionId = selectSelectedCanvasSessionId(state);
122+
const selectIsStaging = buildSelectIsStagingBySessionId(sessionId);
123+
const isStaging = selectIsStaging(state);
119124

120125
const activeTab = selectActiveTab(getState());
121126
if (activeTab === 'generate') {

invokeai/frontend/web/src/app/store/store.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { merge } from 'es-toolkit';
2222
import { omit, pick } from 'es-toolkit/compat';
2323
import { changeBoardModalSliceConfig } from 'features/changeBoardModal/store/slice';
2424
import { canvasSettingsSliceConfig } from 'features/controlLayers/store/canvasSettingsSlice';
25-
import { canvasSliceConfig, undoableCanvasesReducer } from 'features/controlLayers/store/canvasSlice';
25+
import { canvasSliceConfig, migrateCanvas, undoableCanvasesReducer } from 'features/controlLayers/store/canvasSlice';
2626
import { canvasSessionSliceConfig } from 'features/controlLayers/store/canvasStagingAreaSlice';
2727
import { lorasSliceConfig } from 'features/controlLayers/store/lorasSlice';
2828
import { paramsSliceConfig } from 'features/controlLayers/store/paramsSlice';
@@ -219,8 +219,9 @@ export const createStore = (options?: { persist?: boolean; persistDebounce?: num
219219
// Once-off listener to support waiting for rehydration before rendering the app
220220
startAppListening({
221221
actionCreator: createAction(REMEMBER_REHYDRATED),
222-
effect: (action, { unsubscribe }) => {
222+
effect: (action, { dispatch, unsubscribe }) => {
223223
unsubscribe();
224+
dispatch(migrateCanvas());
224225
options?.onRehydrated?.();
225226
},
226227
});

invokeai/frontend/web/src/common/components/SessionMenuItems.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { MenuItem } from '@invoke-ai/ui-library';
22
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
3-
import { useSelectedCanvasManagerSafe } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
3+
import { useCanvasManagerSafe } from 'features/controlLayers/contexts/CanvasManagerProviderGate';
44
import { allEntitiesDeleted, inpaintMaskAdded } from 'features/controlLayers/store/canvasSlice';
55
import { paramsReset } from 'features/controlLayers/store/paramsSlice';
66
import { selectActiveTab } from 'features/ui/store/uiSelectors';
@@ -12,7 +12,7 @@ export const SessionMenuItems = memo(() => {
1212
const { t } = useTranslation();
1313
const dispatch = useAppDispatch();
1414
const tab = useAppSelector(selectActiveTab);
15-
const canvasManager = useSelectedCanvasManagerSafe();
15+
const canvasManager = useCanvasManagerSafe();
1616

1717
const resetCanvasLayers = useCallback(() => {
1818
dispatch(allEntitiesDeleted());

invokeai/frontend/web/src/features/controlLayers/components/CanvasAlerts/CanvasAlertsPreserveMask.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next';
66

77
export const CanvasAlertsPreserveMask = memo(() => {
88
const { t } = useTranslation();
9-
const preserveMask = useAppSelector(selectPreserveMask);
9+
const preserveMask = useAppSelector((state) => selectPreserveMask(state));
1010

1111
if (!preserveMask) {
1212
return null;

invokeai/frontend/web/src/features/controlLayers/components/CanvasAlerts/CanvasAlertsSaveAllImagesToGallery.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next';
66

77
export const CanvasAlertsSaveAllImagesToGallery = memo(() => {
88
const { t } = useTranslation();
9-
const saveAllImagesToGallery = useAppSelector(selectSaveAllImagesToGallery);
9+
const saveAllImagesToGallery = useAppSelector((state) => selectSaveAllImagesToGallery(state));
1010

1111
if (!saveAllImagesToGallery) {
1212
return null;

invokeai/frontend/web/src/features/controlLayers/components/CanvasAutoProcessSwitch.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next';
77
export const CanvasAutoProcessSwitch = memo(() => {
88
const { t } = useTranslation();
99
const dispatch = useAppDispatch();
10-
const autoProcess = useAppSelector(selectAutoProcess);
10+
const autoProcess = useAppSelector((state) => selectAutoProcess(state));
1111

1212
const onChange = useCallback(() => {
1313
dispatch(settingsAutoProcessToggled());

invokeai/frontend/web/src/features/controlLayers/components/CanvasOperationIsolatedLayerPreviewSwitch.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { useTranslation } from 'react-i18next';
1010
export const CanvasOperationIsolatedLayerPreviewSwitch = memo(() => {
1111
const { t } = useTranslation();
1212
const dispatch = useAppDispatch();
13-
const isolatedLayerPreview = useAppSelector(selectIsolatedLayerPreview);
13+
const isolatedLayerPreview = useAppSelector((state) => selectIsolatedLayerPreview(state));
1414
const onChangeIsolatedPreview = useCallback(() => {
1515
dispatch(settingsIsolatedLayerPreviewToggled());
1616
}, [dispatch]);

invokeai/frontend/web/src/features/controlLayers/components/Filters/Filter.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const FilterContentAdvanced = memo(
3535
const config = useStore(adapter.filterer.$filterConfig);
3636
const isProcessing = useStore(adapter.filterer.$isProcessing);
3737
const hasImageState = useStore(adapter.filterer.$hasImageState);
38-
const autoProcess = useAppSelector(selectAutoProcess);
38+
const autoProcess = useAppSelector((state) => selectAutoProcess(state));
3939

4040
const onChangeFilterConfig = useCallback(
4141
(filterConfig: FilterConfig) => {

0 commit comments

Comments
 (0)