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