refactor(ui): update size/prompts state

This commit is contained in:
psychedelicious 2024-06-15 22:50:31 +10:00
parent 5fc7a03669
commit ccceba7565
19 changed files with 124 additions and 151 deletions

View File

@ -79,15 +79,15 @@ const handleMainModels: ModelHandler = (models, state, dispatch, log) => {
const optimalDimension = getOptimalDimension(defaultModelInList);
if (
getIsSizeOptimal(
state.canvasV2.size.width,
state.canvasV2.size.height,
state.canvasV2.document.width,
state.canvasV2.document.height,
optimalDimension
)
) {
return;
}
const { width, height } = calculateNewSize(
state.canvasV2.size.aspectRatio.value,
state.canvasV2.document.aspectRatio.value,
optimalDimension * optimalDimension
);

View File

@ -1,11 +1,7 @@
import { useStore } from '@nanostores/react';
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { useAppSelector } from 'app/store/storeHooks';
import { selectControlAdaptersV2Slice } from 'features/controlLayers/store/controlAdaptersSlice';
import { selectCanvasV2Slice } from 'features/controlLayers/store/canvasV2Slice';
import { selectIPAdaptersSlice } from 'features/controlLayers/store/ipAdaptersSlice';
import { selectLayersSlice } from 'features/controlLayers/store/layersSlice';
import { selectRegionalGuidanceSlice } from 'features/controlLayers/store/regionalGuidanceSlice';
import type { CanvasEntity } from 'features/controlLayers/store/types';
import { selectDynamicPromptsSlice } from 'features/dynamicPrompts/store/dynamicPromptsSlice';
import { getShouldProcessPrompt } from 'features/dynamicPrompts/util/getShouldProcessPrompt';
@ -40,32 +36,13 @@ const createSelector = (templates: Templates) =>
selectWorkflowSettingsSlice,
selectDynamicPromptsSlice,
selectCanvasV2Slice,
selectLayersSlice,
selectControlAdaptersV2Slice,
selectRegionalGuidanceSlice,
selectIPAdaptersSlice,
activeTabNameSelector,
selectUpscalelice,
selectConfigSlice,
activeTabNameSelector,
],
(
generation,
system,
nodes,
workflowSettings,
dynamicPrompts,
canvasV2,
layersState,
controlAdaptersState,
regionalGuidanceState,
ipAdaptersState,
activeTabName,
upscale,
config
) => {
const { model } = generation;
const { size } = canvasV2;
const { positivePrompt } = canvasV2.prompts;
(generation, system, nodes, workflowSettings, dynamicPrompts, canvasV2, upscale, config, activeTabName) => {
const { model, positivePrompt } = generation;
const { bbox } = canvasV2;
const { isConnected } = system;
@ -149,7 +126,7 @@ const createSelector = (templates: Templates) =>
reasons.push({ content: i18n.t('parameters.invoke.noModelSelected') });
}
controlAdaptersState.controlAdapters
canvasV2.controlAdapters
.filter((ca) => ca.isEnabled)
.forEach((ca, i) => {
const layerLiteral = i18n.t('controlLayers.layers_one');
@ -174,7 +151,7 @@ const createSelector = (templates: Templates) =>
// T2I Adapters require images have dimensions that are multiples of 64 (SD1.5) or 32 (SDXL)
if (!ca.controlMode) {
const multiple = model?.base === 'sdxl' ? 32 : 64;
if (size.width % multiple !== 0 || size.height % multiple !== 0) {
if (bbox.width % multiple !== 0 || bbox.height % multiple !== 0) {
problems.push(i18n.t('parameters.invoke.layer.t2iAdapterIncompatibleDimensions', { multiple }));
}
}
@ -185,7 +162,7 @@ const createSelector = (templates: Templates) =>
}
});
ipAdaptersState.ipAdapters
canvasV2.ipAdapters
.filter((ipa) => ipa.isEnabled)
.forEach((ipa, i) => {
const layerLiteral = i18n.t('controlLayers.layers_one');
@ -213,7 +190,7 @@ const createSelector = (templates: Templates) =>
}
});
regionalGuidanceState.regions
canvasV2.regions
.filter((rg) => rg.isEnabled)
.forEach((rg, i) => {
const layerLiteral = i18n.t('controlLayers.layers_one');
@ -250,7 +227,7 @@ const createSelector = (templates: Templates) =>
}
});
layersState.layers
canvasV2.layers
.filter((l) => l.isEnabled)
.forEach((l, i) => {
const layerLiteral = i18n.t('controlLayers.layers_one');

View File

@ -35,7 +35,6 @@ import {
rgLinePointAdded,
rgRectAdded,
rgTranslated,
selectCanvasV2Slice,
toolBufferChanged,
toolChanged,
} from 'features/controlLayers/store/canvasV2Slice';
@ -65,50 +64,51 @@ const log = logger('controlLayers');
const useStageRenderer = (stage: Konva.Stage, container: HTMLDivElement | null, asPreview: boolean) => {
const dispatch = useAppDispatch();
const canvasV2State = useAppSelector(selectCanvasV2Slice);
const controlAdapters = useAppSelector((s) => s.canvasV2.controlAdapters);
const ipAdapters = useAppSelector((s) => s.canvasV2.ipAdapters);
const layers = useAppSelector((s) => s.canvasV2.layers);
const regions = useAppSelector((s) => s.canvasV2.regions);
const tool = useAppSelector((s) => s.canvasV2.tool);
const selectedEntityIdentifier = useAppSelector((s) => s.canvasV2.selectedEntityIdentifier);
const maskFillOpacity = useAppSelector((s) => s.canvasV2.maskFillOpacity);
const bbox = useAppSelector((s) => s.canvasV2.bbox);
const lastCursorPos = useStore($lastCursorPos);
const lastMouseDownPos = useStore($lastMouseDownPos);
const isMouseDown = useStore($isMouseDown);
const isDrawing = useStore($isDrawing);
const selectedEntity = useMemo(() => {
const identifier = canvasV2State.selectedEntityIdentifier;
const identifier = selectedEntityIdentifier;
if (!identifier) {
return null;
} else if (identifier.type === 'layer') {
return canvasV2State.layers.find((i) => i.id === identifier.id) ?? null;
return layers.find((i) => i.id === identifier.id) ?? null;
} else if (identifier.type === 'control_adapter') {
return canvasV2State.controlAdapters.find((i) => i.id === identifier.id) ?? null;
return controlAdapters.find((i) => i.id === identifier.id) ?? null;
} else if (identifier.type === 'ip_adapter') {
return canvasV2State.ipAdapters.find((i) => i.id === identifier.id) ?? null;
return ipAdapters.find((i) => i.id === identifier.id) ?? null;
} else if (identifier.type === 'regional_guidance') {
return canvasV2State.regions.find((i) => i.id === identifier.id) ?? null;
return regions.find((i) => i.id === identifier.id) ?? null;
} else {
return null;
}
}, [
canvasV2State.controlAdapters,
canvasV2State.ipAdapters,
canvasV2State.layers,
canvasV2State.regions,
canvasV2State.selectedEntityIdentifier,
]);
}, [controlAdapters, ipAdapters, layers, regions, selectedEntityIdentifier]);
const currentFill = useMemo(() => {
if (selectedEntity && selectedEntity.type === 'regional_guidance') {
return { ...selectedEntity.fill, a: canvasV2State.maskFillOpacity };
return { ...selectedEntity.fill, a: maskFillOpacity };
}
return canvasV2State.tool.fill;
}, [canvasV2State.maskFillOpacity, canvasV2State.tool.fill, selectedEntity]);
return tool.fill;
}, [maskFillOpacity, selectedEntity, tool.fill]);
const renderers = useMemo(() => (asPreview ? debouncedRenderers : normalRenderers), [asPreview]);
const dpr = useDevicePixelRatio({ round: false });
useLayoutEffect(() => {
$toolState.set(canvasV2State.tool);
$toolState.set(tool);
$selectedEntity.set(selectedEntity);
$bbox.set(canvasV2State.bbox);
$bbox.set(bbox);
$currentFill.set(currentFill);
}, [selectedEntity, canvasV2State.tool, canvasV2State.bbox, currentFill]);
}, [selectedEntity, tool, bbox, currentFill]);
const onPosChanged = useCallback(
(arg: PosChangedArg, entityType: CanvasEntity['type']) => {
@ -305,7 +305,7 @@ const useStageRenderer = (stage: Konva.Stage, container: HTMLDivElement | null,
log.trace('Rendering tool preview');
renderers.renderToolPreview(
stage,
canvasV2State.tool,
tool,
currentFill,
selectedEntity,
lastCursorPos,
@ -315,7 +315,6 @@ const useStageRenderer = (stage: Konva.Stage, container: HTMLDivElement | null,
);
}, [
asPreview,
canvasV2State.tool,
currentFill,
isDrawing,
isMouseDown,
@ -324,6 +323,7 @@ const useStageRenderer = (stage: Konva.Stage, container: HTMLDivElement | null,
renderers,
selectedEntity,
stage,
tool,
]);
useLayoutEffect(() => {
@ -334,8 +334,8 @@ const useStageRenderer = (stage: Konva.Stage, container: HTMLDivElement | null,
log.trace('Rendering bbox preview');
renderers.renderBboxPreview(
stage,
canvasV2State.bbox,
canvasV2State.tool.selected,
bbox,
tool.selected,
$bbox.get,
onBboxTransformed,
$shift.get,
@ -343,31 +343,31 @@ const useStageRenderer = (stage: Konva.Stage, container: HTMLDivElement | null,
$meta.get,
$alt.get
);
}, [asPreview, canvasV2State.bbox, canvasV2State.tool.selected, onBboxTransformed, renderers, stage]);
}, [asPreview, bbox, onBboxTransformed, renderers, stage, tool.selected]);
useLayoutEffect(() => {
log.trace('Rendering layers');
renderers.renderLayers(
stage,
canvasV2State.layers,
canvasV2State.controlAdapters,
canvasV2State.regions,
canvasV2State.maskFillOpacity,
canvasV2State.tool.selected,
layers,
controlAdapters,
regions,
maskFillOpacity,
tool.selected,
selectedEntity,
getImageDTO,
onPosChanged
);
}, [
stage,
renderers,
controlAdapters,
layers,
maskFillOpacity,
onPosChanged,
canvasV2State.tool.selected,
regions,
renderers,
selectedEntity,
canvasV2State.layers,
canvasV2State.controlAdapters,
canvasV2State.regions,
canvasV2State.maskFillOpacity,
stage,
tool.selected,
]);
// useLayoutEffect(() => {

View File

@ -21,13 +21,6 @@ import { DEFAULT_RGBA_COLOR } from './types';
const initialState: CanvasV2State = {
_version: 3,
selectedEntityIdentifier: null,
prompts: {
positivePrompt: '',
negativePrompt: '',
positivePrompt2: '',
negativePrompt2: '',
shouldConcatPrompts: true,
},
tool: {
selected: 'bbox',
selectedBuffer: null,
@ -40,7 +33,7 @@ const initialState: CanvasV2State = {
width: 50,
},
},
size: {
document: {
width: 512,
height: 512,
aspectRatio: deepClone(initialAspectRatioState),
@ -66,41 +59,26 @@ export const canvasV2Slice = createSlice({
...ipAdaptersReducers,
...controlAdaptersReducers,
...regionsReducers,
positivePromptChanged: (state, action: PayloadAction<string>) => {
state.prompts.positivePrompt = action.payload;
},
negativePromptChanged: (state, action: PayloadAction<string>) => {
state.prompts.negativePrompt = action.payload;
},
positivePrompt2Changed: (state, action: PayloadAction<string>) => {
state.prompts.positivePrompt2 = action.payload;
},
negativePrompt2Changed: (state, action: PayloadAction<string>) => {
state.prompts.negativePrompt2 = action.payload;
},
shouldConcatPromptsChanged: (state, action: PayloadAction<boolean>) => {
state.prompts.shouldConcatPrompts = action.payload;
},
widthChanged: (state, action: PayloadAction<{ width: number; updateAspectRatio?: boolean; clamp?: boolean }>) => {
const { width, updateAspectRatio, clamp } = action.payload;
state.size.width = clamp ? Math.max(roundDownToMultiple(width, 8), 64) : width;
state.document.width = clamp ? Math.max(roundDownToMultiple(width, 8), 64) : width;
if (updateAspectRatio) {
state.size.aspectRatio.value = state.size.width / state.size.height;
state.size.aspectRatio.id = 'Free';
state.size.aspectRatio.isLocked = false;
state.document.aspectRatio.value = state.document.width / state.document.height;
state.document.aspectRatio.id = 'Free';
state.document.aspectRatio.isLocked = false;
}
},
heightChanged: (state, action: PayloadAction<{ height: number; updateAspectRatio?: boolean; clamp?: boolean }>) => {
const { height, updateAspectRatio, clamp } = action.payload;
state.size.height = clamp ? Math.max(roundDownToMultiple(height, 8), 64) : height;
state.document.height = clamp ? Math.max(roundDownToMultiple(height, 8), 64) : height;
if (updateAspectRatio) {
state.size.aspectRatio.value = state.size.width / state.size.height;
state.size.aspectRatio.id = 'Free';
state.size.aspectRatio.isLocked = false;
state.document.aspectRatio.value = state.document.width / state.document.height;
state.document.aspectRatio.id = 'Free';
state.document.aspectRatio.isLocked = false;
}
},
aspectRatioChanged: (state, action: PayloadAction<AspectRatioState>) => {
state.size.aspectRatio = action.payload;
state.document.aspectRatio = action.payload;
},
bboxChanged: (state, action: PayloadAction<IRect>) => {
state.bbox = action.payload;
@ -144,22 +122,17 @@ export const canvasV2Slice = createSlice({
return;
}
const optimalDimension = getOptimalDimension(newModel);
if (getIsSizeOptimal(state.size.width, state.size.height, optimalDimension)) {
if (getIsSizeOptimal(state.document.width, state.document.height, optimalDimension)) {
return;
}
const { width, height } = calculateNewSize(state.size.aspectRatio.value, optimalDimension * optimalDimension);
state.size.width = width;
state.size.height = height;
const { width, height } = calculateNewSize(state.document.aspectRatio.value, optimalDimension * optimalDimension);
state.document.width = width;
state.document.height = height;
});
},
});
export const {
positivePromptChanged,
negativePromptChanged,
positivePrompt2Changed,
negativePrompt2Changed,
shouldConcatPromptsChanged,
widthChanged,
heightChanged,
aspectRatioChanged,

View File

@ -3,10 +3,6 @@ import { zModelIdentifierField } from 'features/nodes/types/common';
import type { AspectRatioState } from 'features/parameters/components/ImageSize/types';
import type {
ParameterHeight,
ParameterNegativePrompt,
ParameterNegativeStylePromptSDXL,
ParameterPositivePrompt,
ParameterPositiveStylePromptSDXL,
ParameterWidth,
} from 'features/parameters/types/parameterSchemas';
import {
@ -758,13 +754,6 @@ export type CanvasEntityIdentifier = Pick<CanvasEntity, 'id' | 'type'>;
export type CanvasV2State = {
_version: 3;
selectedEntityIdentifier: CanvasEntityIdentifier | null;
prompts: {
positivePrompt: ParameterPositivePrompt;
negativePrompt: ParameterNegativePrompt;
positivePrompt2: ParameterPositiveStylePromptSDXL;
negativePrompt2: ParameterNegativeStylePromptSDXL;
shouldConcatPrompts: boolean;
};
tool: {
selected: Tool;
selectedBuffer: Tool | null;
@ -777,7 +766,7 @@ export type CanvasV2State = {
};
fill: RgbaColor;
};
size: {
document: {
width: ParameterWidth;
height: ParameterHeight;
aspectRatio: AspectRatioState;

View File

@ -421,7 +421,7 @@ const addInitialImageLayerToGraph = (
) => {
const { vaePrecision } = state.generation;
const { refinerModel, refinerStart } = state.sdxl;
const { width, height } = state.canvasV2.size;
const { width, height } = state.canvasV2.document;
assert(layer.isEnabled, 'Initial image layer is not enabled');
assert(layer.image, 'Initial image layer has no image');
@ -568,7 +568,7 @@ const buildControlImage = (
const getRGLayerBlobs = async (layerIds?: string[], preview: boolean = false): Promise<Record<string, Blob>> => {
const state = getStore().getState();
const { layers } = state.canvasV2;
const { width, height } = state.canvasV2.size;
const { width, height } = state.canvasV2.document;
const reduxLayers = layers.filter(isRegionalGuidanceLayer);
const container = document.createElement('div');
const stage = new Konva.Stage({ container, width, height });

View File

@ -74,7 +74,7 @@ export const addHRF = (
vaeSource: Invocation<'vae_loader'> | Invocation<'main_model_loader'> | Invocation<'seamless'>
): Invocation<'l2i'> => {
const { hrfStrength, hrfEnabled, hrfMethod } = state.hrf;
const { width, height } = state.canvasV2.size;
const { width, height } = state.canvasV2.document;
const optimalDimension = selectOptimalDimension(state);
const { newWidth: hrfWidth, newHeight: hrfHeight } = calculateHrfRes(optimalDimension, width, height);

View File

@ -40,7 +40,7 @@ export const buildGenerationTabGraph = async (state: RootState): Promise<GraphTy
seed,
vae,
} = state.generation;
const { width, height } = state.controlLayers.present.size;
const { width, height } = state.canvasV2.document;
assert(model, 'No model found in state');

View File

@ -36,7 +36,7 @@ export const buildGenerationTabSDXLGraph = async (state: RootState): Promise<Non
vaePrecision,
vae,
} = state.generation;
const { width, height } = state.controlLayers.present.size;
const { width, height } = state.canvasV2.document;
const { refinerModel, refinerStart } = state.sdxl;

View File

@ -22,7 +22,7 @@ export const getPresetModifiedPrompts = (
state: RootState
): { positivePrompt: string; negativePrompt: string; positiveStylePrompt?: string; negativeStylePrompt?: string } => {
const { positivePrompt, negativePrompt, positivePrompt2, negativePrompt2, shouldConcatPrompts } =
state.canvasV2.prompts;
state.generation;
const { activeStylePresetId } = state.stylePreset;
if (activeStylePresetId) {

View File

@ -1,9 +1,9 @@
import { Box, Textarea } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { negativePromptChanged } from 'features/controlLayers/store/canvasV2Slice';
import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel';
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
import { ViewModePrompt } from 'features/parameters/components/Prompts/ViewModePrompt';
import { negativePromptChanged } from 'features/parameters/store/generationSlice';
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
import { PromptPopover } from 'features/prompt/PromptPopover';
import { usePrompt } from 'features/prompt/usePrompt';
@ -13,7 +13,7 @@ import { useListStylePresetsQuery } from 'services/api/endpoints/stylePresets';
export const ParamNegativePrompt = memo(() => {
const dispatch = useAppDispatch();
const prompt = useAppSelector((s) => s.canvasV2.prompts.negativePrompt);
const prompt = useAppSelector((s) => s.generation.negativePrompt);
const viewMode = useAppSelector((s) => s.stylePreset.viewMode);
const activeStylePresetId = useAppSelector((s) => s.stylePreset.activeStylePresetId);

View File

@ -1,10 +1,10 @@
import { Box, Textarea } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { positivePromptChanged } from 'features/controlLayers/store/canvasV2Slice';
import { ShowDynamicPromptsPreviewButton } from 'features/dynamicPrompts/components/ShowDynamicPromptsPreviewButton';
import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel';
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
import { ViewModePrompt } from 'features/parameters/components/Prompts/ViewModePrompt';
import { positivePromptChanged } from 'features/parameters/store/generationSlice';
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
import { PromptPopover } from 'features/prompt/PromptPopover';
import { usePrompt } from 'features/prompt/usePrompt';
@ -17,7 +17,7 @@ import { useListStylePresetsQuery } from 'services/api/endpoints/stylePresets';
export const ParamPositivePrompt = memo(() => {
const dispatch = useAppDispatch();
const prompt = useAppSelector((s) => s.canvasV2.positivePrompt);
const prompt = useAppSelector((s) => s.generation.positivePrompt);
const baseModel = useAppSelector((s) => s.generation.model)?.base;
const viewMode = useAppSelector((s) => s.stylePreset.viewMode);
const activeStylePresetId = useAppSelector((s) => s.stylePreset.activeStylePresetId);

View File

@ -24,14 +24,8 @@ const initialGenerationState: GenerationState = {
cfgScale: 7.5,
cfgRescaleMultiplier: 0,
img2imgStrength: 0.75,
infillMethod: 'patchmatch',
iterations: 1,
scheduler: 'euler',
maskBlur: 16,
maskBlurMethod: 'box',
canvasCoherenceMode: 'Gaussian Blur',
canvasCoherenceMinDenoise: 0,
canvasCoherenceEdgeSize: 16,
seed: 0,
shouldRandomizeSeed: true,
steps: 50,
@ -43,6 +37,12 @@ const initialGenerationState: GenerationState = {
clipSkip: 0,
shouldUseCpuNoise: true,
shouldShowAdvancedOptions: false,
maskBlur: 16,
maskBlurMethod: 'box',
canvasCoherenceMode: 'Gaussian Blur',
canvasCoherenceMinDenoise: 0,
canvasCoherenceEdgeSize: 16,
infillMethod: 'patchmatch',
infillTileSize: 32,
infillPatchmatchDownscaleSize: 1,
infillMosaicTileWidth: 64,
@ -50,6 +50,11 @@ const initialGenerationState: GenerationState = {
infillMosaicMinColor: { r: 0, g: 0, b: 0, a: 1 },
infillMosaicMaxColor: { r: 255, g: 255, b: 255, a: 1 },
infillColorValue: { r: 0, g: 0, b: 0, a: 1 },
positivePrompt: '',
negativePrompt: '',
positivePrompt2: '',
negativePrompt2: '',
shouldConcatPrompts: true,
};
export const generationSlice = createSlice({
@ -166,6 +171,21 @@ export const generationSlice = createSlice({
setInfillColorValue: (state, action: PayloadAction<RgbaColor>) => {
state.infillColorValue = action.payload;
},
positivePromptChanged: (state, action: PayloadAction<string>) => {
state.positivePrompt = action.payload;
},
negativePromptChanged: (state, action: PayloadAction<string>) => {
state.negativePrompt = action.payload;
},
positivePrompt2Changed: (state, action: PayloadAction<string>) => {
state.positivePrompt2 = action.payload;
},
negativePrompt2Changed: (state, action: PayloadAction<string>) => {
state.negativePrompt2 = action.payload;
},
shouldConcatPromptsChanged: (state, action: PayloadAction<boolean>) => {
state.shouldConcatPrompts = action.payload;
},
},
extraReducers: (builder) => {
builder.addCase(configChanged, (state, action) => {
@ -210,6 +230,11 @@ export const {
setInfillMosaicMinColor,
setInfillMosaicMaxColor,
setInfillColorValue,
positivePromptChanged,
negativePromptChanged,
positivePrompt2Changed,
negativePrompt2Changed,
shouldConcatPromptsChanged,
} = generationSlice.actions;
export const { selectOptimalDimension } = generationSlice.selectors;

View File

@ -5,6 +5,10 @@ import type {
ParameterCFGScale,
ParameterMaskBlurMethod,
ParameterModel,
ParameterNegativePrompt,
ParameterNegativeStylePromptSDXL,
ParameterPositivePrompt,
ParameterPositiveStylePromptSDXL,
ParameterPrecision,
ParameterScheduler,
ParameterSeed,
@ -45,6 +49,11 @@ export interface GenerationState {
infillMosaicMinColor: RgbaColor;
infillMosaicMaxColor: RgbaColor;
infillColorValue: RgbaColor;
positivePrompt: ParameterPositivePrompt;
negativePrompt: ParameterNegativePrompt;
positivePrompt2: ParameterPositiveStylePromptSDXL;
negativePrompt2: ParameterNegativeStylePromptSDXL;
shouldConcatPrompts: boolean;
}
export type PayloadActionWithOptimalDimension<T = void> = PayloadAction<T, string, { optimalDimension: number }>;

View File

@ -1,8 +1,8 @@
import { Box, Textarea } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { negativePrompt2Changed } from 'features/controlLayers/store/canvasV2Slice';
import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel';
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
import { negativePrompt2Changed } from 'features/parameters/store/generationSlice';
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
import { PromptPopover } from 'features/prompt/PromptPopover';
import { usePrompt } from 'features/prompt/usePrompt';
@ -12,7 +12,7 @@ import { useTranslation } from 'react-i18next';
export const ParamSDXLNegativeStylePrompt = memo(() => {
const dispatch = useAppDispatch();
const prompt = useAppSelector((s) => s.canvasV2.negativePrompt2);
const prompt = useAppSelector((s) => s.generation.negativePrompt2);
const textareaRef = useRef<HTMLTextAreaElement>(null);
const { t } = useTranslation();
const handleChange = useCallback(

View File

@ -1,8 +1,8 @@
import { Box, Textarea } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { positivePrompt2Changed } from 'features/controlLayers/store/canvasV2Slice';
import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel';
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
import { positivePrompt2Changed } from 'features/parameters/store/generationSlice';
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
import { PromptPopover } from 'features/prompt/PromptPopover';
import { usePrompt } from 'features/prompt/usePrompt';
@ -11,7 +11,7 @@ import { useTranslation } from 'react-i18next';
export const ParamSDXLPositiveStylePrompt = memo(() => {
const dispatch = useAppDispatch();
const prompt = useAppSelector((s) => s.canvasV2.positivePrompt2);
const prompt = useAppSelector((s) => s.generation.positivePrompt2);
const textareaRef = useRef<HTMLTextAreaElement>(null);
const { t } = useTranslation();
const handleChange = useCallback(

View File

@ -1,12 +1,12 @@
import { IconButton, Tooltip } from '@invoke-ai/ui-library';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { shouldConcatPromptsChanged } from 'features/controlLayers/store/canvasV2Slice';
import { shouldConcatPromptsChanged } from 'features/parameters/store/generationSlice';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { PiLinkSimpleBold, PiLinkSimpleBreakBold } from 'react-icons/pi';
export const SDXLConcatButton = memo(() => {
const shouldConcatPrompts = useAppSelector((s) => s.canvasV2.shouldConcatPrompts);
const shouldConcatPrompts = useAppSelector((s) => s.generation.shouldConcatPrompts);
const dispatch = useAppDispatch();
const { t } = useTranslation();

View File

@ -29,7 +29,7 @@ const selector = createMemoizedSelector(
const badges: string[] = [];
const isSDXL = model?.base === 'sdxl';
const { aspectRatio, width, height } = canvasV2.size;
const { aspectRatio, width, height } = canvasV2.document;
badges.push(`${width}×${height}`);
badges.push(aspectRatio.id);

View File

@ -9,9 +9,9 @@ import { memo, useCallback } from 'react';
export const ImageSizeLinear = memo(() => {
const dispatch = useAppDispatch();
const width = useAppSelector((s) => s.canvasV2.size.width);
const height = useAppSelector((s) => s.canvasV2.size.height);
const aspectRatioState = useAppSelector((s) => s.canvasV2.size.aspectRatio);
const width = useAppSelector((s) => s.canvasV2.document.width);
const height = useAppSelector((s) => s.canvasV2.document.height);
const aspectRatioState = useAppSelector((s) => s.canvasV2.document.aspectRatio);
const onChangeWidth = useCallback(
(width: number) => {