From cc4bef4859f436be4e64a80a20d9d5fb92b39374 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Thu, 25 Apr 2024 20:08:21 +1000 Subject: [PATCH] refactor(ui): move size state to regional --- .../listeners/modelsLoaded.ts | 17 +++-- .../listeners/setDefaultSettings.ts | 7 +- .../components/ControlAdapterImagePreview.tsx | 7 +- .../src/features/metadata/util/recallers.ts | 8 +-- .../nodes/util/graph/addHrfToGraph.ts | 3 +- .../graph/buildLinearImageToImageGraph.ts | 3 +- .../graph/buildLinearSDXLImageToImageGraph.ts | 3 +- .../graph/buildLinearSDXLTextToImageGraph.ts | 3 +- .../util/graph/buildLinearTextToImageGraph.ts | 3 +- .../parameters/store/generationSlice.ts | 57 +-------------- .../src/features/parameters/store/types.ts | 6 -- .../components/StageComponent.tsx | 16 ++--- .../store/regionalPromptsSlice.ts | 69 ++++++++++++++++++- .../regionalPrompts/util/getLayerBlobs.ts | 6 +- .../ImageSettingsAccordion.tsx | 7 +- .../ImageSizeLinear.tsx | 12 ++-- 16 files changed, 118 insertions(+), 109 deletions(-) diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts index 2ba9aa3cbf..587f06720f 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/modelsLoaded.ts @@ -8,9 +8,10 @@ import { } from 'features/controlAdapters/store/controlAdaptersSlice'; import { loraRemoved } from 'features/lora/store/loraSlice'; import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize'; -import { heightChanged, modelChanged, vaeSelected, widthChanged } from 'features/parameters/store/generationSlice'; +import { modelChanged, vaeSelected } from 'features/parameters/store/generationSlice'; import { zParameterModel, zParameterVAEModel } from 'features/parameters/types/parameterSchemas'; import { getIsSizeOptimal, getOptimalDimension } from 'features/parameters/util/optimalDimension'; +import { heightChanged, widthChanged } from 'features/regionalPrompts/store/regionalPromptsSlice'; import { refinerModelChanged } from 'features/sdxl/store/sdxlSlice'; import { forEach } from 'lodash-es'; import type { Logger } from 'roarr'; @@ -69,16 +70,22 @@ const handleMainModels: ModelHandler = (models, state, dispatch, log) => { dispatch(modelChanged(defaultModelInList, currentModel)); const optimalDimension = getOptimalDimension(defaultModelInList); - if (getIsSizeOptimal(state.generation.width, state.generation.height, optimalDimension)) { + if ( + getIsSizeOptimal( + state.regionalPrompts.present.size.width, + state.regionalPrompts.present.size.height, + optimalDimension + ) + ) { return; } const { width, height } = calculateNewSize( - state.generation.aspectRatio.value, + state.regionalPrompts.present.size.aspectRatio.value, optimalDimension * optimalDimension ); - dispatch(widthChanged(width)); - dispatch(heightChanged(height)); + dispatch(widthChanged({ width })); + dispatch(heightChanged({ height })); return; } } 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 7fbb55845f..83fadffb26 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,14 +1,12 @@ import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; import { setDefaultSettings } from 'features/parameters/store/actions'; import { - heightRecalled, setCfgRescaleMultiplier, setCfgScale, setScheduler, setSteps, vaePrecisionChanged, vaeSelected, - widthRecalled, } from 'features/parameters/store/generationSlice'; import { isParameterCFGRescaleMultiplier, @@ -20,6 +18,7 @@ import { isParameterWidth, zParameterVAEModel, } from 'features/parameters/types/parameterSchemas'; +import { heightChanged, widthChanged } from 'features/regionalPrompts/store/regionalPromptsSlice'; import { addToast } from 'features/system/store/systemSlice'; import { makeToast } from 'features/system/util/makeToast'; import { t } from 'i18next'; @@ -100,13 +99,13 @@ export const addSetDefaultSettingsListener = (startAppListening: AppStartListeni if (width) { if (isParameterWidth(width)) { - dispatch(widthRecalled(width)); + dispatch(widthChanged({ width, updateAspectRatio: true })); } } if (height) { if (isParameterHeight(height)) { - dispatch(heightRecalled(height)); + dispatch(heightChanged({ height, updateAspectRatio: true })); } } diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterImagePreview.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterImagePreview.tsx index c136fbe064..33269656ad 100644 --- a/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterImagePreview.tsx +++ b/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterImagePreview.tsx @@ -15,7 +15,8 @@ import { } from 'features/controlAdapters/store/controlAdaptersSlice'; import type { TypesafeDraggableData, TypesafeDroppableData } from 'features/dnd/types'; import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize'; -import { heightChanged, selectOptimalDimension, widthChanged } from 'features/parameters/store/generationSlice'; +import { selectOptimalDimension } from 'features/parameters/store/generationSlice'; +import { heightChanged, widthChanged } from 'features/regionalPrompts/store/regionalPromptsSlice'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; import { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -99,8 +100,8 @@ const ControlAdapterImagePreview = ({ isSmall, id }: Props) => { controlImage.width / controlImage.height, optimalDimension * optimalDimension ); - dispatch(widthChanged(width)); - dispatch(heightChanged(height)); + dispatch(widthChanged({ width, updateAspectRatio: true })); + dispatch(heightChanged({ height, updateAspectRatio: true })); } }, [controlImage, activeTabName, dispatch, optimalDimension]); diff --git a/invokeai/frontend/web/src/features/metadata/util/recallers.ts b/invokeai/frontend/web/src/features/metadata/util/recallers.ts index 7850871cb3..fd0d8c9a33 100644 --- a/invokeai/frontend/web/src/features/metadata/util/recallers.ts +++ b/invokeai/frontend/web/src/features/metadata/util/recallers.ts @@ -16,7 +16,6 @@ import type { } from 'features/metadata/types'; import { modelSelected } from 'features/parameters/store/actions'; import { - heightRecalled, initialImageChanged, setCfgRescaleMultiplier, setCfgScale, @@ -25,7 +24,6 @@ import { setSeed, setSteps, vaeSelected, - widthRecalled, } from 'features/parameters/store/generationSlice'; import type { ParameterCFGRescaleMultiplier, @@ -50,10 +48,12 @@ import type { ParameterWidth, } from 'features/parameters/types/parameterSchemas'; import { + heightChanged, negativePrompt2Changed, negativePromptChanged, positivePrompt2Changed, positivePromptChanged, + widthChanged, } from 'features/regionalPrompts/store/regionalPromptsSlice'; import { refinerModelChanged, @@ -103,11 +103,11 @@ const recallInitialImage: MetadataRecallFunc = async (imageDTO) => { }; const recallWidth: MetadataRecallFunc = (width) => { - getStore().dispatch(widthRecalled(width)); + getStore().dispatch(widthChanged({ width, updateAspectRatio: true })); }; const recallHeight: MetadataRecallFunc = (height) => { - getStore().dispatch(heightRecalled(height)); + getStore().dispatch(heightChanged({ height, updateAspectRatio: true })); }; const recallSteps: MetadataRecallFunc = (steps) => { diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/addHrfToGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/addHrfToGraph.ts index 5632cfd112..d7c512728e 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/addHrfToGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/addHrfToGraph.ts @@ -110,10 +110,9 @@ export const addHrfToGraph = (state: RootState, graph: NonNullableGraph): void = const { vae, seamlessXAxis, seamlessYAxis } = state.generation; const { hrfStrength, hrfEnabled, hrfMethod } = state.hrf; + const { width, height } = state.regionalPrompts.present.size; const isAutoVae = !vae; const isSeamlessEnabled = seamlessXAxis || seamlessYAxis; - const width = state.generation.width; - const height = state.generation.height; const optimalDimension = selectOptimalDimension(state); const { newWidth: hrfWidth, newHeight: hrfHeight } = calculateHrfRes(optimalDimension, width, height); diff --git a/invokeai/frontend/web/src/features/nodes/util/graph/buildLinearImageToImageGraph.ts b/invokeai/frontend/web/src/features/nodes/util/graph/buildLinearImageToImageGraph.ts index 08bad689ce..5c9b6b96db 100644 --- a/invokeai/frontend/web/src/features/nodes/util/graph/buildLinearImageToImageGraph.ts +++ b/invokeai/frontend/web/src/features/nodes/util/graph/buildLinearImageToImageGraph.ts @@ -47,8 +47,6 @@ export const buildLinearImageToImageGraph = async (state: RootState): Promise ({ payload, @@ -174,27 +154,6 @@ export const generationSlice = createSlice({ shouldUseCpuNoiseChanged: (state, action: PayloadAction) => { state.shouldUseCpuNoise = action.payload; }, - widthChanged: (state, action: PayloadAction) => { - state.width = action.payload; - }, - heightChanged: (state, action: PayloadAction) => { - state.height = action.payload; - }, - widthRecalled: (state, action: PayloadAction) => { - state.width = action.payload; - state.aspectRatio.value = action.payload / state.height; - state.aspectRatio.id = 'Free'; - state.aspectRatio.isLocked = false; - }, - heightRecalled: (state, action: PayloadAction) => { - state.height = action.payload; - state.aspectRatio.value = state.width / action.payload; - state.aspectRatio.id = 'Free'; - state.aspectRatio.isLocked = false; - }, - aspectRatioChanged: (state, action: PayloadAction) => { - state.aspectRatio = action.payload; - }, setInfillMethod: (state, action: PayloadAction) => { state.infillMethod = action.payload; }, @@ -229,15 +188,6 @@ export const generationSlice = createSlice({ state.vaePrecision = action.payload.sd.vaePrecision; } }); - - // TODO: This is a temp fix to reduce issues with T2I adapter having a different downscaling - // factor than the UNet. Hopefully we get an upstream fix in diffusers. - builder.addMatcher(isAnyControlAdapterAdded, (state, action) => { - if (action.payload.type === 't2i_adapter') { - state.width = roundToMultiple(state.width, 64); - state.height = roundToMultiple(state.height, 64); - } - }); }, selectors: { selectOptimalDimension: (slice) => getOptimalDimension(slice.model), @@ -268,11 +218,6 @@ export const { setClipSkip, shouldUseCpuNoiseChanged, vaePrecisionChanged, - aspectRatioChanged, - widthChanged, - heightChanged, - widthRecalled, - heightRecalled, setInfillTileSize, setInfillPatchmatchDownscaleSize, setInfillMosaicTileWidth, diff --git a/invokeai/frontend/web/src/features/parameters/store/types.ts b/invokeai/frontend/web/src/features/parameters/store/types.ts index 55e6ae63f9..9314f8d076 100644 --- a/invokeai/frontend/web/src/features/parameters/store/types.ts +++ b/invokeai/frontend/web/src/features/parameters/store/types.ts @@ -1,10 +1,8 @@ import type { PayloadAction } from '@reduxjs/toolkit'; -import type { AspectRatioState } from 'features/parameters/components/ImageSize/types'; import type { ParameterCanvasCoherenceMode, ParameterCFGRescaleMultiplier, ParameterCFGScale, - ParameterHeight, ParameterMaskBlurMethod, ParameterModel, ParameterPrecision, @@ -13,7 +11,6 @@ import type { ParameterSteps, ParameterStrength, ParameterVAEModel, - ParameterWidth, } from 'features/parameters/types/parameterSchemas'; import type { RgbaColor } from 'react-colorful'; @@ -21,7 +18,6 @@ export interface GenerationState { _version: 2; cfgScale: ParameterCFGScale; cfgRescaleMultiplier: ParameterCFGRescaleMultiplier; - height: ParameterHeight; img2imgStrength: ParameterStrength; infillMethod: string; initialImage?: { imageName: string; width: number; height: number }; @@ -36,7 +32,6 @@ export interface GenerationState { shouldFitToWidthHeight: boolean; shouldRandomizeSeed: boolean; steps: ParameterSteps; - width: ParameterWidth; model: ParameterModel | null; vae: ParameterVAEModel | null; vaePrecision: ParameterPrecision; @@ -45,7 +40,6 @@ export interface GenerationState { clipSkip: number; shouldUseCpuNoise: boolean; shouldShowAdvancedOptions: boolean; - aspectRatio: AspectRatioState; infillTileSize: number; infillPatchmatchDownscaleSize: number; infillMosaicTileWidth: number; diff --git a/invokeai/frontend/web/src/features/regionalPrompts/components/StageComponent.tsx b/invokeai/frontend/web/src/features/regionalPrompts/components/StageComponent.tsx index f286b75711..d6f6eff812 100644 --- a/invokeai/frontend/web/src/features/regionalPrompts/components/StageComponent.tsx +++ b/invokeai/frontend/web/src/features/regionalPrompts/components/StageComponent.tsx @@ -43,8 +43,6 @@ const useStageRenderer = ( asPreview: boolean ) => { const dispatch = useAppDispatch(); - const width = useAppSelector((s) => s.generation.width); - const height = useAppSelector((s) => s.generation.height); const state = useAppSelector((s) => s.regionalPrompts.present); const tool = useStore($tool); const { onMouseDown, onMouseUp, onMouseMove, onMouseEnter, onMouseLeave, onMouseWheel } = useMouseEvents(); @@ -121,11 +119,11 @@ const useStageRenderer = ( const stage = stageRef.current; const fitStageToContainer = () => { - const newXScale = wrapper.offsetWidth / width; - const newYScale = wrapper.offsetHeight / height; + const newXScale = wrapper.offsetWidth / state.size.width; + const newYScale = wrapper.offsetHeight / state.size.height; const newScale = Math.min(newXScale, newYScale, 1); - stage.width(width * newScale); - stage.height(height * newScale); + stage.width(state.size.width * newScale); + stage.height(state.size.height * newScale); stage.scaleX(newScale); stage.scaleY(newScale); }; @@ -137,7 +135,7 @@ const useStageRenderer = ( return () => { resizeObserver.disconnect(); }; - }, [stageRef, width, height, wrapper]); + }, [stageRef, state.size.width, state.size.height, wrapper]); useLayoutEffect(() => { log.trace('Rendering tool preview'); @@ -188,8 +186,8 @@ const useStageRenderer = ( // The preview should not have a background return; } - renderers.renderBackground(stageRef.current, width, height); - }, [stageRef, asPreview, width, height, renderers]); + renderers.renderBackground(stageRef.current, state.size.width, state.size.height); + }, [stageRef, asPreview, state.size.width, state.size.height, renderers]); useLayoutEffect(() => { log.trace('Arranging layers'); diff --git a/invokeai/frontend/web/src/features/regionalPrompts/store/regionalPromptsSlice.ts b/invokeai/frontend/web/src/features/regionalPrompts/store/regionalPromptsSlice.ts index 8e72e2526b..7d809f2695 100644 --- a/invokeai/frontend/web/src/features/regionalPrompts/store/regionalPromptsSlice.ts +++ b/invokeai/frontend/web/src/features/regionalPrompts/store/regionalPromptsSlice.ts @@ -2,15 +2,24 @@ import type { PayloadAction, UnknownAction } from '@reduxjs/toolkit'; import { createSlice, isAnyOf } from '@reduxjs/toolkit'; import type { PersistConfig, RootState } from 'app/store/store'; import { moveBackward, moveForward, moveToBack, moveToFront } from 'common/util/arrayUtils'; -import { controlAdapterRemoved } from 'features/controlAdapters/store/controlAdaptersSlice'; +import { deepClone } from 'common/util/deepClone'; +import { roundToMultiple } from 'common/util/roundDownToMultiple'; +import { controlAdapterRemoved, isAnyControlAdapterAdded } from 'features/controlAdapters/store/controlAdaptersSlice'; import type { ControlAdapterConfig } from 'features/controlAdapters/store/types'; +import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize'; +import { initialAspectRatioState } from 'features/parameters/components/ImageSize/constants'; +import type { AspectRatioState } from 'features/parameters/components/ImageSize/types'; +import { modelChanged } from 'features/parameters/store/generationSlice'; import type { ParameterAutoNegative, + ParameterHeight, ParameterNegativePrompt, ParameterNegativeStylePromptSDXL, ParameterPositivePrompt, ParameterPositiveStylePromptSDXL, + ParameterWidth, } from 'features/parameters/types/parameterSchemas'; +import { getIsSizeOptimal, getOptimalDimension } from 'features/parameters/util/optimalDimension'; import type { IRect, Vector2d } from 'konva/lib/types'; import { isEqual } from 'lodash-es'; import { atom } from 'nanostores'; @@ -86,6 +95,11 @@ type RegionalPromptsState = { globalMaskLayerOpacity: number; isEnabled: boolean; baseLayer: BaseLayerState; + size: { + width: ParameterWidth; + height: ParameterHeight; + aspectRatio: AspectRatioState; + }; }; export const initialRegionalPromptsState: RegionalPromptsState = { @@ -102,6 +116,11 @@ export const initialRegionalPromptsState: RegionalPromptsState = { negativePrompt2: '', shouldConcatPrompts: true, }, + size: { + width: 512, + height: 512, + aspectRatio: deepClone(initialAspectRatioState), + }, }; const isLine = (obj: VectorMaskLine | VectorMaskRect): obj is VectorMaskLine => obj.type === 'vector_mask_line'; @@ -364,6 +383,27 @@ export const regionalPromptsSlice = createSlice({ shouldConcatPromptsChanged: (state, action: PayloadAction) => { state.baseLayer.shouldConcatPrompts = action.payload; }, + widthChanged: (state, action: PayloadAction<{ width: number; updateAspectRatio?: boolean }>) => { + const { width, updateAspectRatio } = action.payload; + state.size.width = width; + if (updateAspectRatio) { + state.size.aspectRatio.value = width / state.size.height; + state.size.aspectRatio.id = 'Free'; + state.size.aspectRatio.isLocked = false; + } + }, + heightChanged: (state, action: PayloadAction<{ height: number; updateAspectRatio?: boolean }>) => { + const { height, updateAspectRatio } = action.payload; + state.size.height = height; + if (updateAspectRatio) { + state.size.aspectRatio.value = state.size.width / height; + state.size.aspectRatio.id = 'Free'; + state.size.aspectRatio.isLocked = false; + } + }, + aspectRatioChanged: (state, action: PayloadAction) => { + state.size.aspectRatio = action.payload; + }, //#endregion //#region General @@ -396,6 +436,30 @@ export const regionalPromptsSlice = createSlice({ layer.ipAdapterIds = layer.ipAdapterIds.filter((id) => id !== action.payload.id); }); }); + + builder.addCase(modelChanged, (state, action) => { + const newModel = action.payload; + if (!newModel || action.meta.previousModel?.base === newModel.base) { + // Model was cleared or the base didn't change + return; + } + const optimalDimension = getOptimalDimension(newModel); + if (getIsSizeOptimal(state.size.width, state.size.height, optimalDimension)) { + return; + } + const { width, height } = calculateNewSize(state.size.aspectRatio.value, optimalDimension * optimalDimension); + state.size.width = width; + state.size.height = height; + }); + + // TODO: This is a temp fix to reduce issues with T2I adapter having a different downscaling + // factor than the UNet. Hopefully we get an upstream fix in diffusers. + builder.addMatcher(isAnyControlAdapterAdded, (state, action) => { + if (action.payload.type === 't2i_adapter') { + state.size.width = roundToMultiple(state.size.width, 64); + state.size.height = roundToMultiple(state.size.height, 64); + } + }); }, }); @@ -461,6 +525,9 @@ export const { positivePrompt2Changed, negativePrompt2Changed, shouldConcatPromptsChanged, + widthChanged, + heightChanged, + aspectRatioChanged, // General actions brushSizeChanged, globalMaskLayerOpacityChanged, diff --git a/invokeai/frontend/web/src/features/regionalPrompts/util/getLayerBlobs.ts b/invokeai/frontend/web/src/features/regionalPrompts/util/getLayerBlobs.ts index 02c1ae8b60..da8108784d 100644 --- a/invokeai/frontend/web/src/features/regionalPrompts/util/getLayerBlobs.ts +++ b/invokeai/frontend/web/src/features/regionalPrompts/util/getLayerBlobs.ts @@ -17,9 +17,11 @@ export const getRegionalPromptLayerBlobs = async ( preview: boolean = false ): Promise> => { const state = getStore().getState(); - const reduxLayers = state.regionalPrompts.present.layers.filter(isVectorMaskLayer); + const { layers } = state.regionalPrompts.present; + const { width, height } = state.regionalPrompts.present.size; + const reduxLayers = layers.filter(isVectorMaskLayer); const container = document.createElement('div'); - const stage = new Konva.Stage({ container, width: state.generation.width, height: state.generation.height }); + const stage = new Konva.Stage({ container, width, height }); renderers.renderLayers(stage, reduxLayers, 1, 'brush'); const konvaLayers = stage.find(`.${VECTOR_MASK_LAYER_NAME}`); diff --git a/invokeai/frontend/web/src/features/settingsAccordions/components/ImageSettingsAccordion/ImageSettingsAccordion.tsx b/invokeai/frontend/web/src/features/settingsAccordions/components/ImageSettingsAccordion/ImageSettingsAccordion.tsx index 125a611876..30f7f4b0ac 100644 --- a/invokeai/frontend/web/src/features/settingsAccordions/components/ImageSettingsAccordion/ImageSettingsAccordion.tsx +++ b/invokeai/frontend/web/src/features/settingsAccordions/components/ImageSettingsAccordion/ImageSettingsAccordion.tsx @@ -14,6 +14,7 @@ import { ParamSeedNumberInput } from 'features/parameters/components/Seed/ParamS import { ParamSeedRandomize } from 'features/parameters/components/Seed/ParamSeedRandomize'; import { ParamSeedShuffle } from 'features/parameters/components/Seed/ParamSeedShuffle'; import { selectGenerationSlice } from 'features/parameters/store/generationSlice'; +import { selectRegionalPromptsSlice } from 'features/regionalPrompts/store/regionalPromptsSlice'; import { useExpanderToggle } from 'features/settingsAccordions/hooks/useExpanderToggle'; import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/useStandaloneAccordionToggle'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; @@ -24,8 +25,8 @@ import { ImageSizeCanvas } from './ImageSizeCanvas'; import { ImageSizeLinear } from './ImageSizeLinear'; const selector = createMemoizedSelector( - [selectGenerationSlice, selectCanvasSlice, selectHrfSlice, activeTabNameSelector], - (generation, canvas, hrf, activeTabName) => { + [selectGenerationSlice, selectCanvasSlice, selectHrfSlice, selectRegionalPromptsSlice, activeTabNameSelector], + (generation, canvas, hrf, regionalPrompts, activeTabName) => { const { shouldRandomizeSeed, model } = generation; const { hrfEnabled } = hrf; const badges: string[] = []; @@ -42,7 +43,7 @@ const selector = createMemoizedSelector( badges.push('locked'); } } else { - const { aspectRatio, width, height } = generation; + const { aspectRatio, width, height } = regionalPrompts.present.size; badges.push(`${width}×${height}`); badges.push(aspectRatio.id); if (aspectRatio.isLocked) { diff --git a/invokeai/frontend/web/src/features/settingsAccordions/components/ImageSettingsAccordion/ImageSizeLinear.tsx b/invokeai/frontend/web/src/features/settingsAccordions/components/ImageSettingsAccordion/ImageSizeLinear.tsx index 498faf452b..3a00496ec9 100644 --- a/invokeai/frontend/web/src/features/settingsAccordions/components/ImageSettingsAccordion/ImageSizeLinear.tsx +++ b/invokeai/frontend/web/src/features/settingsAccordions/components/ImageSettingsAccordion/ImageSizeLinear.tsx @@ -5,27 +5,27 @@ import { AspectRatioCanvasPreview } from 'features/parameters/components/ImageSi import { AspectRatioIconPreview } from 'features/parameters/components/ImageSize/AspectRatioIconPreview'; import { ImageSize } from 'features/parameters/components/ImageSize/ImageSize'; import type { AspectRatioState } from 'features/parameters/components/ImageSize/types'; -import { aspectRatioChanged, heightChanged, widthChanged } from 'features/parameters/store/generationSlice'; +import { aspectRatioChanged, heightChanged, widthChanged } from 'features/regionalPrompts/store/regionalPromptsSlice'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; import { memo, useCallback } from 'react'; export const ImageSizeLinear = memo(() => { const dispatch = useAppDispatch(); const tab = useAppSelector(activeTabNameSelector); - const width = useAppSelector((s) => s.generation.width); - const height = useAppSelector((s) => s.generation.height); - const aspectRatioState = useAppSelector((s) => s.generation.aspectRatio); + const width = useAppSelector((s) => s.regionalPrompts.present.size.width); + const height = useAppSelector((s) => s.regionalPrompts.present.size.height); + const aspectRatioState = useAppSelector((s) => s.regionalPrompts.present.size.aspectRatio); const onChangeWidth = useCallback( (width: number) => { - dispatch(widthChanged(width)); + dispatch(widthChanged({ width })); }, [dispatch] ); const onChangeHeight = useCallback( (height: number) => { - dispatch(heightChanged(height)); + dispatch(heightChanged({ height })); }, [dispatch] );