mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): split out params/compositing state from canvas rendering state
First step to restoring undo/redo - the undoable state must be in its own slice. So params and settings must be isolated.
This commit is contained in:
parent
301da97670
commit
1303e18e93
@ -1,5 +1,5 @@
|
||||
import { PropsWithChildren, memo, useEffect } from 'react';
|
||||
import { modelChanged } from '../src/features/controlLayers/store/canvasV2Slice';
|
||||
import { modelChanged } from '../src/features/controlLayers/store/paramsSlice';
|
||||
import { useAppDispatch } from '../src/app/store/storeHooks';
|
||||
import { useGlobalModifiersInit } from '@invoke-ai/ui-library';
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { setInfillMethod } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setInfillMethod } from 'features/controlLayers/store/paramsSlice';
|
||||
import { shouldUseNSFWCheckerChanged, shouldUseWatermarkerChanged } from 'features/system/store/systemSlice';
|
||||
import { appInfoApi } from 'services/api/endpoints/appInfo';
|
||||
|
||||
@ -8,7 +8,7 @@ export const addAppConfigReceivedListener = (startAppListening: AppStartListenin
|
||||
matcher: appInfoApi.endpoints.getAppConfig.matchFulfilled,
|
||||
effect: (action, { getState, dispatch }) => {
|
||||
const { infill_methods = [], nsfw_methods = [], watermarking_methods = [] } = action.payload;
|
||||
const infillMethod = getState().canvasV2.compositing.infillMethod;
|
||||
const infillMethod = getState().params.infillMethod;
|
||||
|
||||
if (!infill_methods.includes(infillMethod)) {
|
||||
// if there is no infill method, set it to the first one
|
||||
|
@ -23,7 +23,7 @@ export const addEnqueueRequestedLinear = (startAppListening: AppStartListening)
|
||||
enqueueRequested.match(action) && action.payload.tabName === 'generation',
|
||||
effect: async (action, { getState, dispatch }) => {
|
||||
const state = getState();
|
||||
const model = state.canvasV2.params.model;
|
||||
const model = state.params.model;
|
||||
const { prepend } = action.payload;
|
||||
|
||||
const manager = $canvasManager.get();
|
||||
|
@ -29,7 +29,7 @@ export const addEnqueueRequestedNodes = (startAppListening: AppStartListening) =
|
||||
batch: {
|
||||
graph,
|
||||
workflow: builtWorkflow,
|
||||
runs: state.canvasV2.params.iterations,
|
||||
runs: state.params.iterations,
|
||||
origin: 'workflows',
|
||||
},
|
||||
prepend: action.payload.prepend,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { logger } from 'app/logging/logger';
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { loraDeleted, modelChanged, vaeSelected } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { loraDeleted } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { modelChanged, vaeSelected } from 'features/controlLayers/store/paramsSlice';
|
||||
import { modelSelected } from 'features/parameters/store/actions';
|
||||
import { zParameterModel } from 'features/parameters/types/parameterSchemas';
|
||||
import { toast } from 'features/toast/toast';
|
||||
@ -23,7 +24,7 @@ export const addModelSelectedListener = (startAppListening: AppStartListening) =
|
||||
const newModel = result.data;
|
||||
|
||||
const newBaseModel = newModel.base;
|
||||
const didBaseModelChange = state.canvasV2.params.model?.base !== newBaseModel;
|
||||
const didBaseModelChange = state.params.model?.base !== newBaseModel;
|
||||
|
||||
if (didBaseModelChange) {
|
||||
// we may need to reset some incompatible submodels
|
||||
@ -38,7 +39,7 @@ export const addModelSelectedListener = (startAppListening: AppStartListening) =
|
||||
});
|
||||
|
||||
// handle incompatible vae
|
||||
const { vae } = state.canvasV2.params;
|
||||
const { vae } = state.params;
|
||||
if (vae && vae.base !== newBaseModel) {
|
||||
dispatch(vaeSelected(null));
|
||||
modelsCleared += 1;
|
||||
@ -66,7 +67,7 @@ export const addModelSelectedListener = (startAppListening: AppStartListening) =
|
||||
}
|
||||
}
|
||||
|
||||
dispatch(modelChanged({ model: newModel, previousModel: state.canvasV2.params.model }));
|
||||
dispatch(modelChanged({ model: newModel, previousModel: state.params.model }));
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -8,11 +8,9 @@ import {
|
||||
controlLayerModelChanged,
|
||||
ipaModelChanged,
|
||||
loraDeleted,
|
||||
modelChanged,
|
||||
refinerModelChanged,
|
||||
rgIPAdapterModelChanged,
|
||||
vaeSelected,
|
||||
} from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { modelChanged, refinerModelChanged, vaeSelected } from 'features/controlLayers/store/paramsSlice';
|
||||
import { getEntityIdentifier } from 'features/controlLayers/store/types';
|
||||
import { calculateNewSize } from 'features/parameters/components/DocumentSize/calculateNewSize';
|
||||
import { postProcessingModelChanged, upscaleModelChanged } from 'features/parameters/store/upscaleSlice';
|
||||
@ -63,7 +61,7 @@ type ModelHandler = (
|
||||
) => undefined;
|
||||
|
||||
const handleMainModels: ModelHandler = (models, state, dispatch, log) => {
|
||||
const currentModel = state.canvasV2.params.model;
|
||||
const currentModel = state.params.model;
|
||||
const mainModels = models.filter(isNonRefinerMainModelConfig);
|
||||
if (mainModels.length === 0) {
|
||||
// No models loaded at all
|
||||
@ -110,7 +108,7 @@ const handleMainModels: ModelHandler = (models, state, dispatch, log) => {
|
||||
};
|
||||
|
||||
const handleRefinerModels: ModelHandler = (models, state, dispatch, _log) => {
|
||||
const currentRefinerModel = state.canvasV2.params.refinerModel;
|
||||
const currentRefinerModel = state.params.refinerModel;
|
||||
const refinerModels = models.filter(isRefinerMainModelModelConfig);
|
||||
if (models.length === 0) {
|
||||
// No models loaded at all
|
||||
@ -129,7 +127,7 @@ const handleRefinerModels: ModelHandler = (models, state, dispatch, _log) => {
|
||||
};
|
||||
|
||||
const handleVAEModels: ModelHandler = (models, state, dispatch, log) => {
|
||||
const currentVae = state.canvasV2.params.vae;
|
||||
const currentVae = state.params.vae;
|
||||
|
||||
if (currentVae === null) {
|
||||
// null is a valid VAE! it means "use the default with the main model"
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { isAnyOf } from '@reduxjs/toolkit';
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { positivePromptChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { positivePromptChanged } from 'features/controlLayers/store/paramsSlice';
|
||||
import {
|
||||
combinatorialToggled,
|
||||
isErrorChanged,
|
||||
|
@ -1,14 +1,13 @@
|
||||
import type { AppStartListening } from 'app/store/middleware/listenerMiddleware';
|
||||
import { bboxHeightChanged, bboxWidthChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import {
|
||||
bboxHeightChanged,
|
||||
bboxWidthChanged,
|
||||
setCfgRescaleMultiplier,
|
||||
setCfgScale,
|
||||
setScheduler,
|
||||
setSteps,
|
||||
vaePrecisionChanged,
|
||||
vaeSelected,
|
||||
} from 'features/controlLayers/store/canvasV2Slice';
|
||||
} from 'features/controlLayers/store/paramsSlice';
|
||||
import { setDefaultSettings } from 'features/parameters/store/actions';
|
||||
import {
|
||||
isParameterCFGRescaleMultiplier,
|
||||
@ -31,7 +30,7 @@ export const addSetDefaultSettingsListener = (startAppListening: AppStartListeni
|
||||
effect: async (action, { dispatch, getState }) => {
|
||||
const state = getState();
|
||||
|
||||
const currentModel = state.canvasV2.params.model;
|
||||
const currentModel = state.params.model;
|
||||
|
||||
if (!currentModel) {
|
||||
return;
|
||||
|
@ -7,6 +7,7 @@ import type { SerializableObject } from 'common/types';
|
||||
import { deepClone } from 'common/util/deepClone';
|
||||
import { changeBoardModalSlice } from 'features/changeBoardModal/store/slice';
|
||||
import { canvasV2PersistConfig, canvasV2Slice } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { paramsPersistConfig, paramsSlice } from 'features/controlLayers/store/paramsSlice';
|
||||
import { deleteImageModalSlice } from 'features/deleteImageModal/store/slice';
|
||||
import { dynamicPromptsPersistConfig, dynamicPromptsSlice } from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
||||
import { galleryPersistConfig, gallerySlice } from 'features/gallery/store/gallerySlice';
|
||||
@ -57,6 +58,7 @@ const allReducers = {
|
||||
[workflowSettingsSlice.name]: workflowSettingsSlice.reducer,
|
||||
[upscaleSlice.name]: upscaleSlice.reducer,
|
||||
[stylePresetSlice.name]: stylePresetSlice.reducer,
|
||||
[paramsSlice.name]: paramsSlice.reducer,
|
||||
};
|
||||
|
||||
const rootReducer = combineReducers(allReducers);
|
||||
@ -98,6 +100,7 @@ const persistConfigs: { [key in keyof typeof allReducers]?: PersistConfig } = {
|
||||
[workflowSettingsPersistConfig.name]: workflowSettingsPersistConfig,
|
||||
[upscalePersistConfig.name]: upscalePersistConfig,
|
||||
[stylePresetPersistConfig.name]: stylePresetPersistConfig,
|
||||
[paramsPersistConfig.name]: paramsPersistConfig,
|
||||
};
|
||||
|
||||
const unserialize: UnserializeFunction = (data, key) => {
|
||||
|
@ -32,7 +32,7 @@ export const useGroupedModelCombobox = <T extends AnyModelConfig>(
|
||||
arg: UseGroupedModelComboboxArg<T>
|
||||
): UseGroupedModelComboboxReturn => {
|
||||
const { t } = useTranslation();
|
||||
const base_model = useAppSelector((s) => s.canvasV2.params.model?.base ?? 'sdxl');
|
||||
const base_model = useAppSelector((s) => s.params.model?.base ?? 'sdxl');
|
||||
const { modelConfigs, selectedModel, getIsDisabled, onChange, isLoading, groupByType = false } = arg;
|
||||
const options = useMemo<GroupBase<ComboboxOption>[]>(() => {
|
||||
if (!modelConfigs) {
|
||||
|
@ -2,6 +2,7 @@ import { useStore } from '@nanostores/react';
|
||||
import { $isConnected } from 'app/hooks/useSocketIO';
|
||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { selectParamsSlice } from 'features/controlLayers/store/paramsSlice';
|
||||
import { selectCanvasV2Slice } from 'features/controlLayers/store/selectors';
|
||||
import { selectDynamicPromptsSlice } from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
||||
import { getShouldProcessPrompt } from 'features/dynamicPrompts/util/getShouldProcessPrompt';
|
||||
@ -34,13 +35,14 @@ const createSelector = (templates: Templates, isConnected: boolean) =>
|
||||
selectWorkflowSettingsSlice,
|
||||
selectDynamicPromptsSlice,
|
||||
selectCanvasV2Slice,
|
||||
selectParamsSlice,
|
||||
selectUpscalelice,
|
||||
selectConfigSlice,
|
||||
selectActiveTab,
|
||||
],
|
||||
(system, nodes, workflowSettings, dynamicPrompts, canvasV2, upscale, config, activeTabName) => {
|
||||
(system, nodes, workflowSettings, dynamicPrompts, canvasV2, params, upscale, config, activeTabName) => {
|
||||
const { bbox } = canvasV2;
|
||||
const { model, positivePrompt } = canvasV2.params;
|
||||
const { model, positivePrompt } = params;
|
||||
|
||||
const reasons: { prefix?: string; content: string }[] = [];
|
||||
|
||||
|
@ -18,7 +18,7 @@ export const ControlLayerControlAdapterModel = memo(({ modelKey, onChange: onCha
|
||||
const { t } = useTranslation();
|
||||
const entityIdentifier = useEntityIdentifierContext();
|
||||
const canvasManager = useCanvasManager();
|
||||
const currentBaseModel = useAppSelector((s) => s.canvasV2.params.model?.base);
|
||||
const currentBaseModel = useAppSelector((s) => s.params.model?.base);
|
||||
const [modelConfigs, { isLoading }] = useControlNetAndT2IAdapterModels();
|
||||
const selectedModel = useMemo(() => modelConfigs.find((m) => m.key === modelKey), [modelConfigs, modelKey]);
|
||||
|
||||
|
@ -24,7 +24,7 @@ type Props = {
|
||||
|
||||
export const IPAdapterModel = memo(({ modelKey, onChangeModel, clipVisionModel, onChangeCLIPVisionModel }: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const currentBaseModel = useAppSelector((s) => s.canvasV2.params.model?.base);
|
||||
const currentBaseModel = useAppSelector((s) => s.params.model?.base);
|
||||
const [modelConfigs, { isLoading }] = useIPAdapterModels();
|
||||
const selectedModel = useMemo(() => modelConfigs.find((m) => m.key === modelKey), [modelConfigs, modelKey]);
|
||||
|
||||
|
@ -30,7 +30,7 @@ export const useControlLayerControlAdapter = (entityIdentifier: CanvasEntityIden
|
||||
export const useDefaultControlAdapter = (): ControlNetConfig | T2IAdapterConfig => {
|
||||
const [modelConfigs] = useControlNetAndT2IAdapterModels();
|
||||
|
||||
const baseModel = useAppSelector((s) => s.canvasV2.params.model?.base);
|
||||
const baseModel = useAppSelector((s) => s.params.model?.base);
|
||||
|
||||
const defaultControlAdapter = useMemo(() => {
|
||||
const compatibleModels = modelConfigs.filter((m) => (baseModel ? m.base === baseModel : true));
|
||||
@ -51,7 +51,7 @@ export const useDefaultControlAdapter = (): ControlNetConfig | T2IAdapterConfig
|
||||
export const useDefaultIPAdapter = (): IPAdapterConfig => {
|
||||
const [modelConfigs] = useIPAdapterModels();
|
||||
|
||||
const baseModel = useAppSelector((s) => s.canvasV2.params.model?.base);
|
||||
const baseModel = useAppSelector((s) => s.params.model?.base);
|
||||
|
||||
const defaultControlAdapter = useMemo(() => {
|
||||
const compatibleModels = modelConfigs.filter((m) => (baseModel ? m.base === baseModel : true));
|
||||
|
@ -6,14 +6,12 @@ import { getScaledBoundingBoxDimensions } from 'features/controlLayers/util/getS
|
||||
import { calculateNewSize } from 'features/parameters/components/DocumentSize/calculateNewSize';
|
||||
import { ASPECT_RATIO_MAP, initialAspectRatioState } from 'features/parameters/components/DocumentSize/constants';
|
||||
import type { AspectRatioID } from 'features/parameters/components/DocumentSize/types';
|
||||
import { getOptimalDimension } from 'features/parameters/util/optimalDimension';
|
||||
import type { IRect } from 'konva/lib/types';
|
||||
|
||||
const syncScaledSize = (state: CanvasV2State) => {
|
||||
if (state.bbox.scaleMethod === 'auto') {
|
||||
const optimalDimension = getOptimalDimension(state.params.model);
|
||||
const { width, height } = state.bbox.rect;
|
||||
state.bbox.scaledSize = getScaledBoundingBoxDimensions({ width, height }, optimalDimension);
|
||||
state.bbox.scaledSize = getScaledBoundingBoxDimensions({ width, height }, state.bbox.optimalDimension);
|
||||
}
|
||||
};
|
||||
|
||||
@ -106,15 +104,14 @@ export const bboxReducers = {
|
||||
syncScaledSize(state);
|
||||
},
|
||||
bboxSizeOptimized: (state) => {
|
||||
const optimalDimension = getOptimalDimension(state.params.model);
|
||||
if (state.bbox.aspectRatio.isLocked) {
|
||||
const { width, height } = calculateNewSize(state.bbox.aspectRatio.value, optimalDimension ** 2);
|
||||
const { width, height } = calculateNewSize(state.bbox.aspectRatio.value, state.bbox.optimalDimension ** 2);
|
||||
state.bbox.rect.width = width;
|
||||
state.bbox.rect.height = height;
|
||||
} else {
|
||||
state.bbox.aspectRatio = deepClone(initialAspectRatioState);
|
||||
state.bbox.rect.width = optimalDimension;
|
||||
state.bbox.rect.height = optimalDimension;
|
||||
state.bbox.rect.width = state.bbox.optimalDimension;
|
||||
state.bbox.rect.height = state.bbox.optimalDimension;
|
||||
}
|
||||
|
||||
syncScaledSize(state);
|
||||
|
@ -5,12 +5,11 @@ import { moveOneToEnd, moveOneToStart, moveToEnd, moveToStart } from 'common/uti
|
||||
import { deepClone } from 'common/util/deepClone';
|
||||
import { getPrefixedId } from 'features/controlLayers/konva/util';
|
||||
import { bboxReducers } from 'features/controlLayers/store/bboxReducers';
|
||||
import { compositingReducers } from 'features/controlLayers/store/compositingReducers';
|
||||
import { controlLayersReducers } from 'features/controlLayers/store/controlLayersReducers';
|
||||
import { inpaintMaskReducers } from 'features/controlLayers/store/inpaintMaskReducers';
|
||||
import { ipAdaptersReducers } from 'features/controlLayers/store/ipAdaptersReducers';
|
||||
import { lorasReducers } from 'features/controlLayers/store/lorasReducers';
|
||||
import { paramsReducers } from 'features/controlLayers/store/paramsReducers';
|
||||
import { modelChanged } from 'features/controlLayers/store/paramsSlice';
|
||||
import { rasterLayersReducers } from 'features/controlLayers/store/rasterLayersReducers';
|
||||
import { regionsReducers } from 'features/controlLayers/store/regionsReducers';
|
||||
import { selectAllEntities, selectAllEntitiesOfType, selectEntity } from 'features/controlLayers/store/selectors';
|
||||
@ -19,8 +18,9 @@ import { settingsReducers } from 'features/controlLayers/store/settingsReducers'
|
||||
import { toolReducers } from 'features/controlLayers/store/toolReducers';
|
||||
import { getScaledBoundingBoxDimensions } from 'features/controlLayers/util/getScaledBoundingBoxDimensions';
|
||||
import { simplifyFlatNumbersArray } from 'features/controlLayers/util/simplify';
|
||||
import { calculateNewSize } from 'features/parameters/components/DocumentSize/calculateNewSize';
|
||||
import { initialAspectRatioState } from 'features/parameters/components/DocumentSize/constants';
|
||||
import { getOptimalDimension } from 'features/parameters/util/optimalDimension';
|
||||
import { getIsSizeOptimal, getOptimalDimension } from 'features/parameters/util/optimalDimension';
|
||||
import { pick } from 'lodash-es';
|
||||
import { assert } from 'tsafe';
|
||||
|
||||
@ -69,6 +69,7 @@ const initialState: CanvasV2State = {
|
||||
},
|
||||
bbox: {
|
||||
rect: { x: 0, y: 0, width: 512, height: 512 },
|
||||
optimalDimension: 512,
|
||||
aspectRatio: deepClone(initialAspectRatioState),
|
||||
scaleMethod: 'auto',
|
||||
scaledSize: {
|
||||
@ -86,46 +87,6 @@ const initialState: CanvasV2State = {
|
||||
cropToBboxOnSave: false,
|
||||
dynamicGrid: false,
|
||||
},
|
||||
compositing: {
|
||||
maskBlur: 16,
|
||||
maskBlurMethod: 'box',
|
||||
canvasCoherenceMode: 'Gaussian Blur',
|
||||
canvasCoherenceMinDenoise: 0,
|
||||
canvasCoherenceEdgeSize: 16,
|
||||
infillMethod: 'patchmatch',
|
||||
infillTileSize: 32,
|
||||
infillPatchmatchDownscaleSize: 1,
|
||||
infillColorValue: { r: 0, g: 0, b: 0, a: 1 },
|
||||
},
|
||||
params: {
|
||||
cfgScale: 7.5,
|
||||
cfgRescaleMultiplier: 0,
|
||||
img2imgStrength: 0.75,
|
||||
iterations: 1,
|
||||
scheduler: 'euler',
|
||||
seed: 0,
|
||||
shouldRandomizeSeed: true,
|
||||
steps: 50,
|
||||
model: null,
|
||||
vae: null,
|
||||
vaePrecision: 'fp32',
|
||||
seamlessXAxis: false,
|
||||
seamlessYAxis: false,
|
||||
clipSkip: 0,
|
||||
shouldUseCpuNoise: true,
|
||||
positivePrompt: '',
|
||||
negativePrompt: '',
|
||||
positivePrompt2: '',
|
||||
negativePrompt2: '',
|
||||
shouldConcatPrompts: true,
|
||||
refinerModel: null,
|
||||
refinerSteps: 20,
|
||||
refinerCFGScale: 7.5,
|
||||
refinerScheduler: 'euler',
|
||||
refinerPositiveAestheticScore: 6,
|
||||
refinerNegativeAestheticScore: 2.5,
|
||||
refinerStart: 0.8,
|
||||
},
|
||||
session: {
|
||||
mode: 'generate',
|
||||
isStaging: false,
|
||||
@ -147,8 +108,6 @@ export const canvasV2Slice = createSlice({
|
||||
...bboxReducers,
|
||||
// move out
|
||||
...lorasReducers,
|
||||
...paramsReducers,
|
||||
...compositingReducers,
|
||||
...settingsReducers,
|
||||
...toolReducers,
|
||||
...sessionReducers,
|
||||
@ -400,11 +359,10 @@ export const canvasV2Slice = createSlice({
|
||||
},
|
||||
canvasReset: (state) => {
|
||||
state.bbox = deepClone(initialState.bbox);
|
||||
const optimalDimension = getOptimalDimension(state.params.model);
|
||||
state.bbox.rect.width = optimalDimension;
|
||||
state.bbox.rect.height = optimalDimension;
|
||||
state.bbox.rect.width = state.bbox.optimalDimension;
|
||||
state.bbox.rect.height = state.bbox.optimalDimension;
|
||||
const size = pick(state.bbox.rect, 'width', 'height');
|
||||
state.bbox.scaledSize = getScaledBoundingBoxDimensions(size, optimalDimension);
|
||||
state.bbox.scaledSize = getScaledBoundingBoxDimensions(size, state.bbox.optimalDimension);
|
||||
state.session = deepClone(initialState.session);
|
||||
state.tool = deepClone(initialState.tool);
|
||||
|
||||
@ -417,6 +375,31 @@ export const canvasV2Slice = createSlice({
|
||||
state.selectedEntityIdentifier = deepClone(initialState.selectedEntityIdentifier);
|
||||
},
|
||||
},
|
||||
extraReducers(builder) {
|
||||
builder.addCase(modelChanged, (state, action) => {
|
||||
const { model, previousModel } = action.payload;
|
||||
|
||||
// If the model base changes (e.g. SD1.5 -> SDXL), we need to change a few things
|
||||
if (model === null || previousModel?.base === model.base) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the bbox size to match the new model's optimal size
|
||||
const optimalDimension = getOptimalDimension(model);
|
||||
|
||||
state.bbox.optimalDimension = optimalDimension;
|
||||
|
||||
if (!getIsSizeOptimal(state.bbox.rect.width, state.bbox.rect.height, optimalDimension)) {
|
||||
const bboxDims = calculateNewSize(state.bbox.aspectRatio.value, optimalDimension * optimalDimension);
|
||||
state.bbox.rect.width = bboxDims.width;
|
||||
state.bbox.rect.height = bboxDims.height;
|
||||
|
||||
if (state.bbox.scaleMethod === 'auto') {
|
||||
state.bbox.scaledSize = getScaledBoundingBoxDimensions(bboxDims, optimalDimension);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
@ -495,43 +478,6 @@ export const {
|
||||
rgIPAdapterMethodChanged,
|
||||
rgIPAdapterModelChanged,
|
||||
rgIPAdapterCLIPVisionModelChanged,
|
||||
// Compositing
|
||||
setInfillMethod,
|
||||
setInfillTileSize,
|
||||
setInfillPatchmatchDownscaleSize,
|
||||
setInfillColorValue,
|
||||
setMaskBlur,
|
||||
setCanvasCoherenceMode,
|
||||
setCanvasCoherenceEdgeSize,
|
||||
setCanvasCoherenceMinDenoise,
|
||||
// Parameters
|
||||
setIterations,
|
||||
setSteps,
|
||||
setCfgScale,
|
||||
setCfgRescaleMultiplier,
|
||||
setScheduler,
|
||||
setSeed,
|
||||
setImg2imgStrength,
|
||||
setSeamlessXAxis,
|
||||
setSeamlessYAxis,
|
||||
setShouldRandomizeSeed,
|
||||
vaeSelected,
|
||||
vaePrecisionChanged,
|
||||
setClipSkip,
|
||||
shouldUseCpuNoiseChanged,
|
||||
positivePromptChanged,
|
||||
negativePromptChanged,
|
||||
positivePrompt2Changed,
|
||||
negativePrompt2Changed,
|
||||
shouldConcatPromptsChanged,
|
||||
refinerModelChanged,
|
||||
setRefinerSteps,
|
||||
setRefinerCFGScale,
|
||||
setRefinerScheduler,
|
||||
setRefinerPositiveAestheticScore,
|
||||
setRefinerNegativeAestheticScore,
|
||||
setRefinerStart,
|
||||
modelChanged,
|
||||
// LoRAs
|
||||
loraAdded,
|
||||
loraRecalled,
|
||||
|
@ -1,30 +0,0 @@
|
||||
import type { PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
|
||||
import type { CanvasV2State, RgbaColor } from 'features/controlLayers/store/types';
|
||||
import type { ParameterCanvasCoherenceMode } from 'features/parameters/types/parameterSchemas';
|
||||
|
||||
export const compositingReducers = {
|
||||
setInfillMethod: (state, action: PayloadAction<string>) => {
|
||||
state.compositing.infillMethod = action.payload;
|
||||
},
|
||||
setInfillTileSize: (state, action: PayloadAction<number>) => {
|
||||
state.compositing.infillTileSize = action.payload;
|
||||
},
|
||||
setInfillPatchmatchDownscaleSize: (state, action: PayloadAction<number>) => {
|
||||
state.compositing.infillPatchmatchDownscaleSize = action.payload;
|
||||
},
|
||||
setInfillColorValue: (state, action: PayloadAction<RgbaColor>) => {
|
||||
state.compositing.infillColorValue = action.payload;
|
||||
},
|
||||
setMaskBlur: (state, action: PayloadAction<number>) => {
|
||||
state.compositing.maskBlur = action.payload;
|
||||
},
|
||||
setCanvasCoherenceMode: (state, action: PayloadAction<ParameterCanvasCoherenceMode>) => {
|
||||
state.compositing.canvasCoherenceMode = action.payload;
|
||||
},
|
||||
setCanvasCoherenceEdgeSize: (state, action: PayloadAction<number>) => {
|
||||
state.compositing.canvasCoherenceEdgeSize = action.payload;
|
||||
},
|
||||
setCanvasCoherenceMinDenoise: (state, action: PayloadAction<number>) => {
|
||||
state.compositing.canvasCoherenceMinDenoise = action.payload;
|
||||
},
|
||||
} satisfies SliceCaseReducers<CanvasV2State>;
|
@ -1,132 +0,0 @@
|
||||
import type { PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
|
||||
import type { CanvasV2State } from 'features/controlLayers/store/types';
|
||||
import { getScaledBoundingBoxDimensions } from 'features/controlLayers/util/getScaledBoundingBoxDimensions';
|
||||
import { calculateNewSize } from 'features/parameters/components/DocumentSize/calculateNewSize';
|
||||
import { CLIP_SKIP_MAP } from 'features/parameters/types/constants';
|
||||
import type {
|
||||
ParameterCFGRescaleMultiplier,
|
||||
ParameterCFGScale,
|
||||
ParameterModel,
|
||||
ParameterPrecision,
|
||||
ParameterScheduler,
|
||||
ParameterSDXLRefinerModel,
|
||||
ParameterVAEModel,
|
||||
} from 'features/parameters/types/parameterSchemas';
|
||||
import { getIsSizeOptimal, getOptimalDimension } from 'features/parameters/util/optimalDimension';
|
||||
import { clamp } from 'lodash-es';
|
||||
|
||||
export const paramsReducers = {
|
||||
setIterations: (state, action: PayloadAction<number>) => {
|
||||
state.params.iterations = action.payload;
|
||||
},
|
||||
setSteps: (state, action: PayloadAction<number>) => {
|
||||
state.params.steps = action.payload;
|
||||
},
|
||||
setCfgScale: (state, action: PayloadAction<ParameterCFGScale>) => {
|
||||
state.params.cfgScale = action.payload;
|
||||
},
|
||||
setCfgRescaleMultiplier: (state, action: PayloadAction<ParameterCFGRescaleMultiplier>) => {
|
||||
state.params.cfgRescaleMultiplier = action.payload;
|
||||
},
|
||||
setScheduler: (state, action: PayloadAction<ParameterScheduler>) => {
|
||||
state.params.scheduler = action.payload;
|
||||
},
|
||||
setSeed: (state, action: PayloadAction<number>) => {
|
||||
state.params.seed = action.payload;
|
||||
state.params.shouldRandomizeSeed = false;
|
||||
},
|
||||
setImg2imgStrength: (state, action: PayloadAction<number>) => {
|
||||
state.params.img2imgStrength = action.payload;
|
||||
},
|
||||
setSeamlessXAxis: (state, action: PayloadAction<boolean>) => {
|
||||
state.params.seamlessXAxis = action.payload;
|
||||
},
|
||||
setSeamlessYAxis: (state, action: PayloadAction<boolean>) => {
|
||||
state.params.seamlessYAxis = action.payload;
|
||||
},
|
||||
setShouldRandomizeSeed: (state, action: PayloadAction<boolean>) => {
|
||||
state.params.shouldRandomizeSeed = action.payload;
|
||||
},
|
||||
modelChanged: (
|
||||
state,
|
||||
action: PayloadAction<{ model: ParameterModel | null; previousModel?: ParameterModel | null }>
|
||||
) => {
|
||||
const { model, previousModel } = action.payload;
|
||||
state.params.model = model;
|
||||
|
||||
// If the model base changes (e.g. SD1.5 -> SDXL), we need to change a few things
|
||||
if (model === null || previousModel?.base === model.base) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the bbox size to match the new model's optimal size
|
||||
const optimalDimension = getOptimalDimension(model);
|
||||
if (!getIsSizeOptimal(state.bbox.rect.width, state.bbox.rect.height, optimalDimension)) {
|
||||
const bboxDims = calculateNewSize(state.bbox.aspectRatio.value, optimalDimension * optimalDimension);
|
||||
state.bbox.rect.width = bboxDims.width;
|
||||
state.bbox.rect.height = bboxDims.height;
|
||||
|
||||
if (state.bbox.scaleMethod === 'auto') {
|
||||
state.bbox.scaledSize = getScaledBoundingBoxDimensions(bboxDims, optimalDimension);
|
||||
}
|
||||
}
|
||||
|
||||
// Clamp CLIP skip layer count to the bounds of the new model
|
||||
if (model.base === 'sdxl') {
|
||||
// We don't support user-defined CLIP skip for SDXL because it doesn't do anything useful
|
||||
state.params.clipSkip = 0;
|
||||
} else {
|
||||
const { maxClip } = CLIP_SKIP_MAP[model.base];
|
||||
state.params.clipSkip = clamp(state.params.clipSkip, 0, maxClip);
|
||||
}
|
||||
},
|
||||
vaeSelected: (state, action: PayloadAction<ParameterVAEModel | null>) => {
|
||||
// null is a valid VAE!
|
||||
state.params.vae = action.payload;
|
||||
},
|
||||
vaePrecisionChanged: (state, action: PayloadAction<ParameterPrecision>) => {
|
||||
state.params.vaePrecision = action.payload;
|
||||
},
|
||||
setClipSkip: (state, action: PayloadAction<number>) => {
|
||||
state.params.clipSkip = action.payload;
|
||||
},
|
||||
shouldUseCpuNoiseChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.params.shouldUseCpuNoise = action.payload;
|
||||
},
|
||||
positivePromptChanged: (state, action: PayloadAction<string>) => {
|
||||
state.params.positivePrompt = action.payload;
|
||||
},
|
||||
negativePromptChanged: (state, action: PayloadAction<string>) => {
|
||||
state.params.negativePrompt = action.payload;
|
||||
},
|
||||
positivePrompt2Changed: (state, action: PayloadAction<string>) => {
|
||||
state.params.positivePrompt2 = action.payload;
|
||||
},
|
||||
negativePrompt2Changed: (state, action: PayloadAction<string>) => {
|
||||
state.params.negativePrompt2 = action.payload;
|
||||
},
|
||||
shouldConcatPromptsChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.params.shouldConcatPrompts = action.payload;
|
||||
},
|
||||
refinerModelChanged: (state, action: PayloadAction<ParameterSDXLRefinerModel | null>) => {
|
||||
state.params.refinerModel = action.payload;
|
||||
},
|
||||
setRefinerSteps: (state, action: PayloadAction<number>) => {
|
||||
state.params.refinerSteps = action.payload;
|
||||
},
|
||||
setRefinerCFGScale: (state, action: PayloadAction<number>) => {
|
||||
state.params.refinerCFGScale = action.payload;
|
||||
},
|
||||
setRefinerScheduler: (state, action: PayloadAction<ParameterScheduler>) => {
|
||||
state.params.refinerScheduler = action.payload;
|
||||
},
|
||||
setRefinerPositiveAestheticScore: (state, action: PayloadAction<number>) => {
|
||||
state.params.refinerPositiveAestheticScore = action.payload;
|
||||
},
|
||||
setRefinerNegativeAestheticScore: (state, action: PayloadAction<number>) => {
|
||||
state.params.refinerNegativeAestheticScore = action.payload;
|
||||
},
|
||||
setRefinerStart: (state, action: PayloadAction<number>) => {
|
||||
state.params.refinerStart = action.payload;
|
||||
},
|
||||
} satisfies SliceCaseReducers<CanvasV2State>;
|
@ -0,0 +1,285 @@
|
||||
import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
|
||||
import type { PersistConfig, RootState } from 'app/store/store';
|
||||
import type { RgbaColor } from 'features/controlLayers/store/types';
|
||||
import { CLIP_SKIP_MAP } from 'features/parameters/types/constants';
|
||||
import type {
|
||||
ParameterCanvasCoherenceMode,
|
||||
ParameterCFGRescaleMultiplier,
|
||||
ParameterCFGScale,
|
||||
ParameterMaskBlurMethod,
|
||||
ParameterModel,
|
||||
ParameterNegativePrompt,
|
||||
ParameterNegativeStylePromptSDXL,
|
||||
ParameterPositivePrompt,
|
||||
ParameterPositiveStylePromptSDXL,
|
||||
ParameterPrecision,
|
||||
ParameterScheduler,
|
||||
ParameterSDXLRefinerModel,
|
||||
ParameterSeed,
|
||||
ParameterSteps,
|
||||
ParameterStrength,
|
||||
ParameterVAEModel,
|
||||
} from 'features/parameters/types/parameterSchemas';
|
||||
import { clamp } from 'lodash-es';
|
||||
|
||||
export type ParamsState = {
|
||||
maskBlur: number;
|
||||
maskBlurMethod: ParameterMaskBlurMethod;
|
||||
canvasCoherenceMode: ParameterCanvasCoherenceMode;
|
||||
canvasCoherenceMinDenoise: ParameterStrength;
|
||||
canvasCoherenceEdgeSize: number;
|
||||
infillMethod: string;
|
||||
infillTileSize: number;
|
||||
infillPatchmatchDownscaleSize: number;
|
||||
infillColorValue: RgbaColor;
|
||||
cfgScale: ParameterCFGScale;
|
||||
cfgRescaleMultiplier: ParameterCFGRescaleMultiplier;
|
||||
img2imgStrength: ParameterStrength;
|
||||
iterations: number;
|
||||
scheduler: ParameterScheduler;
|
||||
seed: ParameterSeed;
|
||||
shouldRandomizeSeed: boolean;
|
||||
steps: ParameterSteps;
|
||||
model: ParameterModel | null;
|
||||
vae: ParameterVAEModel | null;
|
||||
vaePrecision: ParameterPrecision;
|
||||
seamlessXAxis: boolean;
|
||||
seamlessYAxis: boolean;
|
||||
clipSkip: number;
|
||||
shouldUseCpuNoise: boolean;
|
||||
positivePrompt: ParameterPositivePrompt;
|
||||
negativePrompt: ParameterNegativePrompt;
|
||||
positivePrompt2: ParameterPositiveStylePromptSDXL;
|
||||
negativePrompt2: ParameterNegativeStylePromptSDXL;
|
||||
shouldConcatPrompts: boolean;
|
||||
refinerModel: ParameterSDXLRefinerModel | null;
|
||||
refinerSteps: number;
|
||||
refinerCFGScale: number;
|
||||
refinerScheduler: ParameterScheduler;
|
||||
refinerPositiveAestheticScore: number;
|
||||
refinerNegativeAestheticScore: number;
|
||||
refinerStart: number;
|
||||
};
|
||||
|
||||
const initialState: ParamsState = {
|
||||
maskBlur: 16,
|
||||
maskBlurMethod: 'box',
|
||||
canvasCoherenceMode: 'Gaussian Blur',
|
||||
canvasCoherenceMinDenoise: 0,
|
||||
canvasCoherenceEdgeSize: 16,
|
||||
infillMethod: 'patchmatch',
|
||||
infillTileSize: 32,
|
||||
infillPatchmatchDownscaleSize: 1,
|
||||
infillColorValue: { r: 0, g: 0, b: 0, a: 1 },
|
||||
cfgScale: 7.5,
|
||||
cfgRescaleMultiplier: 0,
|
||||
img2imgStrength: 0.75,
|
||||
iterations: 1,
|
||||
scheduler: 'euler',
|
||||
seed: 0,
|
||||
shouldRandomizeSeed: true,
|
||||
steps: 50,
|
||||
model: null,
|
||||
vae: null,
|
||||
vaePrecision: 'fp32',
|
||||
seamlessXAxis: false,
|
||||
seamlessYAxis: false,
|
||||
clipSkip: 0,
|
||||
shouldUseCpuNoise: true,
|
||||
positivePrompt: '',
|
||||
negativePrompt: '',
|
||||
positivePrompt2: '',
|
||||
negativePrompt2: '',
|
||||
shouldConcatPrompts: true,
|
||||
refinerModel: null,
|
||||
refinerSteps: 20,
|
||||
refinerCFGScale: 7.5,
|
||||
refinerScheduler: 'euler',
|
||||
refinerPositiveAestheticScore: 6,
|
||||
refinerNegativeAestheticScore: 2.5,
|
||||
refinerStart: 0.8,
|
||||
};
|
||||
|
||||
export const paramsSlice = createSlice({
|
||||
name: 'params',
|
||||
initialState,
|
||||
reducers: {
|
||||
setIterations: (state, action: PayloadAction<number>) => {
|
||||
state.iterations = action.payload;
|
||||
},
|
||||
setSteps: (state, action: PayloadAction<number>) => {
|
||||
state.steps = action.payload;
|
||||
},
|
||||
setCfgScale: (state, action: PayloadAction<ParameterCFGScale>) => {
|
||||
state.cfgScale = action.payload;
|
||||
},
|
||||
setCfgRescaleMultiplier: (state, action: PayloadAction<ParameterCFGRescaleMultiplier>) => {
|
||||
state.cfgRescaleMultiplier = action.payload;
|
||||
},
|
||||
setScheduler: (state, action: PayloadAction<ParameterScheduler>) => {
|
||||
state.scheduler = action.payload;
|
||||
},
|
||||
setSeed: (state, action: PayloadAction<number>) => {
|
||||
state.seed = action.payload;
|
||||
state.shouldRandomizeSeed = false;
|
||||
},
|
||||
setImg2imgStrength: (state, action: PayloadAction<number>) => {
|
||||
state.img2imgStrength = action.payload;
|
||||
},
|
||||
setSeamlessXAxis: (state, action: PayloadAction<boolean>) => {
|
||||
state.seamlessXAxis = action.payload;
|
||||
},
|
||||
setSeamlessYAxis: (state, action: PayloadAction<boolean>) => {
|
||||
state.seamlessYAxis = action.payload;
|
||||
},
|
||||
setShouldRandomizeSeed: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldRandomizeSeed = action.payload;
|
||||
},
|
||||
modelChanged: (
|
||||
state,
|
||||
action: PayloadAction<{ model: ParameterModel | null; previousModel?: ParameterModel | null }>
|
||||
) => {
|
||||
const { model, previousModel } = action.payload;
|
||||
state.model = model;
|
||||
|
||||
// If the model base changes (e.g. SD1.5 -> SDXL), we need to change a few things
|
||||
if (model === null || previousModel?.base === model.base) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Clamp CLIP skip layer count to the bounds of the new model
|
||||
if (model.base === 'sdxl') {
|
||||
// We don't support user-defined CLIP skip for SDXL because it doesn't do anything useful
|
||||
state.clipSkip = 0;
|
||||
} else {
|
||||
const { maxClip } = CLIP_SKIP_MAP[model.base];
|
||||
state.clipSkip = clamp(state.clipSkip, 0, maxClip);
|
||||
}
|
||||
},
|
||||
vaeSelected: (state, action: PayloadAction<ParameterVAEModel | null>) => {
|
||||
// null is a valid VAE!
|
||||
state.vae = action.payload;
|
||||
},
|
||||
vaePrecisionChanged: (state, action: PayloadAction<ParameterPrecision>) => {
|
||||
state.vaePrecision = action.payload;
|
||||
},
|
||||
setClipSkip: (state, action: PayloadAction<number>) => {
|
||||
state.clipSkip = action.payload;
|
||||
},
|
||||
shouldUseCpuNoiseChanged: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldUseCpuNoise = 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;
|
||||
},
|
||||
refinerModelChanged: (state, action: PayloadAction<ParameterSDXLRefinerModel | null>) => {
|
||||
state.refinerModel = action.payload;
|
||||
},
|
||||
setRefinerSteps: (state, action: PayloadAction<number>) => {
|
||||
state.refinerSteps = action.payload;
|
||||
},
|
||||
setRefinerCFGScale: (state, action: PayloadAction<number>) => {
|
||||
state.refinerCFGScale = action.payload;
|
||||
},
|
||||
setRefinerScheduler: (state, action: PayloadAction<ParameterScheduler>) => {
|
||||
state.refinerScheduler = action.payload;
|
||||
},
|
||||
setRefinerPositiveAestheticScore: (state, action: PayloadAction<number>) => {
|
||||
state.refinerPositiveAestheticScore = action.payload;
|
||||
},
|
||||
setRefinerNegativeAestheticScore: (state, action: PayloadAction<number>) => {
|
||||
state.refinerNegativeAestheticScore = action.payload;
|
||||
},
|
||||
setRefinerStart: (state, action: PayloadAction<number>) => {
|
||||
state.refinerStart = action.payload;
|
||||
},
|
||||
setInfillMethod: (state, action: PayloadAction<string>) => {
|
||||
state.infillMethod = action.payload;
|
||||
},
|
||||
setInfillTileSize: (state, action: PayloadAction<number>) => {
|
||||
state.infillTileSize = action.payload;
|
||||
},
|
||||
setInfillPatchmatchDownscaleSize: (state, action: PayloadAction<number>) => {
|
||||
state.infillPatchmatchDownscaleSize = action.payload;
|
||||
},
|
||||
setInfillColorValue: (state, action: PayloadAction<RgbaColor>) => {
|
||||
state.infillColorValue = action.payload;
|
||||
},
|
||||
setMaskBlur: (state, action: PayloadAction<number>) => {
|
||||
state.maskBlur = action.payload;
|
||||
},
|
||||
setCanvasCoherenceMode: (state, action: PayloadAction<ParameterCanvasCoherenceMode>) => {
|
||||
state.canvasCoherenceMode = action.payload;
|
||||
},
|
||||
setCanvasCoherenceEdgeSize: (state, action: PayloadAction<number>) => {
|
||||
state.canvasCoherenceEdgeSize = action.payload;
|
||||
},
|
||||
setCanvasCoherenceMinDenoise: (state, action: PayloadAction<number>) => {
|
||||
state.canvasCoherenceMinDenoise = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
setInfillMethod,
|
||||
setInfillTileSize,
|
||||
setInfillPatchmatchDownscaleSize,
|
||||
setInfillColorValue,
|
||||
setMaskBlur,
|
||||
setCanvasCoherenceMode,
|
||||
setCanvasCoherenceEdgeSize,
|
||||
setCanvasCoherenceMinDenoise,
|
||||
setIterations,
|
||||
setSteps,
|
||||
setCfgScale,
|
||||
setCfgRescaleMultiplier,
|
||||
setScheduler,
|
||||
setSeed,
|
||||
setImg2imgStrength,
|
||||
setSeamlessXAxis,
|
||||
setSeamlessYAxis,
|
||||
setShouldRandomizeSeed,
|
||||
vaeSelected,
|
||||
vaePrecisionChanged,
|
||||
setClipSkip,
|
||||
shouldUseCpuNoiseChanged,
|
||||
positivePromptChanged,
|
||||
negativePromptChanged,
|
||||
positivePrompt2Changed,
|
||||
negativePrompt2Changed,
|
||||
shouldConcatPromptsChanged,
|
||||
refinerModelChanged,
|
||||
setRefinerSteps,
|
||||
setRefinerCFGScale,
|
||||
setRefinerScheduler,
|
||||
setRefinerPositiveAestheticScore,
|
||||
setRefinerNegativeAestheticScore,
|
||||
setRefinerStart,
|
||||
modelChanged,
|
||||
} = paramsSlice.actions;
|
||||
|
||||
export const selectParamsSlice = (state: RootState) => state.params;
|
||||
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
const migrate = (state: any): any => {
|
||||
return state;
|
||||
};
|
||||
|
||||
export const paramsPersistConfig: PersistConfig<ParamsState> = {
|
||||
name: paramsSlice.name,
|
||||
initialState,
|
||||
migrate,
|
||||
persistDenylist: [],
|
||||
};
|
@ -1,5 +1,6 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import type { RootState } from 'app/store/store';
|
||||
import { selectParamsSlice } from 'features/controlLayers/store/paramsSlice';
|
||||
import type {
|
||||
CanvasControlLayerState,
|
||||
CanvasEntityIdentifier,
|
||||
@ -40,8 +41,8 @@ export const selectEntityCount = createSelector(selectCanvasV2Slice, (canvasV2)
|
||||
/**
|
||||
* Selects the optimal dimension for the canvas based on the currently-model
|
||||
*/
|
||||
export const selectOptimalDimension = createSelector(selectCanvasV2Slice, (canvasV2) => {
|
||||
return getOptimalDimension(canvasV2.params.model);
|
||||
export const selectOptimalDimension = createSelector(selectParamsSlice, (params) => {
|
||||
return getOptimalDimension(params.model);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -2,27 +2,7 @@ import type { SerializableObject } from 'common/types';
|
||||
import { getPrefixedId } from 'features/controlLayers/konva/util';
|
||||
import { zModelIdentifierField } from 'features/nodes/types/common';
|
||||
import type { AspectRatioState } from 'features/parameters/components/DocumentSize/types';
|
||||
import type {
|
||||
ParameterCanvasCoherenceMode,
|
||||
ParameterCFGRescaleMultiplier,
|
||||
ParameterCFGScale,
|
||||
ParameterHeight,
|
||||
ParameterLoRAModel,
|
||||
ParameterMaskBlurMethod,
|
||||
ParameterModel,
|
||||
ParameterNegativePrompt,
|
||||
ParameterNegativeStylePromptSDXL,
|
||||
ParameterPositivePrompt,
|
||||
ParameterPositiveStylePromptSDXL,
|
||||
ParameterPrecision,
|
||||
ParameterScheduler,
|
||||
ParameterSDXLRefinerModel,
|
||||
ParameterSeed,
|
||||
ParameterSteps,
|
||||
ParameterStrength,
|
||||
ParameterVAEModel,
|
||||
ParameterWidth,
|
||||
} from 'features/parameters/types/parameterSchemas';
|
||||
import type { ParameterHeight, ParameterLoRAModel, ParameterWidth } from 'features/parameters/types/parameterSchemas';
|
||||
import { zParameterNegativePrompt, zParameterPositivePrompt } from 'features/parameters/types/parameterSchemas';
|
||||
import type { AnyInvocation, BaseModelType, ImageDTO, S } from 'services/api/types';
|
||||
import { z } from 'zod';
|
||||
@ -763,46 +743,7 @@ export type CanvasV2State = {
|
||||
height: ParameterHeight;
|
||||
};
|
||||
scaleMethod: BoundingBoxScaleMethod;
|
||||
};
|
||||
compositing: {
|
||||
maskBlur: number;
|
||||
maskBlurMethod: ParameterMaskBlurMethod;
|
||||
canvasCoherenceMode: ParameterCanvasCoherenceMode;
|
||||
canvasCoherenceMinDenoise: ParameterStrength;
|
||||
canvasCoherenceEdgeSize: number;
|
||||
infillMethod: string;
|
||||
infillTileSize: number;
|
||||
infillPatchmatchDownscaleSize: number;
|
||||
infillColorValue: RgbaColor;
|
||||
};
|
||||
params: {
|
||||
cfgScale: ParameterCFGScale;
|
||||
cfgRescaleMultiplier: ParameterCFGRescaleMultiplier;
|
||||
img2imgStrength: ParameterStrength;
|
||||
iterations: number;
|
||||
scheduler: ParameterScheduler;
|
||||
seed: ParameterSeed;
|
||||
shouldRandomizeSeed: boolean;
|
||||
steps: ParameterSteps;
|
||||
model: ParameterModel | null;
|
||||
vae: ParameterVAEModel | null;
|
||||
vaePrecision: ParameterPrecision;
|
||||
seamlessXAxis: boolean;
|
||||
seamlessYAxis: boolean;
|
||||
clipSkip: number;
|
||||
shouldUseCpuNoise: boolean;
|
||||
positivePrompt: ParameterPositivePrompt;
|
||||
negativePrompt: ParameterNegativePrompt;
|
||||
positivePrompt2: ParameterPositiveStylePromptSDXL;
|
||||
negativePrompt2: ParameterNegativeStylePromptSDXL;
|
||||
shouldConcatPrompts: boolean;
|
||||
refinerModel: ParameterSDXLRefinerModel | null;
|
||||
refinerSteps: number;
|
||||
refinerCFGScale: number;
|
||||
refinerScheduler: ParameterScheduler;
|
||||
refinerPositiveAestheticScore: number;
|
||||
refinerNegativeAestheticScore: number;
|
||||
refinerStart: number;
|
||||
optimalDimension: number;
|
||||
};
|
||||
session: {
|
||||
mode: SessionMode;
|
||||
|
@ -18,7 +18,7 @@ const LoRASelect = () => {
|
||||
const [modelConfigs, { isLoading }] = useLoRAModels();
|
||||
const { t } = useTranslation();
|
||||
const addedLoRAs = useAppSelector(selectLoRAs);
|
||||
const currentBaseModel = useAppSelector((s) => s.canvasV2.params.model?.base);
|
||||
const currentBaseModel = useAppSelector((s) => s.params.model?.base);
|
||||
|
||||
const getIsDisabled = (model: LoRAModelConfig): boolean => {
|
||||
const isCompatible = currentBaseModel === model.base;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { getStore } from 'app/store/nanostores/store';
|
||||
import { deepClone } from 'common/util/deepClone';
|
||||
import { objectKeys } from 'common/util/objectKeys';
|
||||
import { shouldConcatPromptsChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { shouldConcatPromptsChanged } from 'features/controlLayers/store/paramsSlice';
|
||||
import type { LoRA } from 'features/controlLayers/store/types';
|
||||
import type {
|
||||
BuildMetadataHandlers,
|
||||
|
@ -4,6 +4,8 @@ import {
|
||||
bboxWidthChanged,
|
||||
loraAllDeleted,
|
||||
loraRecalled,
|
||||
} from 'features/controlLayers/store/canvasV2Slice';
|
||||
import {
|
||||
negativePrompt2Changed,
|
||||
negativePromptChanged,
|
||||
positivePrompt2Changed,
|
||||
@ -22,7 +24,7 @@ import {
|
||||
setSeed,
|
||||
setSteps,
|
||||
vaeSelected,
|
||||
} from 'features/controlLayers/store/canvasV2Slice';
|
||||
} from 'features/controlLayers/store/paramsSlice';
|
||||
import type { LoRA } from 'features/controlLayers/store/types';
|
||||
import { setHrfEnabled, setHrfMethod, setHrfStrength } from 'features/hrf/store/hrfSlice';
|
||||
import type { MetadataRecallFunc } from 'features/metadata/types';
|
||||
|
@ -20,7 +20,7 @@ const validateBaseCompatibility = (base?: BaseModelType, message?: string) => {
|
||||
if (!base) {
|
||||
throw new InvalidModelConfigError(message || 'Missing base');
|
||||
}
|
||||
const currentBase = getStore().getState().canvasV2.params.model?.base;
|
||||
const currentBase = getStore().getState().params.model?.base;
|
||||
if (currentBase && base !== currentBase) {
|
||||
throw new InvalidModelConfigError(message || `Incompatible base models: ${base} and ${currentBase}`);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ export const prepareLinearUIBatch = (
|
||||
noise: Invocation<'noise'>,
|
||||
posCond: Invocation<'compel' | 'sdxl_compel_prompt'>
|
||||
): BatchConfig => {
|
||||
const { iterations, model, shouldRandomizeSeed, seed, shouldConcatPrompts } = state.canvasV2.params;
|
||||
const { iterations, model, shouldRandomizeSeed, seed, shouldConcatPrompts } = state.params;
|
||||
const { prompts, seedBehaviour } = state.dynamicPrompts;
|
||||
|
||||
const data: Batch['data'] = [];
|
||||
|
@ -13,7 +13,7 @@ import { getBoardField, getPresetModifiedPrompts } from './graphBuilderUtils';
|
||||
export const buildMultidiffusionUpscaleGraph = async (
|
||||
state: RootState
|
||||
): Promise<{ g: Graph; noise: Invocation<'noise'>; posCond: Invocation<'compel' | 'sdxl_compel_prompt'> }> => {
|
||||
const { model, cfgScale: cfg_scale, scheduler, steps, vaePrecision, seed, vae } = state.canvasV2.params;
|
||||
const { model, cfgScale: cfg_scale, scheduler, steps, vaePrecision, seed, vae } = state.params;
|
||||
const { upscaleModel, upscaleInitialImage, structure, creativity, tileControlnetModel, scale } = state.upscale;
|
||||
|
||||
assert(model, 'No model found in state');
|
||||
|
@ -1,7 +1,7 @@
|
||||
import type { RootState } from 'app/store/store';
|
||||
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
|
||||
import { getPrefixedId } from 'features/controlLayers/konva/util';
|
||||
import type { CanvasV2State, Dimensions } from 'features/controlLayers/store/types';
|
||||
import type { Dimensions } from 'features/controlLayers/store/types';
|
||||
import type { Graph } from 'features/nodes/util/graph/generation/Graph';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import type { Invocation } from 'services/api/types';
|
||||
@ -16,14 +16,15 @@ export const addInpaint = async (
|
||||
modelLoader: Invocation<'main_model_loader' | 'sdxl_model_loader'>,
|
||||
originalSize: Dimensions,
|
||||
scaledSize: Dimensions,
|
||||
bbox: CanvasV2State['bbox'],
|
||||
compositing: CanvasV2State['compositing'],
|
||||
denoising_start: number,
|
||||
fp32: boolean
|
||||
): Promise<Invocation<'canvas_v2_mask_and_crop'>> => {
|
||||
denoise.denoising_start = denoising_start;
|
||||
|
||||
const mode = state.canvasV2.session.mode;
|
||||
const { params, canvasV2 } = state;
|
||||
const { bbox, session } = canvasV2;
|
||||
const { mode } = session;
|
||||
|
||||
const initialImage = await manager.compositor.getCompositeRasterLayerImageDTO(bbox.rect);
|
||||
const maskImage = await manager.compositor.getCompositeInpaintMaskImageDTO(bbox.rect);
|
||||
|
||||
@ -60,15 +61,15 @@ export const addInpaint = async (
|
||||
const createGradientMask = g.addNode({
|
||||
id: getPrefixedId('create_gradient_mask'),
|
||||
type: 'create_gradient_mask',
|
||||
coherence_mode: compositing.canvasCoherenceMode,
|
||||
minimum_denoise: compositing.canvasCoherenceMinDenoise,
|
||||
edge_radius: compositing.canvasCoherenceEdgeSize,
|
||||
coherence_mode: params.canvasCoherenceMode,
|
||||
minimum_denoise: params.canvasCoherenceMinDenoise,
|
||||
edge_radius: params.canvasCoherenceEdgeSize,
|
||||
fp32,
|
||||
});
|
||||
const canvasPasteBack = g.addNode({
|
||||
id: getPrefixedId('canvas_v2_mask_and_crop'),
|
||||
type: 'canvas_v2_mask_and_crop',
|
||||
mask_blur: compositing.maskBlur,
|
||||
mask_blur: params.maskBlur,
|
||||
});
|
||||
|
||||
// Resize initial image and mask to scaled size, feed into to gradient mask
|
||||
@ -114,16 +115,16 @@ export const addInpaint = async (
|
||||
const createGradientMask = g.addNode({
|
||||
id: getPrefixedId('create_gradient_mask'),
|
||||
type: 'create_gradient_mask',
|
||||
coherence_mode: compositing.canvasCoherenceMode,
|
||||
minimum_denoise: compositing.canvasCoherenceMinDenoise,
|
||||
edge_radius: compositing.canvasCoherenceEdgeSize,
|
||||
coherence_mode: params.canvasCoherenceMode,
|
||||
minimum_denoise: params.canvasCoherenceMinDenoise,
|
||||
edge_radius: params.canvasCoherenceEdgeSize,
|
||||
fp32,
|
||||
image: { image_name: initialImage.image_name },
|
||||
});
|
||||
const canvasPasteBack = g.addNode({
|
||||
id: getPrefixedId('canvas_v2_mask_and_crop'),
|
||||
type: 'canvas_v2_mask_and_crop',
|
||||
mask_blur: compositing.maskBlur,
|
||||
mask_blur: params.maskBlur,
|
||||
});
|
||||
|
||||
g.addEdge(alphaToMask, 'image', createGradientMask, 'mask');
|
||||
|
@ -1,7 +1,7 @@
|
||||
import type { RootState } from 'app/store/store';
|
||||
import type { CanvasManager } from 'features/controlLayers/konva/CanvasManager';
|
||||
import { getPrefixedId } from 'features/controlLayers/konva/util';
|
||||
import type { CanvasV2State, Dimensions } from 'features/controlLayers/store/types';
|
||||
import type { Dimensions } from 'features/controlLayers/store/types';
|
||||
import type { Graph } from 'features/nodes/util/graph/generation/Graph';
|
||||
import { getInfill } from 'features/nodes/util/graph/graphBuilderUtils';
|
||||
import { isEqual } from 'lodash-es';
|
||||
@ -17,17 +17,18 @@ export const addOutpaint = async (
|
||||
modelLoader: Invocation<'main_model_loader' | 'sdxl_model_loader'>,
|
||||
originalSize: Dimensions,
|
||||
scaledSize: Dimensions,
|
||||
bbox: CanvasV2State['bbox'],
|
||||
compositing: CanvasV2State['compositing'],
|
||||
denoising_start: number,
|
||||
fp32: boolean
|
||||
): Promise<Invocation<'canvas_v2_mask_and_crop'>> => {
|
||||
denoise.denoising_start = denoising_start;
|
||||
|
||||
const mode = state.canvasV2.session.mode;
|
||||
const { params, canvasV2 } = state;
|
||||
const { bbox, session } = canvasV2;
|
||||
const { mode } = session;
|
||||
|
||||
const initialImage = await manager.compositor.getCompositeRasterLayerImageDTO(bbox.rect);
|
||||
const maskImage = await manager.compositor.getCompositeInpaintMaskImageDTO(bbox.rect);
|
||||
const infill = getInfill(g, compositing);
|
||||
const infill = getInfill(g, params);
|
||||
|
||||
if (!isEqual(scaledSize, originalSize)) {
|
||||
// Scale before processing requires some resizing
|
||||
@ -72,9 +73,9 @@ export const addOutpaint = async (
|
||||
const createGradientMask = g.addNode({
|
||||
id: getPrefixedId('create_gradient_mask'),
|
||||
type: 'create_gradient_mask',
|
||||
coherence_mode: compositing.canvasCoherenceMode,
|
||||
minimum_denoise: compositing.canvasCoherenceMinDenoise,
|
||||
edge_radius: compositing.canvasCoherenceEdgeSize,
|
||||
coherence_mode: params.canvasCoherenceMode,
|
||||
minimum_denoise: params.canvasCoherenceMinDenoise,
|
||||
edge_radius: params.canvasCoherenceEdgeSize,
|
||||
fp32,
|
||||
});
|
||||
g.addEdge(infill, 'image', createGradientMask, 'image');
|
||||
@ -103,7 +104,7 @@ export const addOutpaint = async (
|
||||
const canvasPasteBack = g.addNode({
|
||||
id: getPrefixedId('canvas_v2_mask_and_crop'),
|
||||
type: 'canvas_v2_mask_and_crop',
|
||||
mask_blur: compositing.maskBlur,
|
||||
mask_blur: params.maskBlur,
|
||||
});
|
||||
|
||||
// Resize initial image and mask to scaled size, feed into to gradient mask
|
||||
@ -143,16 +144,16 @@ export const addOutpaint = async (
|
||||
const createGradientMask = g.addNode({
|
||||
id: getPrefixedId('create_gradient_mask'),
|
||||
type: 'create_gradient_mask',
|
||||
coherence_mode: compositing.canvasCoherenceMode,
|
||||
minimum_denoise: compositing.canvasCoherenceMinDenoise,
|
||||
edge_radius: compositing.canvasCoherenceEdgeSize,
|
||||
coherence_mode: params.canvasCoherenceMode,
|
||||
minimum_denoise: params.canvasCoherenceMinDenoise,
|
||||
edge_radius: params.canvasCoherenceEdgeSize,
|
||||
fp32,
|
||||
image: { image_name: initialImage.image_name },
|
||||
});
|
||||
const canvasPasteBack = g.addNode({
|
||||
id: getPrefixedId('canvas_v2_mask_and_crop'),
|
||||
type: 'canvas_v2_mask_and_crop',
|
||||
mask_blur: compositing.maskBlur,
|
||||
mask_blur: params.maskBlur,
|
||||
});
|
||||
g.addEdge(maskAlphaToMask, 'image', maskCombine, 'mask1');
|
||||
g.addEdge(initialImageAlphaToMask, 'image', maskCombine, 'mask2');
|
||||
|
@ -23,7 +23,7 @@ export const addSDXLRefiner = async (
|
||||
refinerScheduler,
|
||||
refinerCFGScale,
|
||||
refinerStart,
|
||||
} = state.canvasV2.params;
|
||||
} = state.params;
|
||||
|
||||
assert(refinerModel, 'No refiner model found in state');
|
||||
|
||||
|
@ -21,7 +21,7 @@ export const addSeamless = (
|
||||
modelLoader: Invocation<'main_model_loader'> | Invocation<'sdxl_model_loader'>,
|
||||
vaeLoader: Invocation<'vae_loader'> | null
|
||||
): Invocation<'seamless'> | null => {
|
||||
const { seamlessXAxis: seamless_x, seamlessYAxis: seamless_y } = state.canvasV2.params;
|
||||
const { seamlessXAxis: seamless_x, seamlessYAxis: seamless_y } = state.params;
|
||||
|
||||
if (!seamless_x && !seamless_y) {
|
||||
return null;
|
||||
|
@ -31,7 +31,8 @@ export const buildSD1Graph = async (
|
||||
const generationMode = manager.compositor.getGenerationMode();
|
||||
log.debug({ generationMode }, 'Building SD1/SD2 graph');
|
||||
|
||||
const { bbox, params, session, settings } = state.canvasV2;
|
||||
const { canvasV2, params } = state;
|
||||
const { bbox, session, settings } = canvasV2;
|
||||
|
||||
const {
|
||||
model,
|
||||
@ -172,7 +173,6 @@ export const buildSD1Graph = async (
|
||||
vaePrecision === 'fp32'
|
||||
);
|
||||
} else if (generationMode === 'inpaint') {
|
||||
const { compositing } = state.canvasV2;
|
||||
canvasOutput = await addInpaint(
|
||||
state,
|
||||
g,
|
||||
@ -183,13 +183,10 @@ export const buildSD1Graph = async (
|
||||
modelLoader,
|
||||
originalSize,
|
||||
scaledSize,
|
||||
bbox,
|
||||
compositing,
|
||||
1 - params.img2imgStrength,
|
||||
vaePrecision === 'fp32'
|
||||
);
|
||||
} else if (generationMode === 'outpaint') {
|
||||
const { compositing } = state.canvasV2;
|
||||
canvasOutput = await addOutpaint(
|
||||
state,
|
||||
g,
|
||||
@ -200,8 +197,6 @@ export const buildSD1Graph = async (
|
||||
modelLoader,
|
||||
originalSize,
|
||||
scaledSize,
|
||||
bbox,
|
||||
compositing,
|
||||
1 - params.img2imgStrength,
|
||||
fp32
|
||||
);
|
||||
|
@ -31,7 +31,8 @@ export const buildSDXLGraph = async (
|
||||
const generationMode = manager.compositor.getGenerationMode();
|
||||
log.debug({ generationMode }, 'Building SDXL graph');
|
||||
|
||||
const { bbox, params, session, settings } = state.canvasV2;
|
||||
const { params, canvasV2 } = state;
|
||||
const { bbox, session, settings } = canvasV2;
|
||||
|
||||
const {
|
||||
model,
|
||||
@ -175,7 +176,6 @@ export const buildSDXLGraph = async (
|
||||
fp32
|
||||
);
|
||||
} else if (generationMode === 'inpaint') {
|
||||
const { compositing } = state.canvasV2;
|
||||
canvasOutput = await addInpaint(
|
||||
state,
|
||||
g,
|
||||
@ -186,13 +186,10 @@ export const buildSDXLGraph = async (
|
||||
modelLoader,
|
||||
originalSize,
|
||||
scaledSize,
|
||||
bbox,
|
||||
compositing,
|
||||
refinerModel ? Math.min(refinerStart, 1 - params.img2imgStrength) : 1 - params.img2imgStrength,
|
||||
fp32
|
||||
);
|
||||
} else if (generationMode === 'outpaint') {
|
||||
const { compositing } = state.canvasV2;
|
||||
canvasOutput = await addOutpaint(
|
||||
state,
|
||||
g,
|
||||
@ -203,8 +200,6 @@ export const buildSDXLGraph = async (
|
||||
modelLoader,
|
||||
originalSize,
|
||||
scaledSize,
|
||||
bbox,
|
||||
compositing,
|
||||
refinerModel ? Math.min(refinerStart, 1 - params.img2imgStrength) : 1 - params.img2imgStrength,
|
||||
fp32
|
||||
);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import type { RootState } from 'app/store/store';
|
||||
import type { ParamsState } from 'features/controlLayers/store/paramsSlice';
|
||||
import type { CanvasV2State } from 'features/controlLayers/store/types';
|
||||
import type { BoardField } from 'features/nodes/types/common';
|
||||
import type { Graph } from 'features/nodes/util/graph/generation/Graph';
|
||||
@ -25,8 +26,7 @@ export const getBoardField = (state: RootState): BoardField | undefined => {
|
||||
export const getPresetModifiedPrompts = (
|
||||
state: RootState
|
||||
): { positivePrompt: string; negativePrompt: string; positiveStylePrompt?: string; negativeStylePrompt?: string } => {
|
||||
const { positivePrompt, negativePrompt, positivePrompt2, negativePrompt2, shouldConcatPrompts } =
|
||||
state.canvasV2.params;
|
||||
const { positivePrompt, negativePrompt, positivePrompt2, negativePrompt2, shouldConcatPrompts } = state.params;
|
||||
const { activeStylePresetId } = state.stylePreset;
|
||||
|
||||
if (activeStylePresetId) {
|
||||
@ -70,9 +70,9 @@ export const getSizes = (bboxState: CanvasV2State['bbox']) => {
|
||||
|
||||
export const getInfill = (
|
||||
g: Graph,
|
||||
compositing: CanvasV2State['compositing']
|
||||
params: ParamsState
|
||||
): Invocation<'infill_patchmatch' | 'infill_cv2' | 'infill_lama' | 'infill_rgba' | 'infill_tile'> => {
|
||||
const { infillMethod, infillColorValue, infillPatchmatchDownscaleSize, infillTileSize } = compositing;
|
||||
const { infillMethod, infillColorValue, infillPatchmatchDownscaleSize, infillTileSize } = params;
|
||||
|
||||
// Add Infill Nodes
|
||||
if (infillMethod === 'patchmatch') {
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setCfgRescaleMultiplier } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setCfgRescaleMultiplier } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamCFGRescaleMultiplier = () => {
|
||||
const cfgRescaleMultiplier = useAppSelector((s) => s.canvasV2.params.cfgRescaleMultiplier);
|
||||
const cfgRescaleMultiplier = useAppSelector((s) => s.params.cfgRescaleMultiplier);
|
||||
const initial = useAppSelector((s) => s.config.sd.cfgRescaleMultiplier.initial);
|
||||
const sliderMin = useAppSelector((s) => s.config.sd.cfgRescaleMultiplier.sliderMin);
|
||||
const sliderMax = useAppSelector((s) => s.config.sd.cfgRescaleMultiplier.sliderMax);
|
||||
|
@ -1,19 +1,19 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setClipSkip } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setClipSkip } from 'features/controlLayers/store/paramsSlice';
|
||||
import { CLIP_SKIP_MAP } from 'features/parameters/types/constants';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamClipSkip = () => {
|
||||
const clipSkip = useAppSelector((s) => s.canvasV2.params.clipSkip);
|
||||
const clipSkip = useAppSelector((s) => s.params.clipSkip);
|
||||
const initial = useAppSelector((s) => s.config.sd.clipSkip.initial);
|
||||
const sliderMin = useAppSelector((s) => s.config.sd.clipSkip.sliderMin);
|
||||
const numberInputMin = useAppSelector((s) => s.config.sd.clipSkip.numberInputMin);
|
||||
const coarseStep = useAppSelector((s) => s.config.sd.clipSkip.coarseStep);
|
||||
const fineStep = useAppSelector((s) => s.config.sd.clipSkip.fineStep);
|
||||
const model = useAppSelector((s) => s.canvasV2.params.model);
|
||||
const model = useAppSelector((s) => s.params.model);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setCanvasCoherenceEdgeSize } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setCanvasCoherenceEdgeSize } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamCanvasCoherenceEdgeSize = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const canvasCoherenceEdgeSize = useAppSelector((s) => s.canvasV2.compositing.canvasCoherenceEdgeSize);
|
||||
const canvasCoherenceEdgeSize = useAppSelector((s) => s.params.canvasCoherenceEdgeSize);
|
||||
const initial = useAppSelector((s) => s.config.sd.canvasCoherenceEdgeSize.initial);
|
||||
const sliderMin = useAppSelector((s) => s.config.sd.canvasCoherenceEdgeSize.sliderMin);
|
||||
const sliderMax = useAppSelector((s) => s.config.sd.canvasCoherenceEdgeSize.sliderMax);
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setCanvasCoherenceMinDenoise } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setCanvasCoherenceMinDenoise } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamCanvasCoherenceMinDenoise = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const canvasCoherenceMinDenoise = useAppSelector((s) => s.canvasV2.compositing.canvasCoherenceMinDenoise);
|
||||
const canvasCoherenceMinDenoise = useAppSelector((s) => s.params.canvasCoherenceMinDenoise);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChange = useCallback(
|
||||
|
@ -2,14 +2,14 @@ import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
|
||||
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setCanvasCoherenceMode } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setCanvasCoherenceMode } from 'features/controlLayers/store/paramsSlice';
|
||||
import { isParameterCanvasCoherenceMode } from 'features/parameters/types/parameterSchemas';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamCanvasCoherenceMode = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const canvasCoherenceMode = useAppSelector((s) => s.canvasV2.compositing.canvasCoherenceMode);
|
||||
const canvasCoherenceMode = useAppSelector((s) => s.params.canvasCoherenceMode);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const options = useMemo<ComboboxOption[]>(
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setMaskBlur } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setMaskBlur } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamMaskBlur = () => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const maskBlur = useAppSelector((s) => s.canvasV2.compositing.maskBlur);
|
||||
const maskBlur = useAppSelector((s) => s.params.maskBlur);
|
||||
const initial = useAppSelector((s) => s.config.sd.maskBlur.initial);
|
||||
const sliderMin = useAppSelector((s) => s.config.sd.maskBlur.sliderMin);
|
||||
const sliderMax = useAppSelector((s) => s.config.sd.maskBlur.sliderMax);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Box, Flex, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import IAIColorPicker from 'common/components/IAIColorPicker';
|
||||
import { setInfillColorValue } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setInfillColorValue } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import type { RgbaColor } from 'react-colorful';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -9,8 +9,8 @@ import { useTranslation } from 'react-i18next';
|
||||
const ParamInfillColorOptions = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const infillColor = useAppSelector((s) => s.canvasV2.compositing.infillColorValue);
|
||||
const infillMethod = useAppSelector((s) => s.canvasV2.compositing.infillMethod);
|
||||
const infillColor = useAppSelector((s) => s.params.infillColorValue);
|
||||
const infillMethod = useAppSelector((s) => s.params.infillMethod);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
|
@ -2,7 +2,7 @@ import type { ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
|
||||
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setInfillMethod } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setInfillMethod } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useGetAppConfigQuery } from 'services/api/endpoints/appInfo';
|
||||
@ -10,7 +10,7 @@ import { useGetAppConfigQuery } from 'services/api/endpoints/appInfo';
|
||||
const ParamInfillMethod = () => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const infillMethod = useAppSelector((s) => s.canvasV2.compositing.infillMethod);
|
||||
const infillMethod = useAppSelector((s) => s.params.infillMethod);
|
||||
const { data: appConfigData } = useGetAppConfigQuery();
|
||||
const options = useMemo<ComboboxOption[]>(
|
||||
() =>
|
||||
|
@ -6,7 +6,7 @@ import ParamInfillPatchmatchDownscaleSize from './ParamInfillPatchmatchDownscale
|
||||
import ParamInfillTilesize from './ParamInfillTilesize';
|
||||
|
||||
const ParamInfillOptions = () => {
|
||||
const infillMethod = useAppSelector((s) => s.canvasV2.compositing.infillMethod);
|
||||
const infillMethod = useAppSelector((s) => s.params.infillMethod);
|
||||
if (infillMethod === 'tile') {
|
||||
return <ParamInfillTilesize />;
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setInfillPatchmatchDownscaleSize } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setInfillPatchmatchDownscaleSize } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamInfillPatchmatchDownscaleSize = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const infillMethod = useAppSelector((s) => s.canvasV2.compositing.infillMethod);
|
||||
const infillPatchmatchDownscaleSize = useAppSelector((s) => s.canvasV2.compositing.infillPatchmatchDownscaleSize);
|
||||
const infillMethod = useAppSelector((s) => s.params.infillMethod);
|
||||
const infillPatchmatchDownscaleSize = useAppSelector((s) => s.params.infillPatchmatchDownscaleSize);
|
||||
const initial = useAppSelector((s) => s.config.sd.infillPatchmatchDownscaleSize.initial);
|
||||
const sliderMin = useAppSelector((s) => s.config.sd.infillPatchmatchDownscaleSize.sliderMin);
|
||||
const sliderMax = useAppSelector((s) => s.config.sd.infillPatchmatchDownscaleSize.sliderMax);
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { setInfillTileSize } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setInfillTileSize } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamInfillTileSize = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const infillTileSize = useAppSelector((s) => s.canvasV2.compositing.infillTileSize);
|
||||
const infillTileSize = useAppSelector((s) => s.params.infillTileSize);
|
||||
const initial = useAppSelector((s) => s.config.sd.infillTileSize.initial);
|
||||
const sliderMin = useAppSelector((s) => s.config.sd.infillTileSize.sliderMin);
|
||||
const sliderMax = useAppSelector((s) => s.config.sd.infillTileSize.sliderMax);
|
||||
@ -15,7 +15,7 @@ const ParamInfillTileSize = () => {
|
||||
const coarseStep = useAppSelector((s) => s.config.sd.infillTileSize.coarseStep);
|
||||
const fineStep = useAppSelector((s) => s.config.sd.infillTileSize.fineStep);
|
||||
|
||||
const infillMethod = useAppSelector((s) => s.canvasV2.compositing.infillMethod);
|
||||
const infillMethod = useAppSelector((s) => s.params.infillMethod);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { setImg2imgStrength } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setImg2imgStrength } from 'features/controlLayers/store/paramsSlice';
|
||||
import ImageToImageStrength from 'features/parameters/components/ImageToImage/ImageToImageStrength';
|
||||
import { memo, useCallback } from 'react';
|
||||
|
||||
const ParamImageToImageStrength = () => {
|
||||
const img2imgStrength = useAppSelector((s) => s.canvasV2.params.img2imgStrength);
|
||||
const img2imgStrength = useAppSelector((s) => s.params.img2imgStrength);
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const onChange = useCallback(
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setCfgScale } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setCfgScale } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamCFGScale = () => {
|
||||
const cfgScale = useAppSelector((s) => s.canvasV2.params.cfgScale);
|
||||
const cfgScale = useAppSelector((s) => s.params.cfgScale);
|
||||
const sliderMin = useAppSelector((s) => s.config.sd.guidance.sliderMin);
|
||||
const sliderMax = useAppSelector((s) => s.config.sd.guidance.sliderMax);
|
||||
const numberInputMin = useAppSelector((s) => s.config.sd.guidance.numberInputMin);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Box, Textarea } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { negativePromptChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { negativePromptChanged } from 'features/controlLayers/store/paramsSlice';
|
||||
import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel';
|
||||
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
|
||||
import { ViewModePrompt } from 'features/parameters/components/Prompts/ViewModePrompt';
|
||||
@ -13,7 +13,7 @@ import { useListStylePresetsQuery } from 'services/api/endpoints/stylePresets';
|
||||
|
||||
export const ParamNegativePrompt = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const prompt = useAppSelector((s) => s.canvasV2.params.negativePrompt);
|
||||
const prompt = useAppSelector((s) => s.params.negativePrompt);
|
||||
const viewMode = useAppSelector((s) => s.stylePreset.viewMode);
|
||||
const activeStylePresetId = useAppSelector((s) => s.stylePreset.activeStylePresetId);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Box, Textarea } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { positivePromptChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { positivePromptChanged } from 'features/controlLayers/store/paramsSlice';
|
||||
import { ShowDynamicPromptsPreviewButton } from 'features/dynamicPrompts/components/ShowDynamicPromptsPreviewButton';
|
||||
import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel';
|
||||
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
|
||||
@ -17,8 +17,8 @@ import { useListStylePresetsQuery } from 'services/api/endpoints/stylePresets';
|
||||
|
||||
export const ParamPositivePrompt = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const prompt = useAppSelector((s) => s.canvasV2.params.positivePrompt);
|
||||
const baseModel = useAppSelector((s) => s.canvasV2.params.model)?.base;
|
||||
const prompt = useAppSelector((s) => s.params.positivePrompt);
|
||||
const baseModel = useAppSelector((s) => s.params.model)?.base;
|
||||
const viewMode = useAppSelector((s) => s.stylePreset.viewMode);
|
||||
const activeStylePresetId = useAppSelector((s) => s.stylePreset.activeStylePresetId);
|
||||
|
||||
|
@ -2,7 +2,7 @@ import type { ComboboxOnChange } from '@invoke-ai/ui-library';
|
||||
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setScheduler } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setScheduler } from 'features/controlLayers/store/paramsSlice';
|
||||
import { SCHEDULER_OPTIONS } from 'features/parameters/types/constants';
|
||||
import { isParameterScheduler } from 'features/parameters/types/parameterSchemas';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
@ -11,7 +11,7 @@ import { useTranslation } from 'react-i18next';
|
||||
const ParamScheduler = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
const scheduler = useAppSelector((s) => s.canvasV2.params.scheduler);
|
||||
const scheduler = useAppSelector((s) => s.params.scheduler);
|
||||
|
||||
const onChange = useCallback<ComboboxOnChange>(
|
||||
(v) => {
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setSteps } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setSteps } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamSteps = () => {
|
||||
const steps = useAppSelector((s) => s.canvasV2.params.steps);
|
||||
const steps = useAppSelector((s) => s.params.steps);
|
||||
const initial = useAppSelector((s) => s.config.sd.steps.initial);
|
||||
const sliderMin = useAppSelector((s) => s.config.sd.steps.sliderMin);
|
||||
const sliderMax = useAppSelector((s) => s.config.sd.steps.sliderMax);
|
||||
|
@ -12,7 +12,7 @@ import type { MainModelConfig } from 'services/api/types';
|
||||
const ParamMainModelSelect = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
const selectedModel = useAppSelector((s) => s.canvasV2.params.model);
|
||||
const selectedModel = useAppSelector((s) => s.params.model);
|
||||
const [modelConfigs, { isLoading }] = useSDMainModels();
|
||||
const tooltipLabel = useMemo(() => {
|
||||
if (!modelConfigs.length || !selectedModel) {
|
||||
|
@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import { RiSparklingFill } from 'react-icons/ri';
|
||||
|
||||
export const UseDefaultSettingsButton = () => {
|
||||
const model = useAppSelector((s) => s.canvasV2.params.model);
|
||||
const model = useAppSelector((s) => s.params.model);
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
|
@ -1,25 +1,23 @@
|
||||
import { Flex } from '@invoke-ai/ui-library';
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { selectCanvasV2Slice } from 'features/controlLayers/store/selectors';
|
||||
import { ParamNegativePrompt } from 'features/parameters/components/Core/ParamNegativePrompt';
|
||||
import { ParamPositivePrompt } from 'features/parameters/components/Core/ParamPositivePrompt';
|
||||
import { ParamSDXLNegativeStylePrompt } from 'features/sdxl/components/SDXLPrompts/ParamSDXLNegativeStylePrompt';
|
||||
import { ParamSDXLPositiveStylePrompt } from 'features/sdxl/components/SDXLPrompts/ParamSDXLPositiveStylePrompt';
|
||||
import { memo } from 'react';
|
||||
|
||||
const concatPromptsSelector = createSelector([selectCanvasV2Slice], (canvasV2) => {
|
||||
return canvasV2.params.model?.base !== 'sdxl' || canvasV2.params.shouldConcatPrompts;
|
||||
});
|
||||
|
||||
export const Prompts = memo(() => {
|
||||
const shouldConcatPrompts = useAppSelector(concatPromptsSelector);
|
||||
const withStylePrompts = useAppSelector((s) => {
|
||||
const isSDXL = s.params.model?.base === 'sdxl';
|
||||
const shouldConcatPrompts = s.params.shouldConcatPrompts;
|
||||
return isSDXL && !shouldConcatPrompts;
|
||||
});
|
||||
return (
|
||||
<Flex flexDir="column" gap={2}>
|
||||
<ParamPositivePrompt />
|
||||
{!shouldConcatPrompts && <ParamSDXLPositiveStylePrompt />}
|
||||
{withStylePrompts && <ParamSDXLPositiveStylePrompt />}
|
||||
<ParamNegativePrompt />
|
||||
{!shouldConcatPrompts && <ParamSDXLNegativeStylePrompt />}
|
||||
{withStylePrompts && <ParamSDXLNegativeStylePrompt />}
|
||||
</Flex>
|
||||
);
|
||||
});
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { FormControl, FormLabel, Switch } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setSeamlessXAxis } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setSeamlessXAxis } from 'features/controlLayers/store/paramsSlice';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamSeamlessXAxis = () => {
|
||||
const { t } = useTranslation();
|
||||
const seamlessXAxis = useAppSelector((s) => s.canvasV2.params.seamlessXAxis);
|
||||
const seamlessXAxis = useAppSelector((s) => s.params.seamlessXAxis);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { FormControl, FormLabel, Switch } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setSeamlessYAxis } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setSeamlessYAxis } from 'features/controlLayers/store/paramsSlice';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamSeamlessYAxis = () => {
|
||||
const { t } = useTranslation();
|
||||
const seamlessYAxis = useAppSelector((s) => s.canvasV2.params.seamlessYAxis);
|
||||
const seamlessYAxis = useAppSelector((s) => s.params.seamlessYAxis);
|
||||
const dispatch = useAppDispatch();
|
||||
const handleChange = useCallback(
|
||||
(e: ChangeEvent<HTMLInputElement>) => {
|
||||
|
@ -2,13 +2,13 @@ import { CompositeNumberInput, FormControl, FormLabel } from '@invoke-ai/ui-libr
|
||||
import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setSeed } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setSeed } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const ParamSeedNumberInput = memo(() => {
|
||||
const seed = useAppSelector((s) => s.canvasV2.params.seed);
|
||||
const shouldRandomizeSeed = useAppSelector((s) => s.canvasV2.params.shouldRandomizeSeed);
|
||||
const seed = useAppSelector((s) => s.params.seed);
|
||||
const shouldRandomizeSeed = useAppSelector((s) => s.params.shouldRandomizeSeed);
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { FormControl, FormLabel, Switch } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { setShouldRandomizeSeed } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setShouldRandomizeSeed } from 'features/controlLayers/store/paramsSlice';
|
||||
import type { ChangeEvent } from 'react';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -9,7 +9,7 @@ export const ParamSeedRandomize = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const shouldRandomizeSeed = useAppSelector((s) => s.canvasV2.params.shouldRandomizeSeed);
|
||||
const shouldRandomizeSeed = useAppSelector((s) => s.params.shouldRandomizeSeed);
|
||||
|
||||
const handleChangeShouldRandomizeSeed = useCallback(
|
||||
(e: ChangeEvent<HTMLInputElement>) => dispatch(setShouldRandomizeSeed(e.target.checked)),
|
||||
|
@ -2,14 +2,14 @@ import { Button } from '@invoke-ai/ui-library';
|
||||
import { NUMPY_RAND_MAX, NUMPY_RAND_MIN } from 'app/constants';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import randomInt from 'common/util/randomInt';
|
||||
import { setSeed } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setSeed } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PiShuffleBold } from 'react-icons/pi';
|
||||
|
||||
export const ParamSeedShuffle = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const shouldRandomizeSeed = useAppSelector((s) => s.canvasV2.params.shouldRandomizeSeed);
|
||||
const shouldRandomizeSeed = useAppSelector((s) => s.params.shouldRandomizeSeed);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleClickRandomizeSeed = useCallback(
|
||||
|
@ -2,7 +2,7 @@ import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { useGroupedModelCombobox } from 'common/hooks/useGroupedModelCombobox';
|
||||
import { vaeSelected } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { vaeSelected } from 'features/controlLayers/store/paramsSlice';
|
||||
import { zModelIdentifierField } from 'features/nodes/types/common';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -12,8 +12,8 @@ import type { VAEModelConfig } from 'services/api/types';
|
||||
const ParamVAEModelSelect = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
const model = useAppSelector((s) => s.canvasV2.params.model);
|
||||
const vae = useAppSelector((s) => s.canvasV2.params.vae);
|
||||
const model = useAppSelector((s) => s.params.model);
|
||||
const vae = useAppSelector((s) => s.params.vae);
|
||||
const [modelConfigs, { isLoading }] = useVAEModels();
|
||||
const getIsDisabled = useCallback(
|
||||
(vae: VAEModelConfig): boolean => {
|
||||
|
@ -2,7 +2,7 @@ import type { ComboboxOnChange } from '@invoke-ai/ui-library';
|
||||
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { vaePrecisionChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { vaePrecisionChanged } from 'features/controlLayers/store/paramsSlice';
|
||||
import { isParameterPrecision } from 'features/parameters/types/parameterSchemas';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -15,7 +15,7 @@ const options = [
|
||||
const ParamVAEModelSelect = () => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const vaePrecision = useAppSelector((s) => s.canvasV2.params.vaePrecision);
|
||||
const vaePrecision = useAppSelector((s) => s.params.vaePrecision);
|
||||
|
||||
const onChange = useCallback<ComboboxOnChange>(
|
||||
(v) => {
|
||||
|
@ -17,7 +17,7 @@ const noOptionsMessage = () => t('prompt.noMatchingTriggers');
|
||||
export const PromptTriggerSelect = memo(({ onSelect, onClose }: PromptTriggerSelectProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const mainModel = useAppSelector((s) => s.canvasV2.params.model);
|
||||
const mainModel = useAppSelector((s) => s.params.model);
|
||||
const addedLoRAs = useAppSelector((s) => s.canvasV2.loras);
|
||||
const { data: mainModelConfig, isLoading: isLoadingMainModelConfig } = useGetModelConfigQuery(
|
||||
mainModel?.key ?? skipToken
|
||||
|
@ -2,7 +2,7 @@ import { Divider, Flex, ListItem, Text, Tooltip, UnorderedList } from '@invoke-a
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useIsReadyToEnqueue } from 'common/hooks/useIsReadyToEnqueue';
|
||||
import { selectCanvasV2Slice } from 'features/controlLayers/store/selectors';
|
||||
import { selectParamsSlice } from 'features/controlLayers/store/paramsSlice';
|
||||
import { selectDynamicPromptsSlice } from 'features/dynamicPrompts/store/dynamicPromptsSlice';
|
||||
import { getShouldProcessPrompt } from 'features/dynamicPrompts/util/getShouldProcessPrompt';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
@ -11,8 +11,8 @@ import { useTranslation } from 'react-i18next';
|
||||
import { useEnqueueBatchMutation } from 'services/api/endpoints/queue';
|
||||
import { useBoardName } from 'services/api/hooks/useBoardName';
|
||||
|
||||
const selectPromptsCount = createSelector(selectCanvasV2Slice, selectDynamicPromptsSlice, (canvasV2, dynamicPrompts) =>
|
||||
getShouldProcessPrompt(canvasV2.params.positivePrompt) ? dynamicPrompts.prompts.length : 1
|
||||
const selectPromptsCount = createSelector(selectParamsSlice, selectDynamicPromptsSlice, (params, dynamicPrompts) =>
|
||||
getShouldProcessPrompt(params.positivePrompt) ? dynamicPrompts.prompts.length : 1
|
||||
);
|
||||
|
||||
type Props = {
|
||||
@ -32,7 +32,7 @@ const TooltipContent = memo(({ prepend = false }: Props) => {
|
||||
const { isReady, reasons } = useIsReadyToEnqueue();
|
||||
const isLoadingDynamicPrompts = useAppSelector((s) => s.dynamicPrompts.isLoading);
|
||||
const promptsCount = useAppSelector(selectPromptsCount);
|
||||
const iterationsCount = useAppSelector((s) => s.canvasV2.params.iterations);
|
||||
const iterationsCount = useAppSelector((s) => s.params.iterations);
|
||||
const autoAddBoardId = useAppSelector((s) => s.gallery.autoAddBoardId);
|
||||
const autoAddBoardName = useBoardName(autoAddBoardId);
|
||||
const [_, { isLoading }] = useEnqueueBatchMutation({
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { CompositeNumberInput } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setIterations } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setIterations } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
|
||||
export const QueueIterationsNumberInput = memo(() => {
|
||||
const iterations = useAppSelector((s) => s.canvasV2.params.iterations);
|
||||
const iterations = useAppSelector((s) => s.params.iterations);
|
||||
const coarseStep = useAppSelector((s) => s.config.sd.iterations.coarseStep);
|
||||
const fineStep = useAppSelector((s) => s.config.sd.iterations.fineStep);
|
||||
const dispatch = useAppDispatch();
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Box, Textarea } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { negativePrompt2Changed } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { negativePrompt2Changed } from 'features/controlLayers/store/paramsSlice';
|
||||
import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel';
|
||||
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
|
||||
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
|
||||
@ -12,7 +12,7 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const ParamSDXLNegativeStylePrompt = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const prompt = useAppSelector((s) => s.canvasV2.params.negativePrompt2);
|
||||
const prompt = useAppSelector((s) => s.params.negativePrompt2);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const { t } = useTranslation();
|
||||
const handleChange = useCallback(
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Box, Textarea } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { positivePrompt2Changed } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { positivePrompt2Changed } from 'features/controlLayers/store/paramsSlice';
|
||||
import { PromptLabel } from 'features/parameters/components/Prompts/PromptLabel';
|
||||
import { PromptOverlayButtonWrapper } from 'features/parameters/components/Prompts/PromptOverlayButtonWrapper';
|
||||
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
|
||||
@ -11,7 +11,7 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const ParamSDXLPositiveStylePrompt = memo(() => {
|
||||
const dispatch = useAppDispatch();
|
||||
const prompt = useAppSelector((s) => s.canvasV2.params.positivePrompt2);
|
||||
const prompt = useAppSelector((s) => s.params.positivePrompt2);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const { t } = useTranslation();
|
||||
const handleChange = useCallback(
|
||||
|
@ -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/controlLayers/store/paramsSlice';
|
||||
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.params.shouldConcatPrompts);
|
||||
const shouldConcatPrompts = useAppSelector((s) => s.params.shouldConcatPrompts);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setRefinerCFGScale } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setRefinerCFGScale } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamSDXLRefinerCFGScale = () => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const refinerCFGScale = useAppSelector((s) => s.canvasV2.params.refinerCFGScale);
|
||||
const refinerCFGScale = useAppSelector((s) => s.params.refinerCFGScale);
|
||||
const sliderMin = useAppSelector((s) => s.config.sd.guidance.sliderMin);
|
||||
const sliderMax = useAppSelector((s) => s.config.sd.guidance.sliderMax);
|
||||
const numberInputMin = useAppSelector((s) => s.config.sd.guidance.numberInputMin);
|
||||
|
@ -2,7 +2,7 @@ import { Box, Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { useModelCombobox } from 'common/hooks/useModelCombobox';
|
||||
import { refinerModelChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { refinerModelChanged } from 'features/controlLayers/store/paramsSlice';
|
||||
import { zModelIdentifierField } from 'features/nodes/types/common';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -13,7 +13,7 @@ const optionsFilter = (model: MainModelConfig) => model.base === 'sdxl-refiner';
|
||||
|
||||
const ParamSDXLRefinerModelSelect = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const model = useAppSelector((s) => s.canvasV2.params.refinerModel);
|
||||
const model = useAppSelector((s) => s.params.refinerModel);
|
||||
const { t } = useTranslation();
|
||||
const [modelConfigs, { isLoading }] = useRefinerModels();
|
||||
const _onChange = useCallback(
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setRefinerNegativeAestheticScore } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setRefinerNegativeAestheticScore } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamSDXLRefinerNegativeAestheticScore = () => {
|
||||
const refinerNegativeAestheticScore = useAppSelector((s) => s.canvasV2.params.refinerNegativeAestheticScore);
|
||||
const refinerNegativeAestheticScore = useAppSelector((s) => s.params.refinerNegativeAestheticScore);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setRefinerPositiveAestheticScore } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setRefinerPositiveAestheticScore } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamSDXLRefinerPositiveAestheticScore = () => {
|
||||
const refinerPositiveAestheticScore = useAppSelector((s) => s.canvasV2.params.refinerPositiveAestheticScore);
|
||||
const refinerPositiveAestheticScore = useAppSelector((s) => s.params.refinerPositiveAestheticScore);
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
|
||||
|
@ -2,7 +2,7 @@ import type { ComboboxOnChange } from '@invoke-ai/ui-library';
|
||||
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setRefinerScheduler } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setRefinerScheduler } from 'features/controlLayers/store/paramsSlice';
|
||||
import { SCHEDULER_OPTIONS } from 'features/parameters/types/constants';
|
||||
import { isParameterScheduler } from 'features/parameters/types/parameterSchemas';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
@ -11,7 +11,7 @@ import { useTranslation } from 'react-i18next';
|
||||
const ParamSDXLRefinerScheduler = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useTranslation();
|
||||
const refinerScheduler = useAppSelector((s) => s.canvasV2.params.refinerScheduler);
|
||||
const refinerScheduler = useAppSelector((s) => s.params.refinerScheduler);
|
||||
|
||||
const onChange = useCallback<ComboboxOnChange>(
|
||||
(v) => {
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setRefinerStart } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setRefinerStart } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamSDXLRefinerStart = () => {
|
||||
const refinerStart = useAppSelector((s) => s.canvasV2.params.refinerStart);
|
||||
const refinerStart = useAppSelector((s) => s.params.refinerStart);
|
||||
const dispatch = useAppDispatch();
|
||||
const handleChange = useCallback((v: number) => dispatch(setRefinerStart(v)), [dispatch]);
|
||||
const { t } = useTranslation();
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import { setRefinerSteps } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { setRefinerSteps } from 'features/controlLayers/store/paramsSlice';
|
||||
import { memo, useCallback, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParamSDXLRefinerSteps = () => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const refinerSteps = useAppSelector((s) => s.canvasV2.params.refinerSteps);
|
||||
const refinerSteps = useAppSelector((s) => s.params.refinerSteps);
|
||||
const initial = useAppSelector((s) => s.config.sd.steps.initial);
|
||||
const sliderMin = useAppSelector((s) => s.config.sd.steps.sliderMin);
|
||||
const sliderMax = useAppSelector((s) => s.config.sd.steps.sliderMax);
|
||||
|
@ -3,7 +3,7 @@ import { Flex, FormControlGroup, StandaloneAccordion } from '@invoke-ai/ui-libra
|
||||
import { skipToken } from '@reduxjs/toolkit/query';
|
||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { selectCanvasV2Slice } from 'features/controlLayers/store/selectors';
|
||||
import { selectParamsSlice } from 'features/controlLayers/store/paramsSlice';
|
||||
import ParamCFGRescaleMultiplier from 'features/parameters/components/Advanced/ParamCFGRescaleMultiplier';
|
||||
import ParamClipSkip from 'features/parameters/components/Advanced/ParamClipSkip';
|
||||
import ParamSeamlessXAxis from 'features/parameters/components/Seamless/ParamSeamlessXAxis';
|
||||
@ -28,13 +28,13 @@ const formLabelProps2: FormLabelProps = {
|
||||
};
|
||||
|
||||
export const AdvancedSettingsAccordion = memo(() => {
|
||||
const vaeKey = useAppSelector((state) => state.canvasV2.params.vae?.key);
|
||||
const vaeKey = useAppSelector((state) => state.params.vae?.key);
|
||||
const { currentData: vaeConfig } = useGetModelConfigQuery(vaeKey ?? skipToken);
|
||||
const activeTabName = useAppSelector(selectActiveTab);
|
||||
|
||||
const selectBadges = useMemo(
|
||||
() =>
|
||||
createMemoizedSelector(selectCanvasV2Slice, ({ params }) => {
|
||||
createMemoizedSelector(selectParamsSlice, (params) => {
|
||||
const badges: (string | number)[] = [];
|
||||
if (vaeConfig) {
|
||||
let vaeBadge = vaeConfig.name;
|
||||
|
@ -2,6 +2,7 @@ import type { FormLabelProps } from '@invoke-ai/ui-library';
|
||||
import { Expander, Flex, FormControlGroup, StandaloneAccordion } from '@invoke-ai/ui-library';
|
||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { selectParamsSlice } from 'features/controlLayers/store/paramsSlice';
|
||||
import { selectCanvasV2Slice } from 'features/controlLayers/store/selectors';
|
||||
import { HrfSettings } from 'features/hrf/components/HrfSettings';
|
||||
import { selectHrfSlice } from 'features/hrf/store/hrfSlice';
|
||||
@ -18,31 +19,34 @@ import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/
|
||||
import { memo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const selector = createMemoizedSelector([selectHrfSlice, selectCanvasV2Slice], (hrf, canvasV2) => {
|
||||
const { shouldRandomizeSeed, model } = canvasV2.params;
|
||||
const { hrfEnabled } = hrf;
|
||||
const badges: string[] = [];
|
||||
const isSDXL = model?.base === 'sdxl';
|
||||
const selector = createMemoizedSelector(
|
||||
[selectHrfSlice, selectCanvasV2Slice, selectParamsSlice],
|
||||
(hrf, canvasV2, params) => {
|
||||
const { shouldRandomizeSeed, model } = params;
|
||||
const { hrfEnabled } = hrf;
|
||||
const badges: string[] = [];
|
||||
const isSDXL = model?.base === 'sdxl';
|
||||
|
||||
const { aspectRatio } = canvasV2.bbox;
|
||||
const { width, height } = canvasV2.bbox.rect;
|
||||
const { aspectRatio } = canvasV2.bbox;
|
||||
const { width, height } = canvasV2.bbox.rect;
|
||||
|
||||
badges.push(`${width}×${height}`);
|
||||
badges.push(aspectRatio.id);
|
||||
badges.push(`${width}×${height}`);
|
||||
badges.push(aspectRatio.id);
|
||||
|
||||
if (aspectRatio.isLocked) {
|
||||
badges.push('locked');
|
||||
if (aspectRatio.isLocked) {
|
||||
badges.push('locked');
|
||||
}
|
||||
|
||||
if (!shouldRandomizeSeed) {
|
||||
badges.push('Manual Seed');
|
||||
}
|
||||
|
||||
if (hrfEnabled && !isSDXL) {
|
||||
badges.push('HiRes Fix');
|
||||
}
|
||||
return { badges, isSDXL };
|
||||
}
|
||||
|
||||
if (!shouldRandomizeSeed) {
|
||||
badges.push('Manual Seed');
|
||||
}
|
||||
|
||||
if (hrfEnabled && !isSDXL) {
|
||||
badges.push('HiRes Fix');
|
||||
}
|
||||
return { badges, isSDXL };
|
||||
});
|
||||
);
|
||||
|
||||
const scalingLabelProps: FormLabelProps = {
|
||||
minW: '4.5rem',
|
||||
|
@ -2,7 +2,7 @@ import type { FormLabelProps } from '@invoke-ai/ui-library';
|
||||
import { Flex, FormControlGroup, StandaloneAccordion, Text } from '@invoke-ai/ui-library';
|
||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
||||
import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { selectCanvasV2Slice } from 'features/controlLayers/store/selectors';
|
||||
import { selectParamsSlice } from 'features/controlLayers/store/paramsSlice';
|
||||
import ParamSDXLRefinerCFGScale from 'features/sdxl/components/SDXLRefiner/ParamSDXLRefinerCFGScale';
|
||||
import ParamSDXLRefinerModelSelect from 'features/sdxl/components/SDXLRefiner/ParamSDXLRefinerModelSelect';
|
||||
import ParamSDXLRefinerNegativeAestheticScore from 'features/sdxl/components/SDXLRefiner/ParamSDXLRefinerNegativeAestheticScore';
|
||||
@ -24,7 +24,7 @@ const stepsScaleLabelProps: FormLabelProps = {
|
||||
minW: '5rem',
|
||||
};
|
||||
|
||||
const selectBadges = createMemoizedSelector(selectCanvasV2Slice, ({ params }) =>
|
||||
const selectBadges = createMemoizedSelector(selectParamsSlice, (params) =>
|
||||
params.refinerModel ? ['Enabled'] : undefined
|
||||
);
|
||||
|
||||
@ -60,7 +60,7 @@ const RefinerSettingsAccordionNoRefiner: React.FC = memo(() => {
|
||||
RefinerSettingsAccordionNoRefiner.displayName = 'RefinerSettingsAccordionNoRefiner';
|
||||
|
||||
const RefinerSettingsAccordionContent: React.FC = memo(() => {
|
||||
const isRefinerModelSelected = useAppSelector((state) => !isNil(state.canvasV2.params.refinerModel));
|
||||
const isRefinerModelSelected = useAppSelector((state) => !isNil(state.params.refinerModel));
|
||||
|
||||
return (
|
||||
<FormControlGroup isDisabled={!isRefinerModelSelected}>
|
||||
|
@ -10,7 +10,7 @@ import { useControlNetModels } from 'services/api/hooks/modelsByType';
|
||||
|
||||
export const UpscaleWarning = () => {
|
||||
const { t } = useTranslation();
|
||||
const model = useAppSelector((s) => s.canvasV2.params.model);
|
||||
const model = useAppSelector((s) => s.params.model);
|
||||
const upscaleModel = useAppSelector((s) => s.upscale.upscaleModel);
|
||||
const tileControlnetModel = useAppSelector((s) => s.upscale.tileControlnetModel);
|
||||
const upscaleInitialImage = useAppSelector((s) => s.upscale.upscaleInitialImage);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Badge, Flex, IconButton, Spacer, Text, Tooltip } from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { negativePromptChanged, positivePromptChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { negativePromptChanged, positivePromptChanged } from 'features/controlLayers/store/paramsSlice';
|
||||
import { usePresetModifiedPrompts } from 'features/stylePresets/hooks/usePresetModifiedPrompts';
|
||||
import { activeStylePresetIdChanged, viewModeChanged } from 'features/stylePresets/store/stylePresetSlice';
|
||||
import type { MouseEventHandler } from 'react';
|
||||
|
@ -10,8 +10,8 @@ export const buildPresetModifiedPrompt = (presetPrompt: string, currentPrompt: s
|
||||
};
|
||||
|
||||
export const usePresetModifiedPrompts = () => {
|
||||
const positivePrompt = useAppSelector((s) => s.canvasV2.params.positivePrompt);
|
||||
const negativePrompt = useAppSelector((s) => s.canvasV2.params.negativePrompt);
|
||||
const positivePrompt = useAppSelector((s) => s.params.positivePrompt);
|
||||
const negativePrompt = useAppSelector((s) => s.params.negativePrompt);
|
||||
|
||||
const activeStylePresetId = useAppSelector((s) => s.stylePreset.activeStylePresetId);
|
||||
|
||||
|
@ -19,7 +19,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||
import ScrollableContent from 'common/components/OverlayScrollbars/ScrollableContent';
|
||||
import { useClearStorage } from 'common/hooks/useClearStorage';
|
||||
import { shouldUseCpuNoiseChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||
import { shouldUseCpuNoiseChanged } from 'features/controlLayers/store/paramsSlice';
|
||||
import { SettingsDeveloperLogIsEnabled } from 'features/system/components/SettingsModal/SettingsDeveloperLogIsEnabled';
|
||||
import { SettingsDeveloperLogLevel } from 'features/system/components/SettingsModal/SettingsDeveloperLogLevel';
|
||||
import { SettingsDeveloperLogNamespaces } from 'features/system/components/SettingsModal/SettingsDeveloperLogNamespaces';
|
||||
@ -89,7 +89,7 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
|
||||
|
||||
const { isOpen: isRefreshModalOpen, onOpen: onRefreshModalOpen, onClose: onRefreshModalClose } = useDisclosure();
|
||||
|
||||
const shouldUseCpuNoise = useAppSelector((s) => s.canvasV2.params.shouldUseCpuNoise);
|
||||
const shouldUseCpuNoise = useAppSelector((s) => s.params.shouldUseCpuNoise);
|
||||
const shouldConfirmOnDelete = useAppSelector((s) => s.system.shouldConfirmOnDelete);
|
||||
const shouldShowProgressInViewer = useAppSelector((s) => s.ui.shouldShowProgressInViewer);
|
||||
const shouldAntialiasProgressImage = useAppSelector((s) => s.system.shouldAntialiasProgressImage);
|
||||
|
@ -49,7 +49,7 @@ const ParametersPanelTextToImage = () => {
|
||||
}
|
||||
return `${t('controlLayers.controlLayers')} (${controlLayersCount})`;
|
||||
}, [controlLayersCount, t]);
|
||||
const isSDXL = useAppSelector((s) => s.canvasV2.params.model?.base === 'sdxl');
|
||||
const isSDXL = useAppSelector((s) => s.params.model?.base === 'sdxl');
|
||||
const onChangeTabs = useCallback(
|
||||
(i: number) => {
|
||||
if (i === 1) {
|
||||
|
@ -3,7 +3,7 @@ import { useAppSelector } from 'app/store/storeHooks';
|
||||
import { useGetModelConfigQuery } from 'services/api/endpoints/models';
|
||||
|
||||
export const useSelectedModelConfig = () => {
|
||||
const key = useAppSelector((s) => s.canvasV2.params.model?.key);
|
||||
const key = useAppSelector((s) => s.params.model?.key);
|
||||
const { currentData: modelConfig } = useGetModelConfigQuery(key ?? skipToken);
|
||||
|
||||
return modelConfig;
|
||||
|
Loading…
Reference in New Issue
Block a user