mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
refactor(ui): update components & logic to use new unified slice
This commit is contained in:
parent
83a5c87f5e
commit
6b9e0e6d63
@ -1,5 +1,5 @@
|
|||||||
import { PropsWithChildren, memo, useEffect } from 'react';
|
import { PropsWithChildren, memo, useEffect } from 'react';
|
||||||
import { modelChanged } from '../src/features/parameters/store/generationSlice';
|
import { modelChanged } from '../src/features/controlLayers/store/canvasV2Slice';
|
||||||
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/parameters/store/generationSlice';
|
import { setInfillMethod } from 'features/canvas/store/canvasSlice';
|
||||||
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';
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ export const addEnqueueRequestedLinear = (startAppListening: AppStartListening)
|
|||||||
effect: async (action, { getState, dispatch }) => {
|
effect: async (action, { getState, dispatch }) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const { shouldShowProgressInViewer } = state.ui;
|
const { shouldShowProgressInViewer } = state.ui;
|
||||||
const model = state.generation.model;
|
const model = state.canvasV2.params.model;
|
||||||
const { prepend } = action.payload;
|
const { prepend } = action.payload;
|
||||||
|
|
||||||
let graph;
|
let graph;
|
||||||
|
@ -29,7 +29,7 @@ export const addEnqueueRequestedNodes = (startAppListening: AppStartListening) =
|
|||||||
batch: {
|
batch: {
|
||||||
graph,
|
graph,
|
||||||
workflow: builtWorkflow,
|
workflow: builtWorkflow,
|
||||||
runs: state.generation.iterations,
|
runs: state.canvasV2.params.iterations,
|
||||||
},
|
},
|
||||||
prepend: action.payload.prepend,
|
prepend: action.payload.prepend,
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
||||||
import { loraRemoved } from 'features/lora/store/loraSlice';
|
import { loraRemoved } from 'features/lora/store/loraSlice';
|
||||||
import { modelSelected } from 'features/parameters/store/actions';
|
import { modelSelected } from 'features/parameters/store/actions';
|
||||||
import { modelChanged, vaeSelected } from 'features/parameters/store/generationSlice';
|
import { modelChanged, vaeSelected } from 'features/canvas/store/canvasSlice';
|
||||||
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';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
@ -29,7 +29,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.generation.model?.base !== newBaseModel;
|
const didBaseModelChange = state.canvasV2.params.model?.base !== newBaseModel;
|
||||||
|
|
||||||
if (didBaseModelChange) {
|
if (didBaseModelChange) {
|
||||||
// we may need to reset some incompatible submodels
|
// we may need to reset some incompatible submodels
|
||||||
@ -44,7 +44,7 @@ export const addModelSelectedListener = (startAppListening: AppStartListening) =
|
|||||||
});
|
});
|
||||||
|
|
||||||
// handle incompatible vae
|
// handle incompatible vae
|
||||||
const { vae } = state.generation;
|
const { vae } = state.canvasV2.params;
|
||||||
if (vae && vae.base !== newBaseModel) {
|
if (vae && vae.base !== newBaseModel) {
|
||||||
dispatch(vaeSelected(null));
|
dispatch(vaeSelected(null));
|
||||||
modelsCleared += 1;
|
modelsCleared += 1;
|
||||||
@ -70,7 +70,7 @@ export const addModelSelectedListener = (startAppListening: AppStartListening) =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(modelChanged(newModel, state.generation.model));
|
dispatch(modelChanged(newModel, state.canvasV2.params.model));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -3,17 +3,18 @@ import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'
|
|||||||
import type { AppDispatch, RootState } from 'app/store/store';
|
import type { AppDispatch, RootState } from 'app/store/store';
|
||||||
import type { JSONObject } from 'common/types';
|
import type { JSONObject } from 'common/types';
|
||||||
import {
|
import {
|
||||||
controlAdapterModelCleared,
|
caModelChanged,
|
||||||
selectControlAdapterAll,
|
heightChanged,
|
||||||
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
modelChanged,
|
||||||
import { heightChanged, widthChanged } from 'features/controlLayers/store/canvasV2Slice';
|
refinerModelChanged,
|
||||||
|
vaeSelected,
|
||||||
|
widthChanged,
|
||||||
|
} from 'features/controlLayers/store/canvasV2Slice';
|
||||||
import { loraRemoved } from 'features/lora/store/loraSlice';
|
import { loraRemoved } from 'features/lora/store/loraSlice';
|
||||||
import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize';
|
import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize';
|
||||||
import { modelChanged, vaeSelected } from 'features/parameters/store/generationSlice';
|
|
||||||
import { postProcessingModelChanged, upscaleModelChanged } from 'features/parameters/store/upscaleSlice';
|
import { postProcessingModelChanged, upscaleModelChanged } from 'features/parameters/store/upscaleSlice';
|
||||||
import { zParameterModel, zParameterVAEModel } from 'features/parameters/types/parameterSchemas';
|
import { zParameterModel, zParameterVAEModel } from 'features/parameters/types/parameterSchemas';
|
||||||
import { getIsSizeOptimal, getOptimalDimension } from 'features/parameters/util/optimalDimension';
|
import { getIsSizeOptimal, getOptimalDimension } from 'features/parameters/util/optimalDimension';
|
||||||
import { refinerModelChanged } from 'features/sdxl/store/sdxlSlice';
|
|
||||||
import { forEach } from 'lodash-es';
|
import { forEach } from 'lodash-es';
|
||||||
import type { Logger } from 'roarr';
|
import type { Logger } from 'roarr';
|
||||||
import { modelConfigsAdapterSelectors, modelsApi } from 'services/api/endpoints/models';
|
import { modelConfigsAdapterSelectors, modelsApi } from 'services/api/endpoints/models';
|
||||||
@ -55,11 +56,11 @@ type ModelHandler = (
|
|||||||
) => undefined;
|
) => undefined;
|
||||||
|
|
||||||
const handleMainModels: ModelHandler = (models, state, dispatch, log) => {
|
const handleMainModels: ModelHandler = (models, state, dispatch, log) => {
|
||||||
const currentModel = state.generation.model;
|
const currentModel = state.canvasV2.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
|
||||||
dispatch(modelChanged(null));
|
dispatch(modelChanged({ model: null }));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,16 +75,10 @@ const handleMainModels: ModelHandler = (models, state, dispatch, log) => {
|
|||||||
if (defaultModelInList) {
|
if (defaultModelInList) {
|
||||||
const result = zParameterModel.safeParse(defaultModelInList);
|
const result = zParameterModel.safeParse(defaultModelInList);
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
dispatch(modelChanged(defaultModelInList, currentModel));
|
dispatch(modelChanged({ model: defaultModelInList, previousModel: currentModel ?? undefined }));
|
||||||
|
|
||||||
const optimalDimension = getOptimalDimension(defaultModelInList);
|
const optimalDimension = getOptimalDimension(defaultModelInList);
|
||||||
if (
|
if (getIsSizeOptimal(state.canvasV2.document.width, state.canvasV2.document.height, optimalDimension)) {
|
||||||
getIsSizeOptimal(
|
|
||||||
state.canvasV2.document.width,
|
|
||||||
state.canvasV2.document.height,
|
|
||||||
optimalDimension
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { width, height } = calculateNewSize(
|
const { width, height } = calculateNewSize(
|
||||||
@ -104,11 +99,11 @@ const handleMainModels: ModelHandler = (models, state, dispatch, log) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(modelChanged(result.data, currentModel));
|
dispatch(modelChanged({ model: result.data, previousModel: currentModel ?? undefined }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRefinerModels: ModelHandler = (models, state, dispatch, _log) => {
|
const handleRefinerModels: ModelHandler = (models, state, dispatch, _log) => {
|
||||||
const currentRefinerModel = state.sdxl.refinerModel;
|
const currentRefinerModel = state.canvasV2.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
|
||||||
@ -127,7 +122,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.generation.vae;
|
const currentVae = state.canvasV2.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"
|
||||||
@ -174,14 +169,14 @@ const handleLoRAModels: ModelHandler = (models, state, dispatch, _log) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleControlAdapterModels: ModelHandler = (models, state, dispatch, _log) => {
|
const handleControlAdapterModels: ModelHandler = (models, state, dispatch, _log) => {
|
||||||
selectControlAdapterAll(state.controlAdapters).forEach((ca) => {
|
state.canvasV2.controlAdapters.forEach((ca) => {
|
||||||
const isModelAvailable = models.some((m) => m.key === ca.model?.key);
|
const isModelAvailable = models.some((m) => m.key === ca.model?.key);
|
||||||
|
|
||||||
if (isModelAvailable) {
|
if (isModelAvailable) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(controlAdapterModelCleared({ id: ca.id }));
|
dispatch(caModelChanged({ id: ca.id, modelConfig: null }));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import {
|
|||||||
setSteps,
|
setSteps,
|
||||||
vaePrecisionChanged,
|
vaePrecisionChanged,
|
||||||
vaeSelected,
|
vaeSelected,
|
||||||
} from 'features/parameters/store/generationSlice';
|
} from 'features/canvas/store/canvasSlice';
|
||||||
import {
|
import {
|
||||||
isParameterCFGRescaleMultiplier,
|
isParameterCFGRescaleMultiplier,
|
||||||
isParameterCFGScale,
|
isParameterCFGScale,
|
||||||
@ -30,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.generation.model;
|
const currentModel = state.canvasV2.params.model;
|
||||||
|
|
||||||
if (!currentModel) {
|
if (!currentModel) {
|
||||||
return;
|
return;
|
||||||
|
@ -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.generation.model?.base ?? 'sdxl');
|
const base_model = useAppSelector((s) => s.canvasV2.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) {
|
||||||
|
@ -9,7 +9,6 @@ import { $templates, selectNodesSlice } from 'features/nodes/store/nodesSlice';
|
|||||||
import type { Templates } from 'features/nodes/store/types';
|
import type { Templates } from 'features/nodes/store/types';
|
||||||
import { selectWorkflowSettingsSlice } from 'features/nodes/store/workflowSettingsSlice';
|
import { selectWorkflowSettingsSlice } from 'features/nodes/store/workflowSettingsSlice';
|
||||||
import { isInvocationNode } from 'features/nodes/types/invocation';
|
import { isInvocationNode } from 'features/nodes/types/invocation';
|
||||||
import { selectGenerationSlice } from 'features/parameters/store/generationSlice';
|
|
||||||
import { selectUpscalelice } from 'features/parameters/store/upscaleSlice';
|
import { selectUpscalelice } from 'features/parameters/store/upscaleSlice';
|
||||||
import { selectConfigSlice } from 'features/system/store/configSlice';
|
import { selectConfigSlice } from 'features/system/store/configSlice';
|
||||||
import { selectSystemSlice } from 'features/system/store/systemSlice';
|
import { selectSystemSlice } from 'features/system/store/systemSlice';
|
||||||
@ -30,7 +29,6 @@ const LAYER_TYPE_TO_TKEY: Record<CanvasEntity['type'], string> = {
|
|||||||
const createSelector = (templates: Templates) =>
|
const createSelector = (templates: Templates) =>
|
||||||
createMemoizedSelector(
|
createMemoizedSelector(
|
||||||
[
|
[
|
||||||
selectGenerationSlice,
|
|
||||||
selectSystemSlice,
|
selectSystemSlice,
|
||||||
selectNodesSlice,
|
selectNodesSlice,
|
||||||
selectWorkflowSettingsSlice,
|
selectWorkflowSettingsSlice,
|
||||||
@ -40,9 +38,9 @@ const createSelector = (templates: Templates) =>
|
|||||||
selectConfigSlice,
|
selectConfigSlice,
|
||||||
activeTabNameSelector,
|
activeTabNameSelector,
|
||||||
],
|
],
|
||||||
(generation, system, nodes, workflowSettings, dynamicPrompts, canvasV2, upscale, config, activeTabName) => {
|
(system, nodes, workflowSettings, dynamicPrompts, canvasV2, upscale, config, activeTabName) => {
|
||||||
const { model, positivePrompt } = generation;
|
|
||||||
const { bbox } = canvasV2;
|
const { bbox } = canvasV2;
|
||||||
|
const { model, positivePrompt } = canvasV2.params;
|
||||||
|
|
||||||
const { isConnected } = system;
|
const { isConnected } = system;
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@ import {
|
|||||||
setShouldSnapToGrid,
|
setShouldSnapToGrid,
|
||||||
} from 'features/canvas/store/canvasSlice';
|
} from 'features/canvas/store/canvasSlice';
|
||||||
import { CANVAS_GRID_SIZE_COARSE, CANVAS_GRID_SIZE_FINE } from 'features/canvas/store/constants';
|
import { CANVAS_GRID_SIZE_COARSE, CANVAS_GRID_SIZE_FINE } from 'features/canvas/store/constants';
|
||||||
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize';
|
import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize';
|
||||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
|
||||||
import type Konva from 'konva';
|
import type Konva from 'konva';
|
||||||
import type { GroupConfig } from 'konva/lib/Group';
|
import type { GroupConfig } from 'konva/lib/Group';
|
||||||
import type { KonvaEventObject } from 'konva/lib/Node';
|
import type { KonvaEventObject } from 'konva/lib/Node';
|
||||||
|
@ -3,6 +3,7 @@ import { createSlice } from '@reduxjs/toolkit';
|
|||||||
import type { PersistConfig, RootState } from 'app/store/store';
|
import type { PersistConfig, RootState } from 'app/store/store';
|
||||||
import { deepClone } from 'common/util/deepClone';
|
import { deepClone } from 'common/util/deepClone';
|
||||||
import { roundDownToMultiple, roundToMultiple } from 'common/util/roundDownToMultiple';
|
import { roundDownToMultiple, roundToMultiple } from 'common/util/roundDownToMultiple';
|
||||||
|
import { modelChanged } from 'features/canvas/store/canvasSlice';
|
||||||
import calculateCoordinates from 'features/canvas/util/calculateCoordinates';
|
import calculateCoordinates from 'features/canvas/util/calculateCoordinates';
|
||||||
import calculateScale from 'features/canvas/util/calculateScale';
|
import calculateScale from 'features/canvas/util/calculateScale';
|
||||||
import { STAGE_PADDING_PERCENTAGE } from 'features/canvas/util/constants';
|
import { STAGE_PADDING_PERCENTAGE } from 'features/canvas/util/constants';
|
||||||
@ -11,7 +12,6 @@ import getScaledBoundingBoxDimensions from 'features/canvas/util/getScaledBoundi
|
|||||||
import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize';
|
import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize';
|
||||||
import { initialAspectRatioState } from 'features/parameters/components/ImageSize/constants';
|
import { initialAspectRatioState } from 'features/parameters/components/ImageSize/constants';
|
||||||
import type { AspectRatioState } from 'features/parameters/components/ImageSize/types';
|
import type { AspectRatioState } from 'features/parameters/components/ImageSize/types';
|
||||||
import { modelChanged } from 'features/parameters/store/generationSlice';
|
|
||||||
import type { PayloadActionWithOptimalDimension } from 'features/parameters/store/types';
|
import type { PayloadActionWithOptimalDimension } from 'features/parameters/store/types';
|
||||||
import { getIsSizeOptimal, getOptimalDimension } from 'features/parameters/util/optimalDimension';
|
import { getIsSizeOptimal, getOptimalDimension } from 'features/parameters/util/optimalDimension';
|
||||||
import type { IRect, Vector2d } from 'konva/lib/types';
|
import type { IRect, Vector2d } from 'konva/lib/types';
|
||||||
|
@ -4,10 +4,10 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
|||||||
import IAIDndImage from 'common/components/IAIDndImage';
|
import IAIDndImage from 'common/components/IAIDndImage';
|
||||||
import IAIDndImageIcon from 'common/components/IAIDndImageIcon';
|
import IAIDndImageIcon from 'common/components/IAIDndImageIcon';
|
||||||
import { heightChanged, widthChanged } from 'features/controlLayers/store/canvasV2Slice';
|
import { heightChanged, widthChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import type { ControlAdapterData } from 'features/controlLayers/store/types';
|
import type { ControlAdapterData } from 'features/controlLayers/store/types';
|
||||||
import type { ImageDraggableData, TypesafeDroppableData } from 'features/dnd/types';
|
import type { ImageDraggableData, TypesafeDroppableData } from 'features/dnd/types';
|
||||||
import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize';
|
import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize';
|
||||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
|
||||||
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PiArrowCounterClockwiseBold, PiFloppyDiskBold, PiRulerBold } from 'react-icons/pi';
|
import { PiArrowCounterClockwiseBold, PiFloppyDiskBold, PiRulerBold } from 'react-icons/pi';
|
||||||
|
@ -13,7 +13,7 @@ type Props = {
|
|||||||
|
|
||||||
export const CAModelCombobox = memo(({ modelKey, onChange: onChangeModel }: Props) => {
|
export const CAModelCombobox = memo(({ modelKey, onChange: onChangeModel }: Props) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const currentBaseModel = useAppSelector((s) => s.generation.model?.base);
|
const currentBaseModel = useAppSelector((s) => s.canvasV2.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]);
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import { heightChanged, widthChanged } from 'features/controlLayers/store/canvas
|
|||||||
import type { ImageWithDims } from 'features/controlLayers/store/types';
|
import type { ImageWithDims } from 'features/controlLayers/store/types';
|
||||||
import type { ImageDraggableData, TypesafeDroppableData } from 'features/dnd/types';
|
import type { ImageDraggableData, TypesafeDroppableData } from 'features/dnd/types';
|
||||||
import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize';
|
import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize';
|
||||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import { memo, useCallback, useEffect, useMemo } from 'react';
|
import { memo, useCallback, useEffect, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PiArrowCounterClockwiseBold, PiRulerBold } from 'react-icons/pi';
|
import { PiArrowCounterClockwiseBold, PiRulerBold } from 'react-icons/pi';
|
||||||
|
@ -24,7 +24,7 @@ type Props = {
|
|||||||
|
|
||||||
export const IPAModelCombobox = memo(({ modelKey, onChangeModel, clipVisionModel, onChangeCLIPVisionModel }: Props) => {
|
export const IPAModelCombobox = memo(({ modelKey, onChangeModel, clipVisionModel, onChangeCLIPVisionModel }: Props) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const currentBaseModel = useAppSelector((s) => s.generation.model?.base);
|
const currentBaseModel = useAppSelector((s) => s.canvasV2.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]);
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|||||||
|
|
||||||
export const useAddCALayer = () => {
|
export const useAddCALayer = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const baseModel = useAppSelector((s) => s.generation.model?.base);
|
const baseModel = useAppSelector((s) => s.canvasV2.params.model?.base);
|
||||||
const [modelConfigs] = useControlNetAndT2IAdapterModels();
|
const [modelConfigs] = useControlNetAndT2IAdapterModels();
|
||||||
const model: ControlNetModelConfig | T2IAdapterModelConfig | null = useMemo(() => {
|
const model: ControlNetModelConfig | T2IAdapterModelConfig | null = useMemo(() => {
|
||||||
// prefer to use a model that matches the base model
|
// prefer to use a model that matches the base model
|
||||||
@ -48,7 +48,7 @@ export const useAddCALayer = () => {
|
|||||||
|
|
||||||
export const useAddIPALayer = () => {
|
export const useAddIPALayer = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const baseModel = useAppSelector((s) => s.generation.model?.base);
|
const baseModel = useAppSelector((s) => s.canvasV2.params.model?.base);
|
||||||
const [modelConfigs] = useIPAdapterModels();
|
const [modelConfigs] = useIPAdapterModels();
|
||||||
const model: IPAdapterModelConfig | null = useMemo(() => {
|
const model: IPAdapterModelConfig | null = useMemo(() => {
|
||||||
// prefer to use a model that matches the base model
|
// prefer to use a model that matches the base model
|
||||||
@ -72,7 +72,7 @@ export const useAddIPALayer = () => {
|
|||||||
|
|
||||||
export const useAddIPAdapterToRGLayer = (id: string) => {
|
export const useAddIPAdapterToRGLayer = (id: string) => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const baseModel = useAppSelector((s) => s.generation.model?.base);
|
const baseModel = useAppSelector((s) => s.canvasV2.params.model?.base);
|
||||||
const [modelConfigs] = useIPAdapterModels();
|
const [modelConfigs] = useIPAdapterModels();
|
||||||
const model: IPAdapterModelConfig | null = useMemo(() => {
|
const model: IPAdapterModelConfig | null = useMemo(() => {
|
||||||
// prefer to use a model that matches the base model
|
// prefer to use a model that matches the base model
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
import { selectCanvasSlice } from 'features/canvas/store/canvasSlice';
|
||||||
|
import { getOptimalDimension } from 'features/parameters/util/optimalDimension';
|
||||||
|
|
||||||
export const selectEntityCount = createSelector(selectCanvasSlice, (canvasV2) => {
|
export const selectEntityCount = createSelector(selectCanvasSlice, (canvasV2) => {
|
||||||
return (
|
return (
|
||||||
canvasV2.regions.length + canvasV2.controlAdapters.length + canvasV2.ipAdapters.length + canvasV2.layers.length
|
canvasV2.regions.length + canvasV2.controlAdapters.length + canvasV2.ipAdapters.length + canvasV2.layers.length
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const selectOptimalDimension = createSelector(selectCanvasSlice, (canvasV2) => {
|
||||||
|
return getOptimalDimension(canvasV2.params.model);
|
||||||
|
});
|
||||||
|
@ -7,6 +7,7 @@ import { useDownloadImage } from 'common/hooks/useDownloadImage';
|
|||||||
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
|
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
|
||||||
import { imagesToChangeSelected, isModalOpenChanged } from 'features/changeBoardModal/store/slice';
|
import { imagesToChangeSelected, isModalOpenChanged } from 'features/changeBoardModal/store/slice';
|
||||||
import { iiLayerAdded } from 'features/controlLayers/store/canvasV2Slice';
|
import { iiLayerAdded } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import { imagesToDeleteSelected } from 'features/deleteImageModal/store/slice';
|
import { imagesToDeleteSelected } from 'features/deleteImageModal/store/slice';
|
||||||
import { useImageActions } from 'features/gallery/hooks/useImageActions';
|
import { useImageActions } from 'features/gallery/hooks/useImageActions';
|
||||||
import { sentImageToCanvas, sentImageToImg2Img } from 'features/gallery/store/actions';
|
import { sentImageToCanvas, sentImageToImg2Img } from 'features/gallery/store/actions';
|
||||||
|
@ -17,7 +17,7 @@ const LoRASelect = () => {
|
|||||||
const [modelConfigs, { isLoading }] = useLoRAModels();
|
const [modelConfigs, { isLoading }] = useLoRAModels();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const addedLoRAs = useAppSelector(selectAddedLoRAs);
|
const addedLoRAs = useAppSelector(selectAddedLoRAs);
|
||||||
const currentBaseModel = useAppSelector((s) => s.generation.model?.base);
|
const currentBaseModel = useAppSelector((s) => s.canvasV2.params.model?.base);
|
||||||
|
|
||||||
const getIsDisabled = (lora: LoRAModelConfig): boolean => {
|
const getIsDisabled = (lora: LoRAModelConfig): boolean => {
|
||||||
const isCompatible = currentBaseModel === lora.base;
|
const isCompatible = currentBaseModel === lora.base;
|
||||||
|
@ -40,7 +40,7 @@ import {
|
|||||||
setSeed,
|
setSeed,
|
||||||
setSteps,
|
setSteps,
|
||||||
vaeSelected,
|
vaeSelected,
|
||||||
} from 'features/parameters/store/generationSlice';
|
} from 'features/canvas/store/canvasSlice';
|
||||||
import type {
|
import type {
|
||||||
ParameterCFGRescaleMultiplier,
|
ParameterCFGRescaleMultiplier,
|
||||||
ParameterCFGScale,
|
ParameterCFGScale,
|
||||||
|
@ -9,7 +9,7 @@ import { getHasMetadata, removeMetadata } from './canvas/metadata';
|
|||||||
import { CANVAS_COHERENCE_NOISE, METADATA, NOISE, POSITIVE_CONDITIONING } from './constants';
|
import { CANVAS_COHERENCE_NOISE, METADATA, NOISE, POSITIVE_CONDITIONING } from './constants';
|
||||||
|
|
||||||
export const prepareLinearUIBatch = (state: RootState, graph: NonNullableGraph, prepend: boolean): BatchConfig => {
|
export const prepareLinearUIBatch = (state: RootState, graph: NonNullableGraph, prepend: boolean): BatchConfig => {
|
||||||
const { iterations, model, shouldRandomizeSeed, seed } = state.generation;
|
const { iterations, model, shouldRandomizeSeed, seed } = state.canvasV2.params;
|
||||||
const { shouldConcatPrompts } = state.canvasV2;
|
const { shouldConcatPrompts } = state.canvasV2;
|
||||||
const { prompts, seedBehaviour } = state.dynamicPrompts;
|
const { prompts, seedBehaviour } = state.dynamicPrompts;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ export const addControlNetToLinearGraph = async (
|
|||||||
const controlNets = selectValidControlNets(state.controlAdapters).filter(
|
const controlNets = selectValidControlNets(state.controlAdapters).filter(
|
||||||
({ model, processedControlImage, processorType, controlImage, isEnabled }) => {
|
({ model, processedControlImage, processorType, controlImage, isEnabled }) => {
|
||||||
const hasModel = Boolean(model);
|
const hasModel = Boolean(model);
|
||||||
const doesBaseMatch = model?.base === state.generation.model?.base;
|
const doesBaseMatch = model?.base === state.canvasV2.params.model?.base;
|
||||||
const hasControlImage = (processedControlImage && processorType !== 'none') || controlImage;
|
const hasControlImage = (processedControlImage && processorType !== 'none') || controlImage;
|
||||||
|
|
||||||
return isEnabled && hasModel && doesBaseMatch && hasControlImage;
|
return isEnabled && hasModel && doesBaseMatch && hasControlImage;
|
||||||
|
@ -19,7 +19,7 @@ export const addIPAdapterToLinearGraph = async (
|
|||||||
|
|
||||||
const ipAdapters = selectValidIPAdapters(state.controlAdapters).filter(({ model, controlImage, isEnabled }) => {
|
const ipAdapters = selectValidIPAdapters(state.controlAdapters).filter(({ model, controlImage, isEnabled }) => {
|
||||||
const hasModel = Boolean(model);
|
const hasModel = Boolean(model);
|
||||||
const doesBaseMatch = model?.base === state.generation.model?.base;
|
const doesBaseMatch = model?.base === state.canvasV2.params.model?.base;
|
||||||
const hasControlImage = controlImage;
|
const hasControlImage = controlImage;
|
||||||
return isEnabled && hasModel && doesBaseMatch && hasControlImage;
|
return isEnabled && hasModel && doesBaseMatch && hasControlImage;
|
||||||
});
|
});
|
||||||
|
@ -34,13 +34,13 @@ export const addSDXLRefinerToGraph = async (
|
|||||||
refinerScheduler,
|
refinerScheduler,
|
||||||
refinerCFGScale,
|
refinerCFGScale,
|
||||||
refinerStart,
|
refinerStart,
|
||||||
} = state.sdxl;
|
} = state.canvasV2.params;
|
||||||
|
|
||||||
if (!refinerModel) {
|
if (!refinerModel) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { seamlessXAxis, seamlessYAxis } = state.generation;
|
const { seamlessXAxis, seamlessYAxis } = state.canvasV2.params;
|
||||||
const { boundingBoxScaleMethod } = state.canvas;
|
const { boundingBoxScaleMethod } = state.canvas;
|
||||||
|
|
||||||
const isUsingScaledDimensions = ['auto', 'manual'].includes(boundingBoxScaleMethod);
|
const isUsingScaledDimensions = ['auto', 'manual'].includes(boundingBoxScaleMethod);
|
||||||
|
@ -19,7 +19,7 @@ export const addSeamlessToLinearGraph = (
|
|||||||
modelLoaderNodeId: string
|
modelLoaderNodeId: string
|
||||||
): void => {
|
): void => {
|
||||||
// Remove Existing UNet Connections
|
// Remove Existing UNet Connections
|
||||||
const { seamlessXAxis, seamlessYAxis, vae } = state.generation;
|
const { seamlessXAxis, seamlessYAxis, vae } = state.canvasV2.params;
|
||||||
const isAutoVae = !vae;
|
const isAutoVae = !vae;
|
||||||
|
|
||||||
graph.nodes[SEAMLESS] = {
|
graph.nodes[SEAMLESS] = {
|
||||||
|
@ -20,7 +20,7 @@ export const addT2IAdaptersToLinearGraph = async (
|
|||||||
const t2iAdapters = selectValidT2IAdapters(state.controlAdapters).filter(
|
const t2iAdapters = selectValidT2IAdapters(state.controlAdapters).filter(
|
||||||
({ model, processedControlImage, processorType, controlImage, isEnabled }) => {
|
({ model, processedControlImage, processorType, controlImage, isEnabled }) => {
|
||||||
const hasModel = Boolean(model);
|
const hasModel = Boolean(model);
|
||||||
const doesBaseMatch = model?.base === state.generation.model?.base;
|
const doesBaseMatch = model?.base === state.canvasV2.params.model?.base;
|
||||||
const hasControlImage = (processedControlImage && processorType !== 'none') || controlImage;
|
const hasControlImage = (processedControlImage && processorType !== 'none') || controlImage;
|
||||||
|
|
||||||
return isEnabled && hasModel && doesBaseMatch && hasControlImage;
|
return isEnabled && hasModel && doesBaseMatch && hasControlImage;
|
||||||
|
@ -28,9 +28,9 @@ export const addVAEToGraph = async (
|
|||||||
graph: NonNullableGraph,
|
graph: NonNullableGraph,
|
||||||
modelLoaderNodeId: string = MAIN_MODEL_LOADER
|
modelLoaderNodeId: string = MAIN_MODEL_LOADER
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const { vae, seamlessXAxis, seamlessYAxis } = state.generation;
|
const { vae, seamlessXAxis, seamlessYAxis } = state.canvasV2.params;
|
||||||
const { boundingBoxScaleMethod } = state.canvas;
|
const { boundingBoxScaleMethod } = state.canvas;
|
||||||
const { refinerModel } = state.sdxl;
|
const { refinerModel } = state.canvasV2.params;
|
||||||
|
|
||||||
const isUsingScaledDimensions = ['auto', 'manual'].includes(boundingBoxScaleMethod);
|
const isUsingScaledDimensions = ['auto', 'manual'].includes(boundingBoxScaleMethod);
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ export const buildCanvasGraph = async (
|
|||||||
let graph: NonNullableGraph;
|
let graph: NonNullableGraph;
|
||||||
|
|
||||||
if (generationMode === 'txt2img') {
|
if (generationMode === 'txt2img') {
|
||||||
if (state.generation.model && state.generation.model.base === 'sdxl') {
|
if (state.canvasV2.params.model && state.canvasV2.params.model.base === 'sdxl') {
|
||||||
graph = await buildCanvasSDXLTextToImageGraph(state);
|
graph = await buildCanvasSDXLTextToImageGraph(state);
|
||||||
} else {
|
} else {
|
||||||
graph = await buildCanvasTextToImageGraph(state);
|
graph = await buildCanvasTextToImageGraph(state);
|
||||||
@ -28,7 +28,7 @@ export const buildCanvasGraph = async (
|
|||||||
if (!canvasInitImage) {
|
if (!canvasInitImage) {
|
||||||
throw new Error('Missing canvas init image');
|
throw new Error('Missing canvas init image');
|
||||||
}
|
}
|
||||||
if (state.generation.model && state.generation.model.base === 'sdxl') {
|
if (state.canvasV2.params.model && state.canvasV2.params.model.base === 'sdxl') {
|
||||||
graph = await buildCanvasSDXLImageToImageGraph(state, canvasInitImage);
|
graph = await buildCanvasSDXLImageToImageGraph(state, canvasInitImage);
|
||||||
} else {
|
} else {
|
||||||
graph = await buildCanvasImageToImageGraph(state, canvasInitImage);
|
graph = await buildCanvasImageToImageGraph(state, canvasInitImage);
|
||||||
@ -37,7 +37,7 @@ export const buildCanvasGraph = async (
|
|||||||
if (!canvasInitImage || !canvasMaskImage) {
|
if (!canvasInitImage || !canvasMaskImage) {
|
||||||
throw new Error('Missing canvas init and mask images');
|
throw new Error('Missing canvas init and mask images');
|
||||||
}
|
}
|
||||||
if (state.generation.model && state.generation.model.base === 'sdxl') {
|
if (state.canvasV2.params.model && state.canvasV2.params.model.base === 'sdxl') {
|
||||||
graph = await buildCanvasSDXLInpaintGraph(state, canvasInitImage, canvasMaskImage);
|
graph = await buildCanvasSDXLInpaintGraph(state, canvasInitImage, canvasMaskImage);
|
||||||
} else {
|
} else {
|
||||||
graph = await buildCanvasInpaintGraph(state, canvasInitImage, canvasMaskImage);
|
graph = await buildCanvasInpaintGraph(state, canvasInitImage, canvasMaskImage);
|
||||||
@ -46,7 +46,7 @@ export const buildCanvasGraph = async (
|
|||||||
if (!canvasInitImage) {
|
if (!canvasInitImage) {
|
||||||
throw new Error('Missing canvas init image');
|
throw new Error('Missing canvas init image');
|
||||||
}
|
}
|
||||||
if (state.generation.model && state.generation.model.base === 'sdxl') {
|
if (state.canvasV2.params.model && state.canvasV2.params.model.base === 'sdxl') {
|
||||||
graph = await buildCanvasSDXLOutpaintGraph(state, canvasInitImage, canvasMaskImage);
|
graph = await buildCanvasSDXLOutpaintGraph(state, canvasInitImage, canvasMaskImage);
|
||||||
} else {
|
} else {
|
||||||
graph = await buildCanvasOutpaintGraph(state, canvasInitImage, canvasMaskImage);
|
graph = await buildCanvasOutpaintGraph(state, canvasInitImage, canvasMaskImage);
|
||||||
|
@ -54,7 +54,7 @@ export const buildCanvasImageToImageGraph = async (
|
|||||||
shouldUseCpuNoise,
|
shouldUseCpuNoise,
|
||||||
seamlessXAxis,
|
seamlessXAxis,
|
||||||
seamlessYAxis,
|
seamlessYAxis,
|
||||||
} = state.generation;
|
} = state.canvasV2.params;
|
||||||
|
|
||||||
// The bounding box determines width and height, not the width and height params
|
// The bounding box determines width and height, not the width and height params
|
||||||
const { width, height } = state.canvas.boundingBoxDimensions;
|
const { width, height } = state.canvas.boundingBoxDimensions;
|
||||||
|
@ -61,7 +61,7 @@ export const buildCanvasInpaintGraph = async (
|
|||||||
canvasCoherenceMinDenoise,
|
canvasCoherenceMinDenoise,
|
||||||
canvasCoherenceEdgeSize,
|
canvasCoherenceEdgeSize,
|
||||||
maskBlur,
|
maskBlur,
|
||||||
} = state.generation;
|
} = state.canvasV2.params;
|
||||||
|
|
||||||
if (!model) {
|
if (!model) {
|
||||||
log.error('No model found in state');
|
log.error('No model found in state');
|
||||||
|
@ -73,7 +73,7 @@ export const buildCanvasOutpaintGraph = async (
|
|||||||
canvasCoherenceMinDenoise,
|
canvasCoherenceMinDenoise,
|
||||||
canvasCoherenceEdgeSize,
|
canvasCoherenceEdgeSize,
|
||||||
maskBlur,
|
maskBlur,
|
||||||
} = state.generation;
|
} = state.canvasV2.params;
|
||||||
|
|
||||||
if (!model) {
|
if (!model) {
|
||||||
log.error('No model found in state');
|
log.error('No model found in state');
|
||||||
|
@ -54,9 +54,9 @@ export const buildCanvasSDXLImageToImageGraph = async (
|
|||||||
seamlessXAxis,
|
seamlessXAxis,
|
||||||
seamlessYAxis,
|
seamlessYAxis,
|
||||||
img2imgStrength: strength,
|
img2imgStrength: strength,
|
||||||
} = state.generation;
|
} = state.canvasV2.params;
|
||||||
|
|
||||||
const { refinerModel, refinerStart } = state.sdxl;
|
const { refinerModel, refinerStart } = state.canvasV2.params;
|
||||||
|
|
||||||
// The bounding box determines width and height, not the width and height params
|
// The bounding box determines width and height, not the width and height params
|
||||||
const { width, height } = state.canvas.boundingBoxDimensions;
|
const { width, height } = state.canvas.boundingBoxDimensions;
|
||||||
|
@ -61,9 +61,9 @@ export const buildCanvasSDXLInpaintGraph = async (
|
|||||||
canvasCoherenceMinDenoise,
|
canvasCoherenceMinDenoise,
|
||||||
canvasCoherenceEdgeSize,
|
canvasCoherenceEdgeSize,
|
||||||
maskBlur,
|
maskBlur,
|
||||||
} = state.generation;
|
} = state.canvasV2.params;
|
||||||
|
|
||||||
const { refinerModel, refinerStart } = state.sdxl;
|
const { refinerModel, refinerStart } = state.canvasV2.params;
|
||||||
|
|
||||||
if (!model) {
|
if (!model) {
|
||||||
log.error('No model found in state');
|
log.error('No model found in state');
|
||||||
|
@ -73,9 +73,9 @@ export const buildCanvasSDXLOutpaintGraph = async (
|
|||||||
canvasCoherenceMinDenoise,
|
canvasCoherenceMinDenoise,
|
||||||
canvasCoherenceEdgeSize,
|
canvasCoherenceEdgeSize,
|
||||||
maskBlur,
|
maskBlur,
|
||||||
} = state.generation;
|
} = state.canvasV2.params;
|
||||||
|
|
||||||
const { refinerModel, refinerStart } = state.sdxl;
|
const { refinerModel, refinerStart } = state.canvasV2.params;
|
||||||
|
|
||||||
if (!model) {
|
if (!model) {
|
||||||
log.error('No model found in state');
|
log.error('No model found in state');
|
||||||
|
@ -47,7 +47,7 @@ export const buildCanvasSDXLTextToImageGraph = async (state: RootState): Promise
|
|||||||
shouldUseCpuNoise,
|
shouldUseCpuNoise,
|
||||||
seamlessXAxis,
|
seamlessXAxis,
|
||||||
seamlessYAxis,
|
seamlessYAxis,
|
||||||
} = state.generation;
|
} = state.canvasV2.params;
|
||||||
|
|
||||||
// The bounding box determines width and height, not the width and height params
|
// The bounding box determines width and height, not the width and height params
|
||||||
const { width, height } = state.canvas.boundingBoxDimensions;
|
const { width, height } = state.canvas.boundingBoxDimensions;
|
||||||
@ -58,7 +58,7 @@ export const buildCanvasSDXLTextToImageGraph = async (state: RootState): Promise
|
|||||||
const is_intermediate = true;
|
const is_intermediate = true;
|
||||||
const isUsingScaledDimensions = ['auto', 'manual'].includes(boundingBoxScaleMethod);
|
const isUsingScaledDimensions = ['auto', 'manual'].includes(boundingBoxScaleMethod);
|
||||||
|
|
||||||
const { refinerModel, refinerStart } = state.sdxl;
|
const { refinerModel, refinerStart } = state.canvasV2.params;
|
||||||
|
|
||||||
if (!model) {
|
if (!model) {
|
||||||
log.error('No model found in state');
|
log.error('No model found in state');
|
||||||
|
@ -47,7 +47,7 @@ export const buildCanvasTextToImageGraph = async (state: RootState): Promise<Non
|
|||||||
shouldUseCpuNoise,
|
shouldUseCpuNoise,
|
||||||
seamlessXAxis,
|
seamlessXAxis,
|
||||||
seamlessYAxis,
|
seamlessYAxis,
|
||||||
} = state.generation;
|
} = state.canvasV2.params;
|
||||||
|
|
||||||
// The bounding box determines width and height, not the width and height params
|
// The bounding box determines width and height, not the width and height params
|
||||||
const { width, height } = state.canvas.boundingBoxDimensions;
|
const { width, height } = state.canvas.boundingBoxDimensions;
|
||||||
|
@ -419,8 +419,8 @@ const addInitialImageLayerToGraph = (
|
|||||||
| Invocation<'sdxl_model_loader'>,
|
| Invocation<'sdxl_model_loader'>,
|
||||||
layer: InitialImageLayer
|
layer: InitialImageLayer
|
||||||
) => {
|
) => {
|
||||||
const { vaePrecision } = state.generation;
|
const { vaePrecision } = state.canvasV2.params;
|
||||||
const { refinerModel, refinerStart } = state.sdxl;
|
const { refinerModel, refinerStart } = state.canvasV2.params;
|
||||||
const { width, height } = state.canvasV2.document;
|
const { width, height } = state.canvasV2.document;
|
||||||
assert(layer.isEnabled, 'Initial image layer is not enabled');
|
assert(layer.isEnabled, 'Initial image layer is not enabled');
|
||||||
assert(layer.image, 'Initial image layer has no image');
|
assert(layer.image, 'Initial image layer has no image');
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
} from 'features/nodes/util/graph/constants';
|
} from 'features/nodes/util/graph/constants';
|
||||||
import type { Graph } from 'features/nodes/util/graph/generation/Graph';
|
import type { Graph } from 'features/nodes/util/graph/generation/Graph';
|
||||||
import { getBoardField } from 'features/nodes/util/graph/graphBuilderUtils';
|
import { getBoardField } from 'features/nodes/util/graph/graphBuilderUtils';
|
||||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import type { Invocation } from 'services/api/types';
|
import type { Invocation } from 'services/api/types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,7 +30,7 @@ export const addSDXLRefiner = async (
|
|||||||
refinerScheduler,
|
refinerScheduler,
|
||||||
refinerCFGScale,
|
refinerCFGScale,
|
||||||
refinerStart,
|
refinerStart,
|
||||||
} = state.sdxl;
|
} = state.canvasV2.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.generation;
|
const { seamlessXAxis: seamless_x, seamlessYAxis: seamless_y } = state.canvasV2.params;
|
||||||
|
|
||||||
if (!seamless_x && !seamless_y) {
|
if (!seamless_x && !seamless_y) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -39,7 +39,7 @@ export const buildGenerationTabGraph = async (state: RootState): Promise<GraphTy
|
|||||||
vaePrecision,
|
vaePrecision,
|
||||||
seed,
|
seed,
|
||||||
vae,
|
vae,
|
||||||
} = state.generation;
|
} = state.canvasV2.params;
|
||||||
const { width, height } = state.canvasV2.document;
|
const { width, height } = state.canvasV2.document;
|
||||||
|
|
||||||
assert(model, 'No model found in state');
|
assert(model, 'No model found in state');
|
||||||
|
@ -35,10 +35,10 @@ export const buildGenerationTabSDXLGraph = async (state: RootState): Promise<Non
|
|||||||
shouldUseCpuNoise,
|
shouldUseCpuNoise,
|
||||||
vaePrecision,
|
vaePrecision,
|
||||||
vae,
|
vae,
|
||||||
} = state.generation;
|
} = state.canvasV2.params;
|
||||||
const { width, height } = state.canvasV2.document;
|
const { width, height } = state.canvasV2.document;
|
||||||
|
|
||||||
const { refinerModel, refinerStart } = state.sdxl;
|
const { refinerModel, refinerStart } = state.canvasV2.params;
|
||||||
|
|
||||||
assert(model, 'No model found in state');
|
assert(model, 'No model found in state');
|
||||||
|
|
||||||
|
@ -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/parameters/store/generationSlice';
|
import { setCfgRescaleMultiplier } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.cfgRescaleMultiplier);
|
const cfgRescaleMultiplier = useAppSelector((s) => s.canvasV2.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/parameters/store/generationSlice';
|
import { setClipSkip } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.clipSkip);
|
const clipSkip = useAppSelector((s) => s.canvasV2.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.generation);
|
const model = useAppSelector((s) => s.canvasV2.params.model);
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import { useImageSizeContext } from 'features/parameters/components/ImageSize/ImageSizeContext';
|
import { useImageSizeContext } from 'features/parameters/components/ImageSize/ImageSizeContext';
|
||||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
|
||||||
import { useImageSizeContext } from 'features/parameters/components/ImageSize/ImageSizeContext';
|
import { useImageSizeContext } from 'features/parameters/components/ImageSize/ImageSizeContext';
|
||||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
@ -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/parameters/store/generationSlice';
|
import { setCanvasCoherenceEdgeSize } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.canvasCoherenceEdgeSize);
|
const canvasCoherenceEdgeSize = useAppSelector((s) => s.canvasV2.compositing.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/parameters/store/generationSlice';
|
import { setCanvasCoherenceMinDenoise } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.canvasCoherenceMinDenoise);
|
const canvasCoherenceMinDenoise = useAppSelector((s) => s.canvasV2.compositing.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/parameters/store/generationSlice';
|
import { setCanvasCoherenceMode } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.canvasCoherenceMode);
|
const canvasCoherenceMode = useAppSelector((s) => s.canvasV2.compositing.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/parameters/store/generationSlice';
|
import { setMaskBlur } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.maskBlur);
|
const maskBlur = useAppSelector((s) => s.canvasV2.compositing.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,20 +1,16 @@
|
|||||||
import { Box, Flex, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
import { Box, Flex, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
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 { selectGenerationSlice, setInfillColorValue } from 'features/parameters/store/generationSlice';
|
import { setInfillColorValue } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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';
|
||||||
|
|
||||||
const selectInfillColor = createMemoizedSelector(selectGenerationSlice, (generation) => generation.infillColorValue);
|
|
||||||
|
|
||||||
const ParamInfillColorOptions = () => {
|
const ParamInfillColorOptions = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const infillColor = useAppSelector(selectInfillColor);
|
const infillColor = useAppSelector((s) => s.canvasV2.compositing.infillColorValue);
|
||||||
|
const infillMethod = useAppSelector((s) => s.canvasV2.compositing.infillMethod);
|
||||||
const infillMethod = useAppSelector((s) => s.generation.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/parameters/store/generationSlice';
|
import { setInfillMethod } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.infillMethod);
|
const infillMethod = useAppSelector((s) => s.canvasV2.compositing.infillMethod);
|
||||||
const { data: appConfigData } = useGetAppConfigQuery();
|
const { data: appConfigData } = useGetAppConfigQuery();
|
||||||
const options = useMemo<ComboboxOption[]>(
|
const options = useMemo<ComboboxOption[]>(
|
||||||
() =>
|
() =>
|
||||||
|
@ -1,115 +0,0 @@
|
|||||||
import { Box, CompositeNumberInput, CompositeSlider, Flex, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
|
||||||
import IAIColorPicker from 'common/components/IAIColorPicker';
|
|
||||||
import {
|
|
||||||
setInfillMosaicMaxColor,
|
|
||||||
setInfillMosaicMinColor,
|
|
||||||
setInfillMosaicTileHeight,
|
|
||||||
setInfillMosaicTileWidth,
|
|
||||||
} from 'features/parameters/store/generationSlice';
|
|
||||||
import { memo, useCallback } from 'react';
|
|
||||||
import type { RgbaColor } from 'react-colorful';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
const ParamInfillMosaicTileSize = () => {
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
|
|
||||||
const infillMosaicTileWidth = useAppSelector((s) => s.generation.infillMosaicTileWidth);
|
|
||||||
const infillMosaicTileHeight = useAppSelector((s) => s.generation.infillMosaicTileHeight);
|
|
||||||
const infillMosaicMinColor = useAppSelector((s) => s.generation.infillMosaicMinColor);
|
|
||||||
const infillMosaicMaxColor = useAppSelector((s) => s.generation.infillMosaicMaxColor);
|
|
||||||
const infillMethod = useAppSelector((s) => s.generation.infillMethod);
|
|
||||||
|
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const handleInfillMosaicTileWidthChange = useCallback(
|
|
||||||
(v: number) => {
|
|
||||||
dispatch(setInfillMosaicTileWidth(v));
|
|
||||||
},
|
|
||||||
[dispatch]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleInfillMosaicTileHeightChange = useCallback(
|
|
||||||
(v: number) => {
|
|
||||||
dispatch(setInfillMosaicTileHeight(v));
|
|
||||||
},
|
|
||||||
[dispatch]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleInfillMosaicMinColor = useCallback(
|
|
||||||
(v: RgbaColor) => {
|
|
||||||
dispatch(setInfillMosaicMinColor(v));
|
|
||||||
},
|
|
||||||
[dispatch]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleInfillMosaicMaxColor = useCallback(
|
|
||||||
(v: RgbaColor) => {
|
|
||||||
dispatch(setInfillMosaicMaxColor(v));
|
|
||||||
},
|
|
||||||
[dispatch]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Flex flexDir="column" gap={4}>
|
|
||||||
<FormControl isDisabled={infillMethod !== 'mosaic'}>
|
|
||||||
<FormLabel>{t('parameters.infillMosaicTileWidth')}</FormLabel>
|
|
||||||
<CompositeSlider
|
|
||||||
min={8}
|
|
||||||
max={256}
|
|
||||||
value={infillMosaicTileWidth}
|
|
||||||
defaultValue={64}
|
|
||||||
onChange={handleInfillMosaicTileWidthChange}
|
|
||||||
step={8}
|
|
||||||
fineStep={8}
|
|
||||||
marks
|
|
||||||
/>
|
|
||||||
<CompositeNumberInput
|
|
||||||
min={8}
|
|
||||||
max={1024}
|
|
||||||
value={infillMosaicTileWidth}
|
|
||||||
defaultValue={64}
|
|
||||||
onChange={handleInfillMosaicTileWidthChange}
|
|
||||||
step={8}
|
|
||||||
fineStep={8}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormControl isDisabled={infillMethod !== 'mosaic'}>
|
|
||||||
<FormLabel>{t('parameters.infillMosaicTileHeight')}</FormLabel>
|
|
||||||
<CompositeSlider
|
|
||||||
min={8}
|
|
||||||
max={256}
|
|
||||||
value={infillMosaicTileHeight}
|
|
||||||
defaultValue={64}
|
|
||||||
onChange={handleInfillMosaicTileHeightChange}
|
|
||||||
step={8}
|
|
||||||
fineStep={8}
|
|
||||||
marks
|
|
||||||
/>
|
|
||||||
<CompositeNumberInput
|
|
||||||
min={8}
|
|
||||||
max={1024}
|
|
||||||
value={infillMosaicTileHeight}
|
|
||||||
defaultValue={64}
|
|
||||||
onChange={handleInfillMosaicTileHeightChange}
|
|
||||||
step={8}
|
|
||||||
fineStep={8}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
<FormControl isDisabled={infillMethod !== 'mosaic'}>
|
|
||||||
<FormLabel>{t('parameters.infillMosaicMinColor')}</FormLabel>
|
|
||||||
<Box w="full" pt={2} pb={2}>
|
|
||||||
<IAIColorPicker color={infillMosaicMinColor} onChange={handleInfillMosaicMinColor} />
|
|
||||||
</Box>
|
|
||||||
</FormControl>
|
|
||||||
<FormControl isDisabled={infillMethod !== 'mosaic'}>
|
|
||||||
<FormLabel>{t('parameters.infillMosaicMaxColor')}</FormLabel>
|
|
||||||
<Box w="full" pt={2} pb={2}>
|
|
||||||
<IAIColorPicker color={infillMosaicMaxColor} onChange={handleInfillMosaicMaxColor} />
|
|
||||||
</Box>
|
|
||||||
</FormControl>
|
|
||||||
</Flex>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default memo(ParamInfillMosaicTileSize);
|
|
@ -2,12 +2,11 @@ import { useAppSelector } from 'app/store/storeHooks';
|
|||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
import ParamInfillColorOptions from './ParamInfillColorOptions';
|
import ParamInfillColorOptions from './ParamInfillColorOptions';
|
||||||
import ParamInfillMosaicOptions from './ParamInfillMosaicOptions';
|
|
||||||
import ParamInfillPatchmatchDownscaleSize from './ParamInfillPatchmatchDownscaleSize';
|
import ParamInfillPatchmatchDownscaleSize from './ParamInfillPatchmatchDownscaleSize';
|
||||||
import ParamInfillTilesize from './ParamInfillTilesize';
|
import ParamInfillTilesize from './ParamInfillTilesize';
|
||||||
|
|
||||||
const ParamInfillOptions = () => {
|
const ParamInfillOptions = () => {
|
||||||
const infillMethod = useAppSelector((s) => s.generation.infillMethod);
|
const infillMethod = useAppSelector((s) => s.canvasV2.compositing.infillMethod);
|
||||||
if (infillMethod === 'tile') {
|
if (infillMethod === 'tile') {
|
||||||
return <ParamInfillTilesize />;
|
return <ParamInfillTilesize />;
|
||||||
}
|
}
|
||||||
@ -16,10 +15,6 @@ const ParamInfillOptions = () => {
|
|||||||
return <ParamInfillPatchmatchDownscaleSize />;
|
return <ParamInfillPatchmatchDownscaleSize />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (infillMethod === 'mosaic') {
|
|
||||||
return <ParamInfillMosaicOptions />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (infillMethod === 'color') {
|
if (infillMethod === 'color') {
|
||||||
return <ParamInfillColorOptions />;
|
return <ParamInfillColorOptions />;
|
||||||
}
|
}
|
||||||
|
@ -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/parameters/store/generationSlice';
|
import { setInfillPatchmatchDownscaleSize } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.infillMethod);
|
const infillMethod = useAppSelector((s) => s.canvasV2.compositing.infillMethod);
|
||||||
const infillPatchmatchDownscaleSize = useAppSelector((s) => s.generation.infillPatchmatchDownscaleSize);
|
const infillPatchmatchDownscaleSize = useAppSelector((s) => s.canvasV2.compositing.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/parameters/store/generationSlice';
|
import { setInfillTileSize } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.infillTileSize);
|
const infillTileSize = useAppSelector((s) => s.canvasV2.compositing.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.generation.infillMethod);
|
const infillMethod = useAppSelector((s) => s.canvasV2.compositing.infillMethod);
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
@ -4,14 +4,14 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
|||||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||||
import { setBoundingBoxScaleMethod } from 'features/canvas/store/canvasSlice';
|
import { setBoundingBoxScaleMethod } from 'features/canvas/store/canvasSlice';
|
||||||
import { isBoundingBoxScaleMethod } from 'features/canvas/store/canvasTypes';
|
import { isBoundingBoxScaleMethod } from 'features/canvas/store/canvasTypes';
|
||||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const ParamScaleBeforeProcessing = () => {
|
const ParamScaleBeforeProcessing = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const boundingBoxScaleMethod = useAppSelector((s) => s.canvas.boundingBoxScaleMethod);
|
const boundingBoxScaleMethod = useAppSelector((s) => s.canvasV2.scaledBbox.scaleMethod);
|
||||||
const optimalDimension = useAppSelector(selectOptimalDimension);
|
const optimalDimension = useAppSelector(selectOptimalDimension);
|
||||||
|
|
||||||
const OPTIONS: ComboboxOption[] = useMemo(
|
const OPTIONS: ComboboxOption[] = useMemo(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
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 { setScaledBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
|
import { setScaledBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
|
||||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
@ -9,8 +9,8 @@ const ParamScaledHeight = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const optimalDimension = useAppSelector(selectOptimalDimension);
|
const optimalDimension = useAppSelector(selectOptimalDimension);
|
||||||
const isManual = useAppSelector((s) => s.canvas.boundingBoxScaleMethod === 'manual');
|
const isManual = useAppSelector((s) => s.canvasV2.scaledBbox.scaleMethod === 'manual');
|
||||||
const height = useAppSelector((s) => s.canvas.scaledBoundingBoxDimensions.height);
|
const height = useAppSelector((s) => s.canvasV2.scaledBbox.height);
|
||||||
const sliderMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxHeight.sliderMin);
|
const sliderMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxHeight.sliderMin);
|
||||||
const sliderMax = useAppSelector((s) => s.config.sd.scaledBoundingBoxHeight.sliderMax);
|
const sliderMax = useAppSelector((s) => s.config.sd.scaledBoundingBoxHeight.sliderMax);
|
||||||
const numberInputMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxHeight.numberInputMin);
|
const numberInputMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxHeight.numberInputMin);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
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 { setScaledBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
|
import { setScaledBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
|
||||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
@ -9,8 +9,8 @@ const ParamScaledWidth = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const optimalDimension = useAppSelector(selectOptimalDimension);
|
const optimalDimension = useAppSelector(selectOptimalDimension);
|
||||||
const isManual = useAppSelector((s) => s.canvas.boundingBoxScaleMethod === 'manual');
|
const isManual = useAppSelector((s) => s.canvasV2.scaledBbox.scaleMethod === 'manual');
|
||||||
const width = useAppSelector((s) => s.canvas.scaledBoundingBoxDimensions.width);
|
const width = useAppSelector((s) => s.canvasV2.scaledBbox.width);
|
||||||
const sliderMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxWidth.sliderMin);
|
const sliderMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxWidth.sliderMin);
|
||||||
const sliderMax = useAppSelector((s) => s.config.sd.scaledBoundingBoxWidth.sliderMax);
|
const sliderMax = useAppSelector((s) => s.config.sd.scaledBoundingBoxWidth.sliderMax);
|
||||||
const numberInputMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxWidth.numberInputMin);
|
const numberInputMin = useAppSelector((s) => s.config.sd.scaledBoundingBoxWidth.numberInputMin);
|
||||||
|
@ -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 ImageToImageStrength from 'features/parameters/components/ImageToImage/ImageToImageStrength';
|
import ImageToImageStrength from 'features/parameters/components/ImageToImage/ImageToImageStrength';
|
||||||
import { setImg2imgStrength } from 'features/parameters/store/generationSlice';
|
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
|
|
||||||
const ParamImageToImageStrength = () => {
|
const ParamImageToImageStrength = () => {
|
||||||
const img2imgStrength = useAppSelector((s) => s.generation.img2imgStrength);
|
const img2imgStrength = useAppSelector((s) => s.canvasV2.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/parameters/store/generationSlice';
|
import { setCfgScale } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.cfgScale);
|
const cfgScale = useAppSelector((s) => s.canvasV2.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);
|
||||||
|
@ -2,7 +2,7 @@ import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||||
import { useImageSizeContext } from 'features/parameters/components/ImageSize/ImageSizeContext';
|
import { useImageSizeContext } from 'features/parameters/components/ImageSize/ImageSizeContext';
|
||||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
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 { 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';
|
||||||
import { negativePromptChanged } from 'features/parameters/store/generationSlice';
|
|
||||||
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
|
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
|
||||||
import { PromptPopover } from 'features/prompt/PromptPopover';
|
import { PromptPopover } from 'features/prompt/PromptPopover';
|
||||||
import { usePrompt } from 'features/prompt/usePrompt';
|
import { usePrompt } from 'features/prompt/usePrompt';
|
||||||
@ -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.generation.negativePrompt);
|
const prompt = useAppSelector((s) => s.canvasV2.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,10 +1,10 @@
|
|||||||
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 { 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';
|
||||||
import { ViewModePrompt } from 'features/parameters/components/Prompts/ViewModePrompt';
|
import { ViewModePrompt } from 'features/parameters/components/Prompts/ViewModePrompt';
|
||||||
import { positivePromptChanged } from 'features/parameters/store/generationSlice';
|
|
||||||
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
|
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
|
||||||
import { PromptPopover } from 'features/prompt/PromptPopover';
|
import { PromptPopover } from 'features/prompt/PromptPopover';
|
||||||
import { usePrompt } from 'features/prompt/usePrompt';
|
import { usePrompt } from 'features/prompt/usePrompt';
|
||||||
@ -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.generation.positivePrompt);
|
const prompt = useAppSelector((s) => s.canvasV2.params.positivePrompt);
|
||||||
const baseModel = useAppSelector((s) => s.generation.model)?.base;
|
const baseModel = useAppSelector((s) => s.canvasV2.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/parameters/store/generationSlice';
|
import { setScheduler } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.scheduler);
|
const scheduler = useAppSelector((s) => s.canvasV2.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/parameters/store/generationSlice';
|
import { setSteps } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.steps);
|
const steps = useAppSelector((s) => s.canvasV2.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);
|
||||||
|
@ -2,7 +2,7 @@ import { CompositeNumberInput, CompositeSlider, FormControl, FormLabel } from '@
|
|||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
import { InformationalPopover } from 'common/components/InformationalPopover/InformationalPopover';
|
||||||
import { useImageSizeContext } from 'features/parameters/components/ImageSize/ImageSizeContext';
|
import { useImageSizeContext } from 'features/parameters/components/ImageSize/ImageSizeContext';
|
||||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import { roundToMultiple } from 'common/util/roundDownToMultiple';
|
|||||||
import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize';
|
import { calculateNewSize } from 'features/parameters/components/ImageSize/calculateNewSize';
|
||||||
import { ASPECT_RATIO_MAP, initialAspectRatioState } from 'features/parameters/components/ImageSize/constants';
|
import { ASPECT_RATIO_MAP, initialAspectRatioState } from 'features/parameters/components/ImageSize/constants';
|
||||||
import type { AspectRatioID, AspectRatioState } from 'features/parameters/components/ImageSize/types';
|
import type { AspectRatioID, AspectRatioState } from 'features/parameters/components/ImageSize/types';
|
||||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import { createContext, useCallback, useContext, useMemo } from 'react';
|
import { createContext, useCallback, useContext, useMemo } from 'react';
|
||||||
|
|
||||||
export type ImageSizeContextInnerValue = {
|
export type ImageSizeContextInnerValue = {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { IconButton } from '@invoke-ai/ui-library';
|
import { IconButton } from '@invoke-ai/ui-library';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { useImageSizeContext } from 'features/parameters/components/ImageSize/ImageSizeContext';
|
import { useImageSizeContext } from 'features/parameters/components/ImageSize/ImageSizeContext';
|
||||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import { getIsSizeTooLarge, getIsSizeTooSmall } from 'features/parameters/util/optimalDimension';
|
import { getIsSizeTooLarge, getIsSizeTooSmall } from 'features/parameters/util/optimalDimension';
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
@ -1,22 +1,18 @@
|
|||||||
import { Box, Combobox, FormControl, FormLabel, Tooltip } from '@invoke-ai/ui-library';
|
import { Box, Combobox, FormControl, FormLabel, Tooltip } from '@invoke-ai/ui-library';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
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 { zModelIdentifierField } from 'features/nodes/types/common';
|
import { zModelIdentifierField } from 'features/nodes/types/common';
|
||||||
import { modelSelected } from 'features/parameters/store/actions';
|
import { modelSelected } from 'features/parameters/store/actions';
|
||||||
import { selectGenerationSlice } from 'features/parameters/store/generationSlice';
|
|
||||||
import { memo, useCallback, useMemo } from 'react';
|
import { memo, useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useMainModels } from 'services/api/hooks/modelsByType';
|
import { useMainModels } from 'services/api/hooks/modelsByType';
|
||||||
import type { MainModelConfig } from 'services/api/types';
|
import type { MainModelConfig } from 'services/api/types';
|
||||||
|
|
||||||
const selectModel = createMemoizedSelector(selectGenerationSlice, (generation) => generation.model);
|
|
||||||
|
|
||||||
const ParamMainModelSelect = () => {
|
const ParamMainModelSelect = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const selectedModel = useAppSelector(selectModel);
|
const selectedModel = useAppSelector((s) => s.canvasV2.params.model);
|
||||||
const [modelConfigs, { isLoading }] = useMainModels();
|
const [modelConfigs, { isLoading }] = useMainModels();
|
||||||
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.generation.model);
|
const model = useAppSelector((s) => s.canvasV2.params.model);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
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 { setSeamlessXAxis } from 'features/parameters/store/generationSlice';
|
import { setSeamlessXAxis } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.seamlessXAxis);
|
const seamlessXAxis = useAppSelector((s) => s.canvasV2.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/parameters/store/generationSlice';
|
import { setSeamlessYAxis } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.seamlessYAxis);
|
const seamlessYAxis = useAppSelector((s) => s.canvasV2.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/parameters/store/generationSlice';
|
import { setSeed } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.seed);
|
const seed = useAppSelector((s) => s.canvasV2.params.seed);
|
||||||
const shouldRandomizeSeed = useAppSelector((s) => s.generation.shouldRandomizeSeed);
|
const shouldRandomizeSeed = useAppSelector((s) => s.canvasV2.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/parameters/store/generationSlice';
|
import { setShouldRandomizeSeed } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.shouldRandomizeSeed);
|
const shouldRandomizeSeed = useAppSelector((s) => s.canvasV2.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/parameters/store/generationSlice';
|
import { setSeed } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.shouldRandomizeSeed);
|
const shouldRandomizeSeed = useAppSelector((s) => s.canvasV2.params.shouldRandomizeSeed);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleClickRandomizeSeed = useCallback(
|
const handleClickRandomizeSeed = useCallback(
|
||||||
|
@ -1,24 +1,19 @@
|
|||||||
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
import { Combobox, FormControl, FormLabel } from '@invoke-ai/ui-library';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
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 { zModelIdentifierField } from 'features/nodes/types/common';
|
import { zModelIdentifierField } from 'features/nodes/types/common';
|
||||||
import { selectGenerationSlice, vaeSelected } from 'features/parameters/store/generationSlice';
|
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useVAEModels } from 'services/api/hooks/modelsByType';
|
import { useVAEModels } from 'services/api/hooks/modelsByType';
|
||||||
import type { VAEModelConfig } from 'services/api/types';
|
import type { VAEModelConfig } from 'services/api/types';
|
||||||
|
|
||||||
const selector = createMemoizedSelector(selectGenerationSlice, (generation) => {
|
|
||||||
const { model, vae } = generation;
|
|
||||||
return { model, vae };
|
|
||||||
});
|
|
||||||
|
|
||||||
const ParamVAEModelSelect = () => {
|
const ParamVAEModelSelect = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { model, vae } = useAppSelector(selector);
|
const model = useAppSelector((s) => s.canvasV2.params.model);
|
||||||
|
const vae = useAppSelector((s) => s.canvasV2.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/parameters/store/generationSlice';
|
import { vaePrecisionChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.vaePrecision);
|
const vaePrecision = useAppSelector((s) => s.canvasV2.params.vaePrecision);
|
||||||
|
|
||||||
const onChange = useCallback<ComboboxOnChange>(
|
const onChange = useCallback<ComboboxOnChange>(
|
||||||
(v) => {
|
(v) => {
|
||||||
|
@ -2,8 +2,8 @@ import { skipToken } from '@reduxjs/toolkit/query';
|
|||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
|
import { setInitialCanvasImage } from 'features/canvas/store/canvasSlice';
|
||||||
import { iiLayerAdded } from 'features/controlLayers/store/canvasV2Slice';
|
import { iiLayerAdded } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
|
import { selectOptimalDimension } from 'features/controlLayers/store/selectors';
|
||||||
import { parseAndRecallAllMetadata } from 'features/metadata/util/handlers';
|
import { parseAndRecallAllMetadata } from 'features/metadata/util/handlers';
|
||||||
import { selectOptimalDimension } from 'features/parameters/store/generationSlice';
|
|
||||||
import { toast } from 'features/toast/toast';
|
import { toast } from 'features/toast/toast';
|
||||||
import { setActiveTab } from 'features/ui/store/uiSlice';
|
import { setActiveTab } from 'features/ui/store/uiSlice';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
|
@ -1,264 +0,0 @@
|
|||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
|
||||||
import { createSlice } from '@reduxjs/toolkit';
|
|
||||||
import type { PersistConfig, RootState } from 'app/store/store';
|
|
||||||
import { initialAspectRatioState } from 'features/parameters/components/ImageSize/constants';
|
|
||||||
import { CLIP_SKIP_MAP } from 'features/parameters/types/constants';
|
|
||||||
import type {
|
|
||||||
ParameterCanvasCoherenceMode,
|
|
||||||
ParameterCFGRescaleMultiplier,
|
|
||||||
ParameterCFGScale,
|
|
||||||
ParameterModel,
|
|
||||||
ParameterPrecision,
|
|
||||||
ParameterScheduler,
|
|
||||||
ParameterVAEModel,
|
|
||||||
} from 'features/parameters/types/parameterSchemas';
|
|
||||||
import { getOptimalDimension } from 'features/parameters/util/optimalDimension';
|
|
||||||
import { configChanged } from 'features/system/store/configSlice';
|
|
||||||
import { clamp } from 'lodash-es';
|
|
||||||
import type { RgbaColor } from 'react-colorful';
|
|
||||||
|
|
||||||
import type { GenerationState } from './types';
|
|
||||||
|
|
||||||
const initialGenerationState: GenerationState = {
|
|
||||||
_version: 2,
|
|
||||||
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,
|
|
||||||
shouldShowAdvancedOptions: false,
|
|
||||||
maskBlur: 16,
|
|
||||||
maskBlurMethod: 'box',
|
|
||||||
canvasCoherenceMode: 'Gaussian Blur',
|
|
||||||
canvasCoherenceMinDenoise: 0,
|
|
||||||
canvasCoherenceEdgeSize: 16,
|
|
||||||
infillMethod: 'patchmatch',
|
|
||||||
infillTileSize: 32,
|
|
||||||
infillPatchmatchDownscaleSize: 1,
|
|
||||||
infillMosaicTileWidth: 64,
|
|
||||||
infillMosaicTileHeight: 64,
|
|
||||||
infillMosaicMinColor: { r: 0, g: 0, b: 0, a: 1 },
|
|
||||||
infillMosaicMaxColor: { r: 255, g: 255, b: 255, a: 1 },
|
|
||||||
infillColorValue: { r: 0, g: 0, b: 0, a: 1 },
|
|
||||||
positivePrompt: '',
|
|
||||||
negativePrompt: '',
|
|
||||||
positivePrompt2: '',
|
|
||||||
negativePrompt2: '',
|
|
||||||
shouldConcatPrompts: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const generationSlice = createSlice({
|
|
||||||
name: 'generation',
|
|
||||||
initialState: initialGenerationState,
|
|
||||||
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;
|
|
||||||
},
|
|
||||||
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;
|
|
||||||
},
|
|
||||||
modelChanged: {
|
|
||||||
reducer: (
|
|
||||||
state,
|
|
||||||
action: PayloadAction<ParameterModel | null, string, { previousModel?: ParameterModel | null }>
|
|
||||||
) => {
|
|
||||||
const newModel = action.payload;
|
|
||||||
state.model = newModel;
|
|
||||||
|
|
||||||
if (newModel === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clamp ClipSkip Based On Selected Model
|
|
||||||
// TODO(psyche): remove this special handling when https://github.com/invoke-ai/InvokeAI/issues/4583 is resolved
|
|
||||||
// WIP PR here: https://github.com/invoke-ai/InvokeAI/pull/4624
|
|
||||||
if (newModel.base === 'sdxl') {
|
|
||||||
// We don't support clip skip for SDXL yet - it's not in the graphs
|
|
||||||
state.clipSkip = 0;
|
|
||||||
} else {
|
|
||||||
const { maxClip } = CLIP_SKIP_MAP[newModel.base];
|
|
||||||
state.clipSkip = clamp(state.clipSkip, 0, maxClip);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
prepare: (payload: ParameterModel | null, previousModel?: ParameterModel | null) => ({
|
|
||||||
payload,
|
|
||||||
meta: {
|
|
||||||
previousModel,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
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;
|
|
||||||
},
|
|
||||||
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;
|
|
||||||
},
|
|
||||||
setInfillMosaicTileWidth: (state, action: PayloadAction<number>) => {
|
|
||||||
state.infillMosaicTileWidth = action.payload;
|
|
||||||
},
|
|
||||||
setInfillMosaicTileHeight: (state, action: PayloadAction<number>) => {
|
|
||||||
state.infillMosaicTileHeight = action.payload;
|
|
||||||
},
|
|
||||||
setInfillMosaicMinColor: (state, action: PayloadAction<RgbaColor>) => {
|
|
||||||
state.infillMosaicMinColor = action.payload;
|
|
||||||
},
|
|
||||||
setInfillMosaicMaxColor: (state, action: PayloadAction<RgbaColor>) => {
|
|
||||||
state.infillMosaicMaxColor = action.payload;
|
|
||||||
},
|
|
||||||
setInfillColorValue: (state, action: PayloadAction<RgbaColor>) => {
|
|
||||||
state.infillColorValue = action.payload;
|
|
||||||
},
|
|
||||||
positivePromptChanged: (state, action: PayloadAction<string>) => {
|
|
||||||
state.positivePrompt = action.payload;
|
|
||||||
},
|
|
||||||
negativePromptChanged: (state, action: PayloadAction<string>) => {
|
|
||||||
state.negativePrompt = action.payload;
|
|
||||||
},
|
|
||||||
positivePrompt2Changed: (state, action: PayloadAction<string>) => {
|
|
||||||
state.positivePrompt2 = action.payload;
|
|
||||||
},
|
|
||||||
negativePrompt2Changed: (state, action: PayloadAction<string>) => {
|
|
||||||
state.negativePrompt2 = action.payload;
|
|
||||||
},
|
|
||||||
shouldConcatPromptsChanged: (state, action: PayloadAction<boolean>) => {
|
|
||||||
state.shouldConcatPrompts = action.payload;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
extraReducers: (builder) => {
|
|
||||||
builder.addCase(configChanged, (state, action) => {
|
|
||||||
if (action.payload.sd?.scheduler) {
|
|
||||||
state.scheduler = action.payload.sd.scheduler;
|
|
||||||
}
|
|
||||||
if (action.payload.sd?.vaePrecision) {
|
|
||||||
state.vaePrecision = action.payload.sd.vaePrecision;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
selectors: {
|
|
||||||
selectOptimalDimension: (slice) => getOptimalDimension(slice.model),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const {
|
|
||||||
setCfgScale,
|
|
||||||
setCfgRescaleMultiplier,
|
|
||||||
setImg2imgStrength,
|
|
||||||
setInfillMethod,
|
|
||||||
setIterations,
|
|
||||||
setScheduler,
|
|
||||||
setMaskBlur,
|
|
||||||
setCanvasCoherenceMode,
|
|
||||||
setCanvasCoherenceEdgeSize,
|
|
||||||
setCanvasCoherenceMinDenoise,
|
|
||||||
setSeed,
|
|
||||||
setShouldRandomizeSeed,
|
|
||||||
setSteps,
|
|
||||||
modelChanged,
|
|
||||||
vaeSelected,
|
|
||||||
setSeamlessXAxis,
|
|
||||||
setSeamlessYAxis,
|
|
||||||
setClipSkip,
|
|
||||||
shouldUseCpuNoiseChanged,
|
|
||||||
vaePrecisionChanged,
|
|
||||||
setInfillTileSize,
|
|
||||||
setInfillPatchmatchDownscaleSize,
|
|
||||||
setInfillMosaicTileWidth,
|
|
||||||
setInfillMosaicTileHeight,
|
|
||||||
setInfillMosaicMinColor,
|
|
||||||
setInfillMosaicMaxColor,
|
|
||||||
setInfillColorValue,
|
|
||||||
positivePromptChanged,
|
|
||||||
negativePromptChanged,
|
|
||||||
positivePrompt2Changed,
|
|
||||||
negativePrompt2Changed,
|
|
||||||
shouldConcatPromptsChanged,
|
|
||||||
} = generationSlice.actions;
|
|
||||||
|
|
||||||
export const { selectOptimalDimension } = generationSlice.selectors;
|
|
||||||
|
|
||||||
export const selectGenerationSlice = (state: RootState) => state.generation;
|
|
||||||
|
|
||||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
||||||
const migrateGenerationState = (state: any): GenerationState => {
|
|
||||||
if (!('_version' in state)) {
|
|
||||||
state._version = 1;
|
|
||||||
state.aspectRatio = initialAspectRatioState;
|
|
||||||
}
|
|
||||||
if (state._version === 1) {
|
|
||||||
// The signature of the model has changed, so we need to reset it
|
|
||||||
state._version = 2;
|
|
||||||
state.model = null;
|
|
||||||
state.canvasCoherenceMode = initialGenerationState.canvasCoherenceMode;
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const generationPersistConfig: PersistConfig<GenerationState> = {
|
|
||||||
name: generationSlice.name,
|
|
||||||
initialState: initialGenerationState,
|
|
||||||
migrate: migrateGenerationState,
|
|
||||||
persistDenylist: [],
|
|
||||||
};
|
|
@ -1,59 +0,0 @@
|
|||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
|
||||||
import type {
|
|
||||||
ParameterCanvasCoherenceMode,
|
|
||||||
ParameterCFGRescaleMultiplier,
|
|
||||||
ParameterCFGScale,
|
|
||||||
ParameterMaskBlurMethod,
|
|
||||||
ParameterModel,
|
|
||||||
ParameterNegativePrompt,
|
|
||||||
ParameterNegativeStylePromptSDXL,
|
|
||||||
ParameterPositivePrompt,
|
|
||||||
ParameterPositiveStylePromptSDXL,
|
|
||||||
ParameterPrecision,
|
|
||||||
ParameterScheduler,
|
|
||||||
ParameterSeed,
|
|
||||||
ParameterSteps,
|
|
||||||
ParameterStrength,
|
|
||||||
ParameterVAEModel,
|
|
||||||
} from 'features/parameters/types/parameterSchemas';
|
|
||||||
import type { RgbaColor } from 'react-colorful';
|
|
||||||
|
|
||||||
export interface GenerationState {
|
|
||||||
_version: 2;
|
|
||||||
cfgScale: ParameterCFGScale;
|
|
||||||
cfgRescaleMultiplier: ParameterCFGRescaleMultiplier;
|
|
||||||
img2imgStrength: ParameterStrength;
|
|
||||||
infillMethod: string;
|
|
||||||
iterations: number;
|
|
||||||
scheduler: ParameterScheduler;
|
|
||||||
maskBlur: number;
|
|
||||||
maskBlurMethod: ParameterMaskBlurMethod;
|
|
||||||
canvasCoherenceMode: ParameterCanvasCoherenceMode;
|
|
||||||
canvasCoherenceMinDenoise: ParameterStrength;
|
|
||||||
canvasCoherenceEdgeSize: number;
|
|
||||||
seed: ParameterSeed;
|
|
||||||
shouldRandomizeSeed: boolean;
|
|
||||||
steps: ParameterSteps;
|
|
||||||
model: ParameterModel | null;
|
|
||||||
vae: ParameterVAEModel | null;
|
|
||||||
vaePrecision: ParameterPrecision;
|
|
||||||
seamlessXAxis: boolean;
|
|
||||||
seamlessYAxis: boolean;
|
|
||||||
clipSkip: number;
|
|
||||||
shouldUseCpuNoise: boolean;
|
|
||||||
shouldShowAdvancedOptions: boolean;
|
|
||||||
infillTileSize: number;
|
|
||||||
infillPatchmatchDownscaleSize: number;
|
|
||||||
infillMosaicTileWidth: number;
|
|
||||||
infillMosaicTileHeight: number;
|
|
||||||
infillMosaicMinColor: RgbaColor;
|
|
||||||
infillMosaicMaxColor: RgbaColor;
|
|
||||||
infillColorValue: RgbaColor;
|
|
||||||
positivePrompt: ParameterPositivePrompt;
|
|
||||||
negativePrompt: ParameterNegativePrompt;
|
|
||||||
positivePrompt2: ParameterPositiveStylePromptSDXL;
|
|
||||||
negativePrompt2: ParameterNegativeStylePromptSDXL;
|
|
||||||
shouldConcatPrompts: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PayloadActionWithOptimalDimension<T = void> = PayloadAction<T, string, { optimalDimension: number }>;
|
|
@ -1,11 +1,8 @@
|
|||||||
import type { ChakraProps, ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
|
import type { ChakraProps, ComboboxOnChange, ComboboxOption } from '@invoke-ai/ui-library';
|
||||||
import { Combobox, FormControl } from '@invoke-ai/ui-library';
|
import { Combobox, FormControl } from '@invoke-ai/ui-library';
|
||||||
import { skipToken } from '@reduxjs/toolkit/query';
|
import { skipToken } from '@reduxjs/toolkit/query';
|
||||||
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
|
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import type { GroupBase } from 'chakra-react-select';
|
import type { GroupBase } from 'chakra-react-select';
|
||||||
import { selectLoraSlice } from 'features/lora/store/loraSlice';
|
|
||||||
import { selectGenerationSlice } from 'features/parameters/store/generationSlice';
|
|
||||||
import type { PromptTriggerSelectProps } from 'features/prompt/types';
|
import type { PromptTriggerSelectProps } from 'features/prompt/types';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
import { flatten, map } from 'lodash-es';
|
import { flatten, map } from 'lodash-es';
|
||||||
@ -17,14 +14,11 @@ import { isNonRefinerMainModelConfig } from 'services/api/types';
|
|||||||
|
|
||||||
const noOptionsMessage = () => t('prompt.noMatchingTriggers');
|
const noOptionsMessage = () => t('prompt.noMatchingTriggers');
|
||||||
|
|
||||||
const selectLoRAs = createMemoizedSelector(selectLoraSlice, (loras) => loras.loras);
|
|
||||||
const selectMainModel = createMemoizedSelector(selectGenerationSlice, (generation) => generation.model);
|
|
||||||
|
|
||||||
export const PromptTriggerSelect = memo(({ onSelect, onClose }: PromptTriggerSelectProps) => {
|
export const PromptTriggerSelect = memo(({ onSelect, onClose }: PromptTriggerSelectProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const mainModel = useAppSelector(selectMainModel);
|
const mainModel = useAppSelector((s) => s.canvasV2.params.model);
|
||||||
const addedLoRAs = useAppSelector(selectLoRAs);
|
const addedLoRAs = useAppSelector((s) => s.lora.loras);
|
||||||
const { data: mainModelConfig, isLoading: isLoadingMainModelConfig } = useGetModelConfigQuery(
|
const { data: mainModelConfig, isLoading: isLoadingMainModelConfig } = useGetModelConfigQuery(
|
||||||
mainModel?.key ?? skipToken
|
mainModel?.key ?? skipToken
|
||||||
);
|
);
|
||||||
|
@ -35,7 +35,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.generation.iterations);
|
const iterationsCount = useAppSelector((s) => s.canvasV2.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/parameters/store/generationSlice';
|
import { setIterations } from 'features/canvas/store/canvasSlice';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
|
|
||||||
export const QueueIterationsNumberInput = memo(() => {
|
export const QueueIterationsNumberInput = memo(() => {
|
||||||
const iterations = useAppSelector((s) => s.generation.iterations);
|
const iterations = useAppSelector((s) => s.canvasV2.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,8 +1,8 @@
|
|||||||
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 { 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 { negativePrompt2Changed } from 'features/parameters/store/generationSlice';
|
|
||||||
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
|
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
|
||||||
import { PromptPopover } from 'features/prompt/PromptPopover';
|
import { PromptPopover } from 'features/prompt/PromptPopover';
|
||||||
import { usePrompt } from 'features/prompt/usePrompt';
|
import { usePrompt } from 'features/prompt/usePrompt';
|
||||||
@ -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.generation.negativePrompt2);
|
const prompt = useAppSelector((s) => s.canvasV2.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,8 +1,8 @@
|
|||||||
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 { 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 { positivePrompt2Changed } from 'features/parameters/store/generationSlice';
|
|
||||||
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
|
import { AddPromptTriggerButton } from 'features/prompt/AddPromptTriggerButton';
|
||||||
import { PromptPopover } from 'features/prompt/PromptPopover';
|
import { PromptPopover } from 'features/prompt/PromptPopover';
|
||||||
import { usePrompt } from 'features/prompt/usePrompt';
|
import { usePrompt } from 'features/prompt/usePrompt';
|
||||||
@ -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.generation.positivePrompt2);
|
const prompt = useAppSelector((s) => s.canvasV2.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/parameters/store/generationSlice';
|
import { shouldConcatPromptsChanged } from 'features/controlLayers/store/canvasV2Slice';
|
||||||
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.generation.shouldConcatPrompts);
|
const shouldConcatPrompts = useAppSelector((s) => s.canvasV2.params.shouldConcatPrompts);
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
@ -8,7 +8,7 @@ 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.sdxl.refinerCFGScale);
|
const refinerCFGScale = useAppSelector((s) => s.canvasV2.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);
|
||||||
|
@ -6,7 +6,7 @@ import { memo, useCallback } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const ParamSDXLRefinerNegativeAestheticScore = () => {
|
const ParamSDXLRefinerNegativeAestheticScore = () => {
|
||||||
const refinerNegativeAestheticScore = useAppSelector((s) => s.sdxl.refinerNegativeAestheticScore);
|
const refinerNegativeAestheticScore = useAppSelector((s) => s.canvasV2.params.refinerNegativeAestheticScore);
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
@ -6,7 +6,7 @@ import { memo, useCallback } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const ParamSDXLRefinerPositiveAestheticScore = () => {
|
const ParamSDXLRefinerPositiveAestheticScore = () => {
|
||||||
const refinerPositiveAestheticScore = useAppSelector((s) => s.sdxl.refinerPositiveAestheticScore);
|
const refinerPositiveAestheticScore = useAppSelector((s) => s.canvasV2.params.refinerPositiveAestheticScore);
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
@ -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.sdxl.refinerScheduler);
|
const refinerScheduler = useAppSelector((s) => s.canvasV2.params.refinerScheduler);
|
||||||
|
|
||||||
const onChange = useCallback<ComboboxOnChange>(
|
const onChange = useCallback<ComboboxOnChange>(
|
||||||
(v) => {
|
(v) => {
|
||||||
|
@ -6,7 +6,7 @@ import { memo, useCallback } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const ParamSDXLRefinerStart = () => {
|
const ParamSDXLRefinerStart = () => {
|
||||||
const refinerStart = useAppSelector((s) => s.sdxl.refinerStart);
|
const refinerStart = useAppSelector((s) => s.canvasV2.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();
|
||||||
|
@ -8,7 +8,7 @@ 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.sdxl.refinerSteps);
|
const refinerSteps = useAppSelector((s) => s.canvasV2.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);
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
|
||||||
import { createSlice } from '@reduxjs/toolkit';
|
|
||||||
import type { PersistConfig, RootState } from 'app/store/store';
|
|
||||||
import type { ParameterScheduler, ParameterSDXLRefinerModel } from 'features/parameters/types/parameterSchemas';
|
|
||||||
|
|
||||||
type SDXLState = {
|
|
||||||
_version: 2;
|
|
||||||
refinerModel: ParameterSDXLRefinerModel | null;
|
|
||||||
refinerSteps: number;
|
|
||||||
refinerCFGScale: number;
|
|
||||||
refinerScheduler: ParameterScheduler;
|
|
||||||
refinerPositiveAestheticScore: number;
|
|
||||||
refinerNegativeAestheticScore: number;
|
|
||||||
refinerStart: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
const initialSDXLState: SDXLState = {
|
|
||||||
_version: 2,
|
|
||||||
refinerModel: null,
|
|
||||||
refinerSteps: 20,
|
|
||||||
refinerCFGScale: 7.5,
|
|
||||||
refinerScheduler: 'euler',
|
|
||||||
refinerPositiveAestheticScore: 6,
|
|
||||||
refinerNegativeAestheticScore: 2.5,
|
|
||||||
refinerStart: 0.8,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const sdxlSlice = createSlice({
|
|
||||||
name: 'sdxl',
|
|
||||||
initialState: initialSDXLState,
|
|
||||||
reducers: {
|
|
||||||
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;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const {
|
|
||||||
refinerModelChanged,
|
|
||||||
setRefinerSteps,
|
|
||||||
setRefinerCFGScale,
|
|
||||||
setRefinerScheduler,
|
|
||||||
setRefinerPositiveAestheticScore,
|
|
||||||
setRefinerNegativeAestheticScore,
|
|
||||||
setRefinerStart,
|
|
||||||
} = sdxlSlice.actions;
|
|
||||||
|
|
||||||
export const selectSdxlSlice = (state: RootState) => state.sdxl;
|
|
||||||
|
|
||||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
||||||
const migrateSDXLState = (state: any): any => {
|
|
||||||
if (!('_version' in state)) {
|
|
||||||
state._version = 1;
|
|
||||||
}
|
|
||||||
if (state._version === 1) {
|
|
||||||
// Model type has changed, so we need to reset the state - too risky to migrate
|
|
||||||
state._version = 2;
|
|
||||||
state.refinerModel = null;
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const sdxlPersistConfig: PersistConfig<SDXLState> = {
|
|
||||||
name: sdxlSlice.name,
|
|
||||||
initialState: initialSDXLState,
|
|
||||||
migrate: migrateSDXLState,
|
|
||||||
persistDenylist: [],
|
|
||||||
};
|
|
@ -12,7 +12,7 @@ import { ParamSeedRandomize } from 'features/parameters/components/Seed/ParamSee
|
|||||||
import { ParamSeedShuffle } from 'features/parameters/components/Seed/ParamSeedShuffle';
|
import { ParamSeedShuffle } from 'features/parameters/components/Seed/ParamSeedShuffle';
|
||||||
import ParamVAEModelSelect from 'features/parameters/components/VAEModel/ParamVAEModelSelect';
|
import ParamVAEModelSelect from 'features/parameters/components/VAEModel/ParamVAEModelSelect';
|
||||||
import ParamVAEPrecision from 'features/parameters/components/VAEModel/ParamVAEPrecision';
|
import ParamVAEPrecision from 'features/parameters/components/VAEModel/ParamVAEPrecision';
|
||||||
import { selectGenerationSlice } from 'features/parameters/store/generationSlice';
|
import { selectGenerationSlice } from 'features/canvas/store/canvasSlice';
|
||||||
import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/useStandaloneAccordionToggle';
|
import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/useStandaloneAccordionToggle';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
@ -28,7 +28,7 @@ const formLabelProps2: FormLabelProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const AdvancedSettingsAccordion = memo(() => {
|
export const AdvancedSettingsAccordion = memo(() => {
|
||||||
const vaeKey = useAppSelector((state) => state.generation.vae?.key);
|
const vaeKey = useAppSelector((state) => state.canvasV2.params.vae?.key);
|
||||||
const { currentData: vaeConfig } = useGetModelConfigQuery(vaeKey ?? skipToken);
|
const { currentData: vaeConfig } = useGetModelConfigQuery(vaeKey ?? skipToken);
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const activeTabName = useAppSelector(activeTabNameSelector);
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import ParamImageToImageStrength from 'features/parameters/components/Canvas/Par
|
|||||||
import { ParamSeedNumberInput } from 'features/parameters/components/Seed/ParamSeedNumberInput';
|
import { ParamSeedNumberInput } from 'features/parameters/components/Seed/ParamSeedNumberInput';
|
||||||
import { ParamSeedRandomize } from 'features/parameters/components/Seed/ParamSeedRandomize';
|
import { ParamSeedRandomize } from 'features/parameters/components/Seed/ParamSeedRandomize';
|
||||||
import { ParamSeedShuffle } from 'features/parameters/components/Seed/ParamSeedShuffle';
|
import { ParamSeedShuffle } from 'features/parameters/components/Seed/ParamSeedShuffle';
|
||||||
import { selectGenerationSlice } from 'features/parameters/store/generationSlice';
|
import { selectGenerationSlice } from 'features/canvas/store/canvasSlice';
|
||||||
import { useExpanderToggle } from 'features/settingsAccordions/hooks/useExpanderToggle';
|
import { useExpanderToggle } from 'features/settingsAccordions/hooks/useExpanderToggle';
|
||||||
import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/useStandaloneAccordionToggle';
|
import { useStandaloneAccordionToggle } from 'features/settingsAccordions/hooks/useStandaloneAccordionToggle';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
||||||
|
@ -58,7 +58,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.sdxl.refinerModel));
|
const isRefinerModelSelected = useAppSelector((state) => !isNil(state.canvasV2.params.refinerModel));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormControlGroup isDisabled={!isRefinerModelSelected}>
|
<FormControlGroup isDisabled={!isRefinerModelSelected}>
|
||||||
|
@ -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/parameters/store/generationSlice';
|
import { shouldUseCpuNoiseChanged } from 'features/canvas/store/canvasSlice';
|
||||||
import { useClearIntermediates } from 'features/system/components/SettingsModal/useClearIntermediates';
|
import { useClearIntermediates } from 'features/system/components/SettingsModal/useClearIntermediates';
|
||||||
import { StickyScrollable } from 'features/system/components/StickyScrollable';
|
import { StickyScrollable } from 'features/system/components/StickyScrollable';
|
||||||
import {
|
import {
|
||||||
@ -88,7 +88,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.generation.shouldUseCpuNoise);
|
const shouldUseCpuNoise = useAppSelector((s) => s.canvasV2.params.shouldUseCpuNoise);
|
||||||
const shouldConfirmOnDelete = useAppSelector((s) => s.system.shouldConfirmOnDelete);
|
const shouldConfirmOnDelete = useAppSelector((s) => s.system.shouldConfirmOnDelete);
|
||||||
const enableImageDebugging = useAppSelector((s) => s.system.enableImageDebugging);
|
const enableImageDebugging = useAppSelector((s) => s.system.enableImageDebugging);
|
||||||
const shouldShowProgressInViewer = useAppSelector((s) => s.ui.shouldShowProgressInViewer);
|
const shouldShowProgressInViewer = useAppSelector((s) => s.ui.shouldShowProgressInViewer);
|
||||||
|
@ -16,7 +16,6 @@ import { RefinerSettingsAccordion } from 'features/settingsAccordions/components
|
|||||||
import { StylePresetMenu } from 'features/stylePresets/components/StylePresetMenu';
|
import { StylePresetMenu } from 'features/stylePresets/components/StylePresetMenu';
|
||||||
import { StylePresetMenuTrigger } from 'features/stylePresets/components/StylePresetMenuTrigger';
|
import { StylePresetMenuTrigger } from 'features/stylePresets/components/StylePresetMenuTrigger';
|
||||||
import { $isMenuOpen } from 'features/stylePresets/store/isMenuOpen';
|
import { $isMenuOpen } from 'features/stylePresets/store/isMenuOpen';
|
||||||
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
|
||||||
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
||||||
import type { CSSProperties } from 'react';
|
import type { CSSProperties } from 'react';
|
||||||
import { memo, useCallback, useMemo, useRef } from 'react';
|
import { memo, useCallback, useMemo, useRef } from 'react';
|
||||||
@ -42,15 +41,14 @@ const selectedStyles: ChakraProps['sx'] = {
|
|||||||
const ParametersPanelTextToImage = () => {
|
const ParametersPanelTextToImage = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const controlLayersCount = useAppSelector((s) => s.canvasV2.layers.length);
|
||||||
const controlLayersCount = useAppSelector((s) => s.layers.layers.length);
|
|
||||||
const controlLayersTitle = useMemo(() => {
|
const controlLayersTitle = useMemo(() => {
|
||||||
if (controlLayersCount === 0) {
|
if (controlLayersCount === 0) {
|
||||||
return t('controlLayers.controlLayers');
|
return t('controlLayers.controlLayers');
|
||||||
}
|
}
|
||||||
return `${t('controlLayers.controlLayers')} (${controlLayersCount})`;
|
return `${t('controlLayers.controlLayers')} (${controlLayersCount})`;
|
||||||
}, [controlLayersCount, t]);
|
}, [controlLayersCount, t]);
|
||||||
const isSDXL = useAppSelector((s) => s.generation.model?.base === 'sdxl');
|
const isSDXL = useAppSelector((s) => s.canvasV2.params.model?.base === 'sdxl');
|
||||||
const onChangeTabs = useCallback(
|
const onChangeTabs = useCallback(
|
||||||
(i: number) => {
|
(i: number) => {
|
||||||
if (i === 1) {
|
if (i === 1) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { skipToken } from '@reduxjs/toolkit/query';
|
import { skipToken } from '@reduxjs/toolkit/query';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { selectGenerationSlice } from 'features/parameters/store/generationSlice';
|
import { selectGenerationSlice } from 'features/canvas/store/canvasSlice';
|
||||||
import { useGetModelConfigQuery } from 'services/api/endpoints/models';
|
import { useGetModelConfigQuery } from 'services/api/endpoints/models';
|
||||||
|
|
||||||
const selectModelKey = createSelector(selectGenerationSlice, (generation) => generation.model?.key);
|
const selectModelKey = createSelector(selectGenerationSlice, (generation) => generation.model?.key);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user