From dd03e3ddcdc10c1c731af3ffe539c7618308b7b2 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Mon, 14 Jul 2025 16:31:35 +1000 Subject: [PATCH] refactor(ui): simplify canvas session logic --- invokeai/frontend/web/public/locales/en.json | 6 +- .../app/components/GlobalModalIsolator.tsx | 6 - .../web/src/app/hooks/useStudioInitAction.ts | 2 - .../listeners/modelSelected.ts | 5 +- .../listeners/setDefaultSettings.ts | 5 +- .../ControlLayerSettingsEmptyState.tsx | 9 +- .../NewSessionConfirmationAlertDialog.tsx | 131 --- .../RefImage/RefImageNoImageState.tsx | 7 +- .../RefImageNoImageStateWithCanvasOptions.tsx | 9 +- ...nalGuidanceIPAdapterSettingsEmptyState.tsx | 9 +- .../SimpleSession/StagingAreaItemsList.tsx | 4 +- .../components/SimpleSession/context.tsx | 834 +++++++++--------- .../StagingAreaToolbarAcceptButton.tsx | 7 +- .../StagingAreaToolbarDiscardAllButton.tsx | 7 +- .../hooks/useCanvasDeleteLayerHotkey.ts | 7 +- .../CanvasEntity/CanvasEntityAdapterBase.ts | 5 +- .../konva/CanvasStagingAreaModule.ts | 54 +- .../store/canvasStagingAreaSlice.ts | 99 +-- .../features/gallery/hooks/useRecallAll.ts | 4 +- .../gallery/hooks/useRecallDimensions.ts | 4 +- .../features/gallery/hooks/useRecallRemix.ts | 4 +- .../components/Bbox/BboxAspectRatioSelect.tsx | 4 +- .../Bbox/BboxSwapDimensionsButton.tsx | 6 +- .../Bbox/use-is-bbox-size-locked.ts | 5 +- .../features/queue/hooks/useEnqueueCanvas.ts | 9 +- .../queue/hooks/useEnqueueGenerate.ts | 8 +- .../ui/layouts/CanvasWorkspacePanel.tsx | 14 +- .../src/features/ui/layouts/StagingArea.tsx | 5 +- .../web/src/features/ui/store/uiSelectors.ts | 1 - .../web/src/features/ui/store/uiSlice.ts | 4 - .../web/src/features/ui/store/uiTypes.ts | 2 - 31 files changed, 536 insertions(+), 740 deletions(-) delete mode 100644 invokeai/frontend/web/src/features/controlLayers/components/NewSessionConfirmationAlertDialog.tsx diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index 5f8e2070c3..33fdd7b371 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -2087,9 +2087,9 @@ "resetCanvasLayers": "Reset Canvas Layers", "resetGenerationSettings": "Reset Generation Settings", "replaceCurrent": "Replace Current", - "controlLayerEmptyState": "Upload an image, drag an image from the gallery onto this layer, pull the bounding box into this layer, or draw on the canvas to get started.", - "referenceImageEmptyStateWithCanvasOptions": "Upload an image, drag an image from the gallery onto this Reference Image or pull the bounding box into this Reference Image to get started.", - "referenceImageEmptyState": "Upload an image or drag an image from the gallery onto this Reference Image to get started.", + "controlLayerEmptyState": "Upload an image, drag an image from the gallery onto this layer, pull the bounding box into this layer, or draw on the canvas to get started.", + "referenceImageEmptyStateWithCanvasOptions": "Upload an image, drag an image from the gallery onto this Reference Image or pull the bounding box into this Reference Image to get started.", + "referenceImageEmptyState": "Upload an image or drag an image from the gallery onto this Reference Image to get started.", "uploadOrDragAnImage": "Drag an image from the gallery or upload an image.", "imageNoise": "Image Noise", "denoiseLimit": "Denoise Limit", diff --git a/invokeai/frontend/web/src/app/components/GlobalModalIsolator.tsx b/invokeai/frontend/web/src/app/components/GlobalModalIsolator.tsx index 662994ec41..59f73f109b 100644 --- a/invokeai/frontend/web/src/app/components/GlobalModalIsolator.tsx +++ b/invokeai/frontend/web/src/app/components/GlobalModalIsolator.tsx @@ -1,10 +1,6 @@ import { GlobalImageHotkeys } from 'app/components/GlobalImageHotkeys'; import ChangeBoardModal from 'features/changeBoardModal/components/ChangeBoardModal'; import { CanvasPasteModal } from 'features/controlLayers/components/CanvasPasteModal'; -import { - NewCanvasSessionDialog, - NewGallerySessionDialog, -} from 'features/controlLayers/components/NewSessionConfirmationAlertDialog'; import { CanvasManagerProviderGate } from 'features/controlLayers/contexts/CanvasManagerProviderGate'; import { DeleteImageModal } from 'features/deleteImageModal/components/DeleteImageModal'; import { FullscreenDropzone } from 'features/dnd/FullscreenDropzone'; @@ -50,8 +46,6 @@ export const GlobalModalIsolator = memo(() => { - - diff --git a/invokeai/frontend/web/src/app/hooks/useStudioInitAction.ts b/invokeai/frontend/web/src/app/hooks/useStudioInitAction.ts index b27613b84b..d0e043381d 100644 --- a/invokeai/frontend/web/src/app/hooks/useStudioInitAction.ts +++ b/invokeai/frontend/web/src/app/hooks/useStudioInitAction.ts @@ -21,7 +21,6 @@ import { $isStylePresetsMenuOpen, activeStylePresetIdChanged } from 'features/st import { toast } from 'features/toast/toast'; import { navigationApi } from 'features/ui/layouts/navigation-api'; import { LAUNCHPAD_PANEL_ID, WORKSPACE_PANEL_ID } from 'features/ui/layouts/shared'; -import { activeTabCanvasRightPanelChanged } from 'features/ui/store/uiSlice'; import { useLoadWorkflowWithDialog } from 'features/workflowLibrary/components/LoadWorkflowConfirmationAlertDialog'; import { atom } from 'nanostores'; import { useCallback, useEffect } from 'react'; @@ -165,7 +164,6 @@ export const useStudioInitAction = (action?: StudioInitAction) => { // Go to the generate tab, open the launchpad await navigationApi.focusPanel('generate', LAUNCHPAD_PANEL_ID); store.dispatch(paramsReset()); - store.dispatch(activeTabCanvasRightPanelChanged('gallery')); break; case 'canvas': // Go to the canvas tab, open the launchpad diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts index 7d2e8f7520..f99a458cd7 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelSelected.ts @@ -1,7 +1,7 @@ import { logger } from 'app/logging/logger'; import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; import { bboxSyncedToOptimalDimension, rgRefImageModelChanged } from 'features/controlLayers/store/canvasSlice'; -import { selectIsStaging } from 'features/controlLayers/store/canvasStagingAreaSlice'; +import { buildSelectIsStaging, selectCanvasSessionId } from 'features/controlLayers/store/canvasStagingAreaSlice'; import { loraDeleted } from 'features/controlLayers/store/lorasSlice'; import { modelChanged, syncedToOptimalDimension, vaeSelected } from 'features/controlLayers/store/paramsSlice'; import { refImageModelChanged, selectReferenceImageEntities } from 'features/controlLayers/store/refImagesSlice'; @@ -152,7 +152,8 @@ export const addModelSelectedListener = (startAppListening: AppStartListening) = if (modelBase !== state.params.model?.base) { // Sync generate tab settings whenever the model base changes dispatch(syncedToOptimalDimension()); - if (!selectIsStaging(state)) { + const isStaging = buildSelectIsStaging(selectCanvasSessionId(state))(state); + if (!isStaging) { // Canvas tab only syncs if not staging dispatch(bboxSyncedToOptimalDimension()); } diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/setDefaultSettings.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/setDefaultSettings.ts index 38978baf3d..56a8958d1f 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/setDefaultSettings.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/setDefaultSettings.ts @@ -1,7 +1,7 @@ import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; import { isNil } from 'es-toolkit'; import { bboxHeightChanged, bboxWidthChanged } from 'features/controlLayers/store/canvasSlice'; -import { selectIsStaging } from 'features/controlLayers/store/canvasStagingAreaSlice'; +import { buildSelectIsStaging, selectCanvasSessionId } from 'features/controlLayers/store/canvasStagingAreaSlice'; import { heightChanged, setCfgRescaleMultiplier, @@ -115,7 +115,8 @@ export const addSetDefaultSettingsListener = (startAppListening: AppStartListeni } const setSizeOptions = { updateAspectRatio: true, clamp: true }; - const isStaging = selectIsStaging(getState()); + const isStaging = buildSelectIsStaging(selectCanvasSessionId(state))(state); + const activeTab = selectActiveTab(getState()); if (activeTab === 'generate') { if (isParameterWidth(width)) { diff --git a/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerSettingsEmptyState.tsx b/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerSettingsEmptyState.tsx index b1150417f3..596886599e 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerSettingsEmptyState.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/ControlLayer/ControlLayerSettingsEmptyState.tsx @@ -5,7 +5,6 @@ import { useEntityIdentifierContext } from 'features/controlLayers/contexts/Enti import { usePullBboxIntoLayer } from 'features/controlLayers/hooks/saveCanvasHooks'; import { useCanvasIsBusy } from 'features/controlLayers/hooks/useCanvasIsBusy'; import { replaceCanvasEntityObjectsWithImage } from 'features/imageActions/actions'; -import { activeTabCanvasRightPanelChanged } from 'features/ui/store/uiSlice'; import { memo, useCallback, useMemo } from 'react'; import { Trans } from 'react-i18next'; import type { ImageDTO } from 'services/api/types'; @@ -21,9 +20,6 @@ export const ControlLayerSettingsEmptyState = memo(() => { [dispatch, entityIdentifier, getState] ); const uploadApi = useImageUploadButton({ onUpload, allowMultiple: false }); - const onClickGalleryButton = useCallback(() => { - dispatch(activeTabCanvasRightPanelChanged('gallery')); - }, [dispatch]); const pullBboxIntoLayer = usePullBboxIntoLayer(entityIdentifier); const components = useMemo( @@ -31,14 +27,11 @@ export const ControlLayerSettingsEmptyState = memo(() => { UploadButton: (