fix(ui): fix all circular dependencies

This commit is contained in:
psychedelicious
2023-07-22 22:48:39 +10:00
parent 5468d9a9fc
commit 6452d0fc28
89 changed files with 446 additions and 588 deletions

View File

@ -20,7 +20,7 @@ const selector = createSelector(
export default function ParamAdvancedCollapse() {
const { activeLabel } = useAppSelector(selector);
const shouldShowAdvancedOptions = useAppSelector(
(state: RootState) => state.ui.shouldShowAdvancedOptions
(state: RootState) => state.generation.shouldShowAdvancedOptions
);
if (!shouldShowAdvancedOptions) {

View File

@ -2,28 +2,10 @@ import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISlider from 'common/components/IAISlider';
import { setClipSkip } from 'features/parameters/store/generationSlice';
import { clipSkipMap } from 'features/parameters/types/constants';
import { useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
export const clipSkipMap = {
'sd-1': {
maxClip: 12,
markers: [0, 1, 2, 3, 4, 8, 12],
},
'sd-2': {
maxClip: 24,
markers: [0, 1, 2, 3, 5, 10, 15, 20, 24],
},
sdxl: {
maxClip: 24,
markers: [0, 1, 2, 3, 5, 10, 15, 20, 24],
},
'sdxl-refiner': {
maxClip: 24,
markers: [0, 1, 2, 3, 5, 10, 15, 20, 24],
},
};
export default function ParamClipSkip() {
const clipSkip = useAppSelector(
(state: RootState) => state.generation.clipSkip

View File

@ -1,23 +1,20 @@
import { createSelector } from '@reduxjs/toolkit';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAISlider from 'common/components/IAISlider';
import { roundToMultiple } from 'common/util/roundDownToMultiple';
import {
canvasSelector,
isStagingSelector,
} from 'features/canvas/store/canvasSelectors';
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
import { setBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
const selector = createSelector(
[canvasSelector, isStagingSelector, uiSelector],
(canvas, isStaging, ui) => {
[stateSelector, isStagingSelector],
({ canvas, generation }, isStaging) => {
const { boundingBoxDimensions } = canvas;
const { aspectRatio } = ui;
const { aspectRatio } = generation;
return {
boundingBoxDimensions,
isStaging,

View File

@ -1,23 +1,20 @@
import { createSelector } from '@reduxjs/toolkit';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAISlider from 'common/components/IAISlider';
import { roundToMultiple } from 'common/util/roundDownToMultiple';
import {
canvasSelector,
isStagingSelector,
} from 'features/canvas/store/canvasSelectors';
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
import { setBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
const selector = createSelector(
[canvasSelector, isStagingSelector, uiSelector],
(canvas, isStaging, ui) => {
[stateSelector, isStagingSelector],
({ canvas, generation }, isStaging) => {
const { boundingBoxDimensions } = canvas;
const { aspectRatio } = ui;
const { aspectRatio } = generation;
return {
boundingBoxDimensions,
isStaging,

View File

@ -1,5 +1,6 @@
import { Divider, Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAICollapse from 'common/components/IAICollapse';
@ -9,7 +10,6 @@ import ParamControlNetFeatureToggle from 'features/controlNet/components/paramet
import {
controlNetAdded,
controlNetModelChanged,
controlNetSelector,
} from 'features/controlNet/store/controlNetSlice';
import { getValidControlNets } from 'features/controlNet/util/getValidControlNets';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
@ -21,8 +21,8 @@ import { useGetControlNetModelsQuery } from 'services/api/endpoints/models';
import { v4 as uuidv4 } from 'uuid';
const selector = createSelector(
controlNetSelector,
(controlNet) => {
[stateSelector],
({ controlNet }) => {
const { controlNets, isEnabled } = controlNet;
const validControlNets = getValidControlNets(controlNets);

View File

@ -2,7 +2,7 @@ import { ButtonGroup, Flex } from '@chakra-ui/react';
import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIButton from 'common/components/IAIButton';
import { setAspectRatio } from 'features/ui/store/uiSlice';
import { setAspectRatio } from 'features/parameters/store/generationSlice';
import { activeTabNameSelector } from '../../../../ui/store/uiSelectors';
const aspectRatios = [
@ -14,7 +14,7 @@ const aspectRatios = [
export default function ParamAspectRatio() {
const aspectRatio = useAppSelector(
(state: RootState) => state.ui.aspectRatio
(state: RootState) => state.generation.aspectRatio
);
const dispatch = useAppDispatch();

View File

@ -1,19 +1,16 @@
import { createSelector } from '@reduxjs/toolkit';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAINumberInput from 'common/components/IAINumberInput';
import IAISlider from 'common/components/IAISlider';
import { generationSelector } from 'features/parameters/store/generationSelectors';
import { setCfgScale } from 'features/parameters/store/generationSlice';
import { configSelector } from 'features/system/store/configSelectors';
import { hotkeysSelector } from 'features/ui/store/hotkeysSlice';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const selector = createSelector(
[generationSelector, configSelector, uiSelector, hotkeysSelector],
(generation, config, ui, hotkeys) => {
[stateSelector],
({ generation, config, ui, hotkeys }) => {
const { initial, min, sliderMax, inputMax } = config.sd.guidance;
const { cfgScale } = generation;
const { shouldUseSliders } = ui;

View File

@ -1,23 +1,20 @@
import { createSelector } from '@reduxjs/toolkit';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAISlider, { IAIFullSliderProps } from 'common/components/IAISlider';
import { roundToMultiple } from 'common/util/roundDownToMultiple';
import { generationSelector } from 'features/parameters/store/generationSelectors';
import { setHeight, setWidth } from 'features/parameters/store/generationSlice';
import { configSelector } from 'features/system/store/configSelectors';
import { hotkeysSelector } from 'features/ui/store/hotkeysSlice';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const selector = createSelector(
[generationSelector, hotkeysSelector, configSelector, uiSelector],
(generation, hotkeys, config, ui) => {
[stateSelector],
({ generation, hotkeys, config }) => {
const { initial, min, sliderMax, inputMax, fineStep, coarseStep } =
config.sd.height;
const { height } = generation;
const { aspectRatio } = ui;
const { aspectRatio } = generation;
const step = hotkeys.shift ? fineStep : coarseStep;

View File

@ -1,12 +1,15 @@
import { createSelector } from '@reduxjs/toolkit';
import { SCHEDULER_LABEL_MAP, SCHEDULER_NAMES } from 'app/constants';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAIMantineSearchableSelect from 'common/components/IAIMantineSearchableSelect';
import { generationSelector } from 'features/parameters/store/generationSelectors';
import { setScheduler } from 'features/parameters/store/generationSlice';
import { SchedulerParam } from 'features/parameters/types/parameterSchemas';
import {
SCHEDULER_LABEL_MAP,
SchedulerParam,
} from 'features/parameters/types/parameterSchemas';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { map } from 'lodash-es';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
@ -16,10 +19,10 @@ const selector = createSelector(
const { scheduler } = generation;
const { favoriteSchedulers: enabledSchedulers } = ui;
const data = SCHEDULER_NAMES.map((schedulerName) => ({
value: schedulerName,
label: SCHEDULER_LABEL_MAP[schedulerName as SchedulerParam],
group: enabledSchedulers.includes(schedulerName)
const data = map(SCHEDULER_LABEL_MAP, (label, name) => ({
value: name,
label: label,
group: enabledSchedulers.includes(name as SchedulerParam)
? 'Favorites'
: undefined,
})).sort((a, b) => a.label.localeCompare(b.label));

View File

@ -1,23 +1,20 @@
import { createSelector } from '@reduxjs/toolkit';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAINumberInput from 'common/components/IAINumberInput';
import IAISlider from 'common/components/IAISlider';
import { generationSelector } from 'features/parameters/store/generationSelectors';
import {
clampSymmetrySteps,
setSteps,
} from 'features/parameters/store/generationSlice';
import { configSelector } from 'features/system/store/configSelectors';
import { hotkeysSelector } from 'features/ui/store/hotkeysSlice';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const selector = createSelector(
[generationSelector, configSelector, uiSelector, hotkeysSelector],
(generation, config, ui, hotkeys) => {
[stateSelector],
({ generation, config, ui, hotkeys }) => {
const { initial, min, sliderMax, inputMax, fineStep, coarseStep } =
config.sd.steps;
const { steps } = generation;

View File

@ -1,23 +1,19 @@
import { createSelector } from '@reduxjs/toolkit';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAISlider, { IAIFullSliderProps } from 'common/components/IAISlider';
import { roundToMultiple } from 'common/util/roundDownToMultiple';
import { generationSelector } from 'features/parameters/store/generationSelectors';
import { setHeight, setWidth } from 'features/parameters/store/generationSlice';
import { configSelector } from 'features/system/store/configSelectors';
import { hotkeysSelector } from 'features/ui/store/hotkeysSlice';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const selector = createSelector(
[generationSelector, hotkeysSelector, configSelector, uiSelector],
(generation, hotkeys, config, ui) => {
[stateSelector],
({ generation, hotkeys, config, ui }) => {
const { initial, min, sliderMax, inputMax, fineStep, coarseStep } =
config.sd.width;
const { width } = generation;
const { aspectRatio } = ui;
const { width, aspectRatio } = generation;
const step = hotkeys.shift ? fineStep : coarseStep;

View File

@ -1,17 +1,15 @@
import { createSelector } from '@reduxjs/toolkit';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAISlider from 'common/components/IAISlider';
import { generationSelector } from 'features/parameters/store/generationSelectors';
import { setImg2imgStrength } from 'features/parameters/store/generationSlice';
import { configSelector } from 'features/system/store/configSelectors';
import { hotkeysSelector } from 'features/ui/store/hotkeysSlice';
import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const selector = createSelector(
[generationSelector, hotkeysSelector, configSelector],
(generation, hotkeys, config) => {
[stateSelector],
({ generation, hotkeys, config }) => {
const { initial, min, sliderMax, inputMax, fineStep, coarseStep } =
config.sd.img2imgStrength;
const { img2imgStrength } = generation;

View File

@ -1,15 +1,10 @@
import type { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit';
import { DEFAULT_SCHEDULER_NAME } from 'app/constants';
import { roundToMultiple } from 'common/util/roundDownToMultiple';
import { configChanged } from 'features/system/store/configSlice';
import {
setAspectRatio,
setShouldShowAdvancedOptions,
} from 'features/ui/store/uiSlice';
import { clamp } from 'lodash-es';
import { ImageDTO, MainModelField } from 'services/api/types';
import { clipSkipMap } from '../components/Parameters/Advanced/ParamClipSkip';
import { clipSkipMap } from '../types/constants';
import {
CfgScaleParam,
HeightParam,
@ -60,6 +55,8 @@ export interface GenerationState {
seamlessYAxis: boolean;
clipSkip: number;
shouldUseCpuNoise: boolean;
shouldShowAdvancedOptions: boolean;
aspectRatio: number | null;
}
export const initialGenerationState: GenerationState = {
@ -71,7 +68,7 @@ export const initialGenerationState: GenerationState = {
perlin: 0,
positivePrompt: '',
negativePrompt: '',
scheduler: DEFAULT_SCHEDULER_NAME,
scheduler: 'euler',
seamBlur: 16,
seamSize: 96,
seamSteps: 30,
@ -96,6 +93,8 @@ export const initialGenerationState: GenerationState = {
seamlessYAxis: false,
clipSkip: 0,
shouldUseCpuNoise: true,
shouldShowAdvancedOptions: false,
aspectRatio: null,
};
const initialState: GenerationState = initialGenerationState;
@ -248,6 +247,19 @@ export const generationSlice = createSlice({
shouldUseCpuNoiseChanged: (state, action: PayloadAction<boolean>) => {
state.shouldUseCpuNoise = action.payload;
},
setShouldShowAdvancedOptions: (state, action: PayloadAction<boolean>) => {
state.shouldShowAdvancedOptions = action.payload;
if (!action.payload) {
state.clipSkip = 0;
}
},
setAspectRatio: (state, action: PayloadAction<number | null>) => {
const newAspectRatio = action.payload;
state.aspectRatio = newAspectRatio;
if (newAspectRatio) {
state.height = roundToMultiple(state.width / newAspectRatio, 8);
}
},
},
extraReducers: (builder) => {
builder.addCase(configChanged, (state, action) => {
@ -270,12 +282,6 @@ export const generationSlice = createSlice({
const advancedOptionsStatus = action.payload;
if (!advancedOptionsStatus) state.clipSkip = 0;
});
builder.addCase(setAspectRatio, (state, action) => {
const ratio = action.payload;
if (ratio) {
state.height = roundToMultiple(state.width / ratio, 8);
}
});
},
});
@ -319,6 +325,8 @@ export const {
setSeamlessYAxis,
setClipSkip,
shouldUseCpuNoiseChanged,
setShouldShowAdvancedOptions,
setAspectRatio,
} = generationSlice.actions;
export default generationSlice.reducer;

View File

@ -4,3 +4,22 @@ export const MODEL_TYPE_MAP = {
sdxl: 'Stable Diffusion XL',
'sdxl-refiner': 'Stable Diffusion XL Refiner',
};
export const clipSkipMap = {
'sd-1': {
maxClip: 12,
markers: [0, 1, 2, 3, 4, 8, 12],
},
'sd-2': {
maxClip: 24,
markers: [0, 1, 2, 3, 5, 10, 15, 20, 24],
},
sdxl: {
maxClip: 24,
markers: [0, 1, 2, 3, 5, 10, 15, 20, 24],
},
'sdxl-refiner': {
maxClip: 24,
markers: [0, 1, 2, 3, 5, 10, 15, 20, 24],
},
};

View File

@ -1,4 +1,4 @@
import { NUMPY_RAND_MAX, SCHEDULER_NAMES_AS_CONST } from 'app/constants';
import { NUMPY_RAND_MAX } from 'app/constants';
import { z } from 'zod';
/**
@ -73,7 +73,30 @@ export const isValidCfgScale = (val: unknown): val is CfgScaleParam =>
/**
* Zod schema for scheduler parameter
*/
export const zScheduler = z.enum(SCHEDULER_NAMES_AS_CONST);
export const zScheduler = z.enum([
'euler',
'deis',
'ddim',
'ddpm',
'dpmpp_2s',
'dpmpp_2m',
'dpmpp_2m_sde',
'dpmpp_sde',
'heun',
'kdpm_2',
'lms',
'pndm',
'unipc',
'euler_k',
'dpmpp_2s_k',
'dpmpp_2m_k',
'dpmpp_2m_sde_k',
'dpmpp_sde_k',
'heun_k',
'lms_k',
'euler_a',
'kdpm_2_a',
]);
/**
* Type alias for scheduler parameter, inferred from its zod schema
*/
@ -84,6 +107,31 @@ export type SchedulerParam = z.infer<typeof zScheduler>;
export const isValidScheduler = (val: unknown): val is SchedulerParam =>
zScheduler.safeParse(val).success;
export const SCHEDULER_LABEL_MAP: Record<SchedulerParam, string> = {
euler: 'Euler',
deis: 'DEIS',
ddim: 'DDIM',
ddpm: 'DDPM',
dpmpp_sde: 'DPM++ SDE',
dpmpp_2s: 'DPM++ 2S',
dpmpp_2m: 'DPM++ 2M',
dpmpp_2m_sde: 'DPM++ 2M SDE',
heun: 'Heun',
kdpm_2: 'KDPM 2',
lms: 'LMS',
pndm: 'PNDM',
unipc: 'UniPC',
euler_k: 'Euler Karras',
dpmpp_sde_k: 'DPM++ SDE Karras',
dpmpp_2s_k: 'DPM++ 2S Karras',
dpmpp_2m_k: 'DPM++ 2M Karras',
dpmpp_2m_sde_k: 'DPM++ 2M SDE Karras',
heun_k: 'Heun Karras',
lms_k: 'LMS Karras',
euler_a: 'Euler Ancestral',
kdpm_2_a: 'KDPM 2 Ancestral',
};
/**
* Zod schema for seed parameter
*/