Merge branch 'main' into logging-facelift

This commit is contained in:
blessedcoolant 2023-05-15 02:08:29 +12:00 committed by GitHub
commit c4681774a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 436 additions and 112 deletions

View File

@ -113,6 +113,7 @@ SAMPLER_CHOICES = [
"lms",
"pndm",
"heun",
"heun_k",
"euler",
"euler_k",
"euler_a",

View File

@ -9,7 +9,8 @@ SCHEDULER_MAP = dict(
deis=(DEISMultistepScheduler, dict()),
lms=(LMSDiscreteScheduler, dict()),
pndm=(PNDMScheduler, dict()),
heun=(HeunDiscreteScheduler, dict()),
heun=(HeunDiscreteScheduler, dict(use_karras_sigmas=False)),
heun_k=(HeunDiscreteScheduler, dict(use_karras_sigmas=True)),
euler=(EulerDiscreteScheduler, dict(use_karras_sigmas=False)),
euler_k=(EulerDiscreteScheduler, dict(use_karras_sigmas=True)),
euler_a=(EulerAncestralDiscreteScheduler, dict()),

View File

@ -9,6 +9,7 @@ SAMPLER_CHOICES = [
"lms",
"pndm",
"heun",
'heun_k',
"euler",
"euler_k",
"euler_a",

View File

@ -62,11 +62,13 @@
"@dagrejs/graphlib": "^2.1.12",
"@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6",
"@floating-ui/react-dom": "^2.0.0",
"@fontsource/inter": "^4.5.15",
"@reduxjs/toolkit": "^1.9.5",
"@roarr/browser-log-writer": "^1.1.5",
"chakra-ui-contextmenu": "^1.0.5",
"dateformat": "^5.0.3",
"downshift": "^7.6.0",
"formik": "^2.2.9",
"framer-motion": "^10.12.4",
"fuse.js": "^6.6.2",

View File

@ -540,7 +540,10 @@
"consoleLogLevel": "Log Level",
"shouldLogToConsole": "Console Logging",
"developer": "Developer",
"general": "General"
"general": "General",
"generation": "Generation",
"ui": "User Interface",
"availableSchedulers": "Available Schedulers"
},
"toast": {
"serverError": "Server Error",

View File

@ -30,9 +30,14 @@ const DEFAULT_CONFIG = {};
interface Props {
config?: PartialAppConfig;
headerComponent?: ReactNode;
setIsReady?: (isReady: boolean) => void;
}
const App = ({ config = DEFAULT_CONFIG, headerComponent }: Props) => {
const App = ({
config = DEFAULT_CONFIG,
headerComponent,
setIsReady,
}: Props) => {
useToastWatcher();
useGlobalHotkeys();
@ -61,6 +66,16 @@ const App = ({ config = DEFAULT_CONFIG, headerComponent }: Props) => {
setLoadingOverridden(true);
}, []);
useEffect(() => {
if (isApplicationReady && setIsReady) {
setIsReady(true);
}
return () => {
setIsReady && setIsReady(false);
};
}, [isApplicationReady, setIsReady]);
return (
<Grid w="100vw" h="100vh" position="relative" overflow="hidden">
{isLightboxEnabled && <Lightbox />}

View File

@ -24,9 +24,16 @@ interface Props extends PropsWithChildren {
token?: string;
config?: PartialAppConfig;
headerComponent?: ReactNode;
setIsReady?: (isReady: boolean) => void;
}
const InvokeAIUI = ({ apiUrl, token, config, headerComponent }: Props) => {
const InvokeAIUI = ({
apiUrl,
token,
config,
headerComponent,
setIsReady,
}: Props) => {
useEffect(() => {
// configure API client token
if (token) {
@ -55,7 +62,11 @@ const InvokeAIUI = ({ apiUrl, token, config, headerComponent }: Props) => {
<Provider store={store}>
<React.Suspense fallback={<Loading />}>
<ThemeLocaleProvider>
<App config={config} headerComponent={headerComponent} />
<App
config={config}
headerComponent={headerComponent}
setIsReady={setIsReady}
/>
</ThemeLocaleProvider>
</React.Suspense>
</Provider>

View File

@ -1,29 +1,24 @@
// TODO: use Enums?
export const DIFFUSERS_SCHEDULERS: Array<string> = [
export const SCHEDULERS: Array<string> = [
'ddim',
'ddpm',
'deis',
'lms',
'pndm',
'heun',
'euler',
'euler_k',
'euler_a',
'kdpm_2',
'kdpm_2_a',
'dpmpp_2s',
'dpmpp_2m',
'dpmpp_2m_k',
'kdpm_2',
'kdpm_2_a',
'deis',
'ddpm',
'pndm',
'heun',
'heun_k',
'unipc',
];
export const IMG2IMG_DIFFUSERS_SCHEDULERS = DIFFUSERS_SCHEDULERS.filter(
(scheduler) => {
return scheduler !== 'dpmpp_2s';
}
);
// Valid image widths
export const WIDTHS: Array<number> = Array.from(Array(64)).map(
(_x, i) => (i + 1) * 64

View File

@ -52,6 +52,7 @@ export type CommonGeneratedImageMetadata = {
| 'lms'
| 'pndm'
| 'heun'
| 'heun_k'
| 'euler'
| 'euler_k'
| 'euler_a'

View File

@ -0,0 +1,172 @@
import { CheckIcon } from '@chakra-ui/icons';
import {
Box,
Flex,
FlexProps,
FormControl,
FormControlProps,
FormLabel,
Grid,
GridItem,
List,
ListItem,
Select,
Text,
Tooltip,
TooltipProps,
} from '@chakra-ui/react';
import { autoUpdate, offset, shift, useFloating } from '@floating-ui/react-dom';
import { useSelect } from 'downshift';
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
import { memo } from 'react';
type IAICustomSelectProps = {
label?: string;
items: string[];
selectedItem: string;
setSelectedItem: (v: string | null | undefined) => void;
withCheckIcon?: boolean;
formControlProps?: FormControlProps;
buttonProps?: FlexProps;
tooltip?: string;
tooltipProps?: Omit<TooltipProps, 'children'>;
};
const IAICustomSelect = (props: IAICustomSelectProps) => {
const {
label,
items,
setSelectedItem,
selectedItem,
withCheckIcon,
formControlProps,
tooltip,
buttonProps,
tooltipProps,
} = props;
const {
isOpen,
getToggleButtonProps,
getLabelProps,
getMenuProps,
highlightedIndex,
getItemProps,
} = useSelect({
items,
selectedItem,
onSelectedItemChange: ({ selectedItem: newSelectedItem }) =>
setSelectedItem(newSelectedItem),
});
const { refs, floatingStyles } = useFloating<HTMLButtonElement>({
whileElementsMounted: autoUpdate,
middleware: [offset(4), shift({ crossAxis: true, padding: 8 })],
});
return (
<FormControl sx={{ w: 'full' }} {...formControlProps}>
{label && (
<FormLabel
{...getLabelProps()}
onClick={() => {
refs.floating.current && refs.floating.current.focus();
}}
>
{label}
</FormLabel>
)}
<Tooltip label={tooltip} {...tooltipProps}>
<Select
{...getToggleButtonProps({ ref: refs.setReference })}
{...buttonProps}
as={Flex}
sx={{
alignItems: 'center',
userSelect: 'none',
cursor: 'pointer',
}}
>
<Text sx={{ fontSize: 'sm', fontWeight: 500, color: 'base.100' }}>
{selectedItem}
</Text>
</Select>
</Tooltip>
<Box {...getMenuProps()}>
{isOpen && (
<List
as={Flex}
ref={refs.setFloating}
sx={{
...floatingStyles,
width: 'max-content',
top: 0,
left: 0,
flexDirection: 'column',
zIndex: 1,
bg: 'base.800',
borderRadius: 'base',
border: '1px',
borderColor: 'base.700',
shadow: 'dark-lg',
py: 2,
px: 0,
h: 'fit-content',
maxH: 64,
}}
>
<OverlayScrollbarsComponent>
{items.map((item, index) => (
<ListItem
sx={{
bg: highlightedIndex === index ? 'base.700' : undefined,
py: 1,
paddingInlineStart: 3,
paddingInlineEnd: 6,
cursor: 'pointer',
transitionProperty: 'common',
transitionDuration: '0.15s',
}}
key={`${item}${index}`}
{...getItemProps({ item, index })}
>
{withCheckIcon ? (
<Grid gridTemplateColumns="1.25rem auto">
<GridItem>
{selectedItem === item && <CheckIcon boxSize={2} />}
</GridItem>
<GridItem>
<Text
sx={{
fontSize: 'sm',
color: 'base.100',
fontWeight: 500,
}}
>
{item}
</Text>
</GridItem>
</Grid>
) : (
<Text
sx={{
fontSize: 'sm',
color: 'base.100',
fontWeight: 500,
}}
>
{item}
</Text>
)}
</ListItem>
))}
</OverlayScrollbarsComponent>
</List>
)}
</Box>
</FormControl>
);
};
export default memo(IAICustomSelect);

View File

@ -4,10 +4,10 @@ import { useAppSelector } from 'app/store/storeHooks';
import { systemSelector } from 'features/system/store/systemSelectors';
import { isEqual } from 'lodash-es';
import { MdPhoto } from 'react-icons/md';
import { selectedImageSelector } from '../store/gallerySelectors';
import CurrentImageButtons from './CurrentImageButtons';
import CurrentImagePreview from './CurrentImagePreview';
import { FaImage } from 'react-icons/fa';
export const currentImageDisplaySelector = createSelector(
[systemSelector, selectedImageSelector],
@ -61,7 +61,7 @@ const CurrentImageDisplay = () => {
</>
) : (
<Icon
as={MdPhoto}
as={FaImage}
sx={{
boxSize: 24,
color: 'base.500',

View File

@ -1,9 +1,6 @@
import {
DIFFUSERS_SCHEDULERS,
IMG2IMG_DIFFUSERS_SCHEDULERS,
} from 'app/constants';
import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAICustomSelect from 'common/components/IAICustomSelect';
import IAISelect from 'common/components/IAISelect';
import { setSampler } from 'features/parameters/store/generationSlice';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
@ -17,25 +14,36 @@ const ParamSampler = () => {
const activeTabName = useAppSelector(activeTabNameSelector);
const schedulers = useAppSelector((state: RootState) => state.ui.schedulers);
const img2imgSchedulers = schedulers.filter((scheduler) => {
return !['dpmpp_2s'].includes(scheduler);
});
const dispatch = useAppDispatch();
const { t } = useTranslation();
const handleChange = useCallback(
(e: ChangeEvent<HTMLSelectElement>) => dispatch(setSampler(e.target.value)),
(v: string | null | undefined) => {
if (!v) {
return;
}
dispatch(setSampler(v));
},
[dispatch]
);
return (
<IAISelect
<IAICustomSelect
label={t('parameters.sampler')}
value={sampler}
onChange={handleChange}
validValues={
activeTabName === 'img2img' || activeTabName == 'unifiedCanvas'
? IMG2IMG_DIFFUSERS_SCHEDULERS
: DIFFUSERS_SCHEDULERS
selectedItem={sampler}
setSelectedItem={handleChange}
items={
['img2img', 'unifiedCanvas'].includes(activeTabName)
? img2imgSchedulers
: schedulers
}
minWidth={36}
withCheckIcon
/>
);
};

View File

@ -0,0 +1,19 @@
import { Box, Flex } from '@chakra-ui/react';
import { memo } from 'react';
import ParamSampler from './ParamSampler';
import ModelSelect from 'features/system/components/ModelSelect';
const ParamSchedulerAndModel = () => {
return (
<Flex gap={3} w="full">
<Box w="16rem">
<ParamSampler />
</Box>
<Box w="full">
<ModelSelect />
</Box>
</Flex>
);
};
export default memo(ParamSchedulerAndModel);

View File

@ -1,4 +1,4 @@
import { Flex, Image } from '@chakra-ui/react';
import { Flex, Icon, Image } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import SelectImagePlaceholder from 'common/components/SelectImagePlaceholder';
@ -13,6 +13,7 @@ import { generationSelector } from 'features/parameters/store/generationSelector
import { initialImageSelected } from 'features/parameters/store/actions';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import ImageFallbackSpinner from 'features/gallery/components/ImageFallbackSpinner';
import { FaImage } from 'react-icons/fa';
const selector = createSelector(
[generationSelector],
@ -83,7 +84,15 @@ const InitialImagePreview = () => {
<ImageMetadataOverlay image={initialImage} />
</>
)}
{!initialImage?.url && <SelectImagePlaceholder />}
{!initialImage?.url && (
<Icon
as={FaImage}
sx={{
boxSize: 24,
color: 'base.500',
}}
/>
)}
</Flex>
);
};

View File

@ -2,8 +2,9 @@ import type { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit';
import * as InvokeAI from 'app/types/invokeai';
import promptToString from 'common/util/promptToString';
import { clamp } from 'lodash-es';
import { clamp, sample } from 'lodash-es';
import { setAllParametersReducer } from './setAllParametersReducer';
import { receivedModels } from 'services/thunks/model';
export interface GenerationState {
cfgScale: number;
@ -236,6 +237,16 @@ export const generationSlice = createSlice({
state.model = action.payload;
},
},
extraReducers: (builder) => {
builder.addCase(receivedModels.fulfilled, (state, action) => {
if (!state.model) {
const randomModel = sample(action.payload);
if (randomModel) {
state.model = randomModel.name;
}
}
});
},
});
export const {

View File

@ -17,8 +17,17 @@ const InvokeAILogoComponent = () => {
h="32px"
minW="32px"
minH="32px"
userSelect="none"
/>
<Flex gap={3} display={{ base: 'inherit', sm: 'none', md: 'inherit' }}>
<Flex
gap={3}
display={{
base: 'inherit',
sm: 'none',
md: 'inherit',
userSelect = 'none',
}}
>
<Text fontSize="xl">
invoke <strong>ai</strong>
</Text>

View File

@ -1,21 +1,20 @@
import { createSelector } from '@reduxjs/toolkit';
import { ChangeEvent, memo } from 'react';
import { memo, useCallback } from 'react';
import { isEqual } from 'lodash-es';
import { useTranslation } from 'react-i18next';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISelect from 'common/components/IAISelect';
import { selectModelsById, selectModelsIds } from '../store/modelSlice';
import { RootState } from 'app/store/store';
import { modelSelected } from 'features/parameters/store/generationSlice';
import { generationSelector } from 'features/parameters/store/generationSelectors';
import IAICustomSelect from 'common/components/IAICustomSelect';
const selector = createSelector(
[(state: RootState) => state, generationSelector],
(state, generation) => {
// const selectedModel = selectedModelSelector(state);
const selectedModel = selectModelsById(state, generation.model);
const allModelNames = selectModelsIds(state);
const allModelNames = selectModelsIds(state).map((id) => String(id));
return {
allModelNames,
selectedModel,
@ -32,19 +31,25 @@ const ModelSelect = () => {
const dispatch = useAppDispatch();
const { t } = useTranslation();
const { allModelNames, selectedModel } = useAppSelector(selector);
const handleChangeModel = (e: ChangeEvent<HTMLSelectElement>) => {
dispatch(modelSelected(e.target.value));
};
const handleChangeModel = useCallback(
(v: string | null | undefined) => {
if (!v) {
return;
}
dispatch(modelSelected(v));
},
[dispatch]
);
return (
<IAISelect
<IAICustomSelect
label={t('modelManager.model')}
style={{ fontSize: 'sm' }}
aria-label={t('accessibility.modelSelect')}
tooltip={selectedModel?.description || ''}
value={selectedModel?.name || undefined}
validValues={allModelNames}
onChange={handleChangeModel}
tooltip={selectedModel?.description}
items={allModelNames}
selectedItem={selectedModel?.name ?? ''}
setSelectedItem={handleChangeModel}
withCheckIcon={true}
tooltipProps={{ placement: 'top', hasArrow: true }}
/>
);
};

View File

@ -40,6 +40,7 @@ import { useTranslation } from 'react-i18next';
import { VALID_LOG_LEVELS } from 'app/logging/useLogger';
import { LogLevelName } from 'roarr';
import { LOCALSTORAGE_KEYS, LOCALSTORAGE_PREFIX } from 'app/store/constants';
import SettingsSchedulers from './SettingsSchedulers';
const selector = createSelector(
[systemSelector, uiSelector],
@ -171,7 +172,6 @@ const SettingsModal = ({ children }: SettingsModalProps) => {
<Flex sx={{ gap: 4, flexDirection: 'column' }}>
<Flex sx={modalSectionStyles}>
<Heading size="sm">{t('settings.general')}</Heading>
<IAISwitch
label={t('settings.confirmOnDelete')}
isChecked={shouldConfirmOnDelete}
@ -179,6 +179,15 @@ const SettingsModal = ({ children }: SettingsModalProps) => {
dispatch(setShouldConfirmOnDelete(e.target.checked))
}
/>
</Flex>
<Flex sx={modalSectionStyles}>
<Heading size="sm">{t('settings.generation')}</Heading>
<SettingsSchedulers />
</Flex>
<Flex sx={modalSectionStyles}>
<Heading size="sm">{t('settings.ui')}</Heading>
<IAISwitch
label={t('settings.displayHelpIcons')}
isChecked={shouldDisplayGuides}

View File

@ -0,0 +1,49 @@
import {
Box,
Menu,
MenuButton,
MenuItemOption,
MenuList,
MenuOptionGroup,
} from '@chakra-ui/react';
import { SCHEDULERS } from 'app/constants';
import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIButton from 'common/components/IAIButton';
import { setSchedulers } from 'features/ui/store/uiSlice';
import { isArray } from 'lodash-es';
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
import { useTranslation } from 'react-i18next';
export default function SettingsSchedulers() {
const schedulers = useAppSelector((state: RootState) => state.ui.schedulers);
const dispatch = useAppDispatch();
const { t } = useTranslation();
const schedulerSettingsHandler = (v: string | string[]) => {
if (isArray(v)) dispatch(setSchedulers(v.sort()));
};
return (
<Menu closeOnSelect={false}>
<MenuButton as={IAIButton}>
{t('settings.availableSchedulers')}
</MenuButton>
<MenuList maxHeight={64} overflowY="scroll">
<MenuOptionGroup
value={schedulers}
type="checkbox"
onChange={schedulerSettingsHandler}
>
{SCHEDULERS.map((scheduler) => (
<MenuItemOption key={scheduler} value={scheduler}>
{scheduler}
</MenuItemOption>
))}
</MenuOptionGroup>
</MenuList>
</Menu>
);
}

View File

@ -1,5 +1,5 @@
import { memo } from 'react';
import { Box, Flex } from '@chakra-ui/react';
import { Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { useAppSelector } from 'app/store/storeHooks';
@ -9,11 +9,10 @@ import ParamSteps from 'features/parameters/components/Parameters/Core/ParamStep
import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale';
import ParamWidth from 'features/parameters/components/Parameters/Core/ParamWidth';
import ParamHeight from 'features/parameters/components/Parameters/Core/ParamHeight';
import ParamSampler from 'features/parameters/components/Parameters/Core/ParamSampler';
import ModelSelect from 'features/system/components/ModelSelect';
import ImageToImageStrength from 'features/parameters/components/Parameters/ImageToImage/ImageToImageStrength';
import ImageToImageFit from 'features/parameters/components/Parameters/ImageToImage/ImageToImageFit';
import { generationSelector } from 'features/parameters/store/generationSelectors';
import ParamSchedulerAndModel from 'features/parameters/components/Parameters/Core/ParamSchedulerAndModel';
const selector = createSelector(
[uiSelector, generationSelector],
@ -48,14 +47,7 @@ const ImageToImageTabCoreParameters = () => {
<ParamHeight isDisabled={!shouldFitToWidthHeight} />
<ImageToImageStrength />
<ImageToImageFit />
<Flex gap={3} w="full">
<Box flexGrow={2}>
<ParamSampler />
</Box>
<Box flexGrow={3}>
<ModelSelect />
</Box>
</Flex>
<ParamSchedulerAndModel />
</Flex>
) : (
<Flex sx={{ gap: 2, flexDirection: 'column' }}>
@ -64,14 +56,7 @@ const ImageToImageTabCoreParameters = () => {
<ParamSteps />
<ParamCFGScale />
</Flex>
<Flex gap={3} w="full">
<Box flexGrow={2}>
<ParamSampler />
</Box>
<Box flexGrow={3}>
<ModelSelect />
</Box>
</Flex>
<ParamSchedulerAndModel />
<ParamWidth isDisabled={!shouldFitToWidthHeight} />
<ParamHeight isDisabled={!shouldFitToWidthHeight} />
<ImageToImageStrength />

View File

@ -3,14 +3,13 @@ import ParamSteps from 'features/parameters/components/Parameters/Core/ParamStep
import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale';
import ParamWidth from 'features/parameters/components/Parameters/Core/ParamWidth';
import ParamHeight from 'features/parameters/components/Parameters/Core/ParamHeight';
import ParamSampler from 'features/parameters/components/Parameters/Core/ParamSampler';
import ModelSelect from 'features/system/components/ModelSelect';
import { Box, Flex } from '@chakra-ui/react';
import { Flex } from '@chakra-ui/react';
import { useAppSelector } from 'app/store/storeHooks';
import { createSelector } from '@reduxjs/toolkit';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import { memo } from 'react';
import ParamSchedulerAndModel from 'features/parameters/components/Parameters/Core/ParamSchedulerAndModel';
const selector = createSelector(
uiSelector,
@ -42,14 +41,7 @@ const TextToImageTabCoreParameters = () => {
<ParamCFGScale />
<ParamWidth />
<ParamHeight />
<Flex gap={3} w="full">
<Box flexGrow={2}>
<ParamSampler />
</Box>
<Box flexGrow={3}>
<ModelSelect />
</Box>
</Flex>
<ParamSchedulerAndModel />
</Flex>
) : (
<Flex sx={{ gap: 2, flexDirection: 'column' }}>
@ -58,14 +50,7 @@ const TextToImageTabCoreParameters = () => {
<ParamSteps />
<ParamCFGScale />
</Flex>
<Flex gap={3} w="full">
<Box flexGrow={2}>
<ParamSampler />
</Box>
<Box flexGrow={3}>
<ModelSelect />
</Box>
</Flex>
<ParamSchedulerAndModel />
<ParamWidth />
<ParamHeight />
</Flex>

View File

@ -1,10 +1,9 @@
import { memo } from 'react';
import { Box, Flex } from '@chakra-ui/react';
import { Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { uiSelector } from 'features/ui/store/uiSelectors';
import { useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import ModelSelect from 'features/system/components/ModelSelect';
import ParamIterations from 'features/parameters/components/Parameters/Core/ParamIterations';
import ParamSteps from 'features/parameters/components/Parameters/Core/ParamSteps';
import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale';
@ -12,7 +11,7 @@ import ParamWidth from 'features/parameters/components/Parameters/Core/ParamWidt
import ParamHeight from 'features/parameters/components/Parameters/Core/ParamHeight';
import ImageToImageStrength from 'features/parameters/components/Parameters/ImageToImage/ImageToImageStrength';
import ImageToImageFit from 'features/parameters/components/Parameters/ImageToImage/ImageToImageFit';
import ParamSampler from 'features/parameters/components/Parameters/Core/ParamSampler';
import ParamSchedulerAndModel from 'features/parameters/components/Parameters/Core/ParamSchedulerAndModel';
const selector = createSelector(
uiSelector,
@ -46,14 +45,7 @@ const UnifiedCanvasCoreParameters = () => {
<ParamHeight />
<ImageToImageStrength />
<ImageToImageFit />
<Flex gap={3} w="full">
<Box flexGrow={2}>
<ParamSampler />
</Box>
<Box flexGrow={3}>
<ModelSelect />
</Box>
</Flex>
<ParamSchedulerAndModel />
</Flex>
) : (
<Flex sx={{ gap: 2, flexDirection: 'column' }}>
@ -62,14 +54,7 @@ const UnifiedCanvasCoreParameters = () => {
<ParamSteps />
<ParamCFGScale />
</Flex>
<Flex gap={3} w="full">
<Box flexGrow={2}>
<ParamSampler />
</Box>
<Box flexGrow={3}>
<ModelSelect />
</Box>
</Flex>
<ParamSchedulerAndModel />
<ParamWidth />
<ParamHeight />
<ImageToImageStrength />

View File

@ -5,6 +5,7 @@ import { InvokeTabName, tabMap } from './tabMap';
import { AddNewModelType, Coordinates, Rect, UIState } from './uiTypes';
import { initialImageSelected } from 'features/parameters/store/actions';
import { initialImageChanged } from 'features/parameters/store/generationSlice';
import { SCHEDULERS } from 'app/constants';
export const initialUIState: UIState = {
activeTab: 0,
@ -27,6 +28,7 @@ export const initialUIState: UIState = {
shouldShowProgressImages: false,
shouldShowProgressInViewer: false,
shouldShowImageParameters: false,
schedulers: SCHEDULERS,
};
export const uiSlice = createSlice({
@ -146,6 +148,10 @@ export const uiSlice = createSlice({
) => {
state.shouldShowImageParameters = action.payload;
},
setSchedulers: (state, action: PayloadAction<string[]>) => {
state.schedulers = [];
state.schedulers = action.payload;
},
},
extraReducers(builder) {
builder.addCase(initialImageChanged, (state) => {
@ -179,6 +185,7 @@ export const {
setShouldShowProgressImages,
setShouldShowProgressInViewer,
shouldShowImageParametersChanged,
setSchedulers,
} = uiSlice.actions;
export default uiSlice.reducer;

View File

@ -33,4 +33,5 @@ export interface UIState {
shouldShowProgressImages: boolean;
shouldShowProgressInViewer: boolean;
shouldShowImageParameters: boolean;
schedulers: string[];
}

View File

@ -57,7 +57,7 @@
dependencies:
regenerator-runtime "^0.13.11"
"@babel/runtime@^7.1.2":
"@babel/runtime@^7.1.2", "@babel/runtime@^7.14.8":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200"
integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==
@ -1198,6 +1198,25 @@
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.39.0.tgz#58b536bcc843f4cd1e02a7e6171da5c040f4d44b"
integrity sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==
"@floating-ui/core@^1.2.6":
version "1.2.6"
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.2.6.tgz#d21ace437cc919cdd8f1640302fa8851e65e75c0"
integrity sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg==
"@floating-ui/dom@^1.2.7":
version "1.2.7"
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.2.7.tgz#c123e4db014b07b97e996cd459245fa217049c6b"
integrity sha512-DyqylONj1ZaBnzj+uBnVfzdjjCkFCL2aA9ESHLyUOGSqb03RpbLMImP1ekIQXYs4KLk9jAjJfZAU8hXfWSahEg==
dependencies:
"@floating-ui/core" "^1.2.6"
"@floating-ui/react-dom@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.0.tgz#7514baac526c818892bbcc84e1c3115008c029f9"
integrity sha512-Ke0oU3SeuABC2C4OFu2mSAwHIP5WUiV98O9YWoHV4Q5aT6E9k06DV0Khi5uYspR8xmmBk08t8ZDcz3TR3ARkEg==
dependencies:
"@floating-ui/dom" "^1.2.7"
"@fontsource/inter@^4.5.15":
version "4.5.15"
resolved "https://registry.yarnpkg.com/@fontsource/inter/-/inter-4.5.15.tgz#eed1873d68755d3b52d6fcfcfa3493118430a512"
@ -2680,6 +2699,11 @@ compute-scroll-into-view@1.0.20:
resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz#1768b5522d1172754f5d0c9b02de3af6be506a43"
integrity sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==
compute-scroll-into-view@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-2.0.4.tgz#2b444b2b9e4724819d2531efacb7ac094155fdf6"
integrity sha512-y/ZA3BGnxoM/QHHQ2Uy49CLtnWPbt4tTPpEEZiEmmiWBFKjej7nEyH8Ryz54jH0MLXflUYA3Er2zUxPSJu5R+g==
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@ -3131,6 +3155,17 @@ dot-prop@^5.2.0:
dependencies:
is-obj "^2.0.0"
downshift@^7.6.0:
version "7.6.0"
resolved "https://registry.yarnpkg.com/downshift/-/downshift-7.6.0.tgz#de04fb2962bd6c4ea94589c797c91f34aa9816f3"
integrity sha512-VSoTVynTAsabou/hbZ6HJHUVhtBiVOjQoBsCPcQq5eAROIGP+9XKMp9asAKQ3cEcUP4oe0fFdD2pziUjhFY33Q==
dependencies:
"@babel/runtime" "^7.14.8"
compute-scroll-into-view "^2.0.4"
prop-types "^15.7.2"
react-is "^17.0.2"
tslib "^2.3.0"
duplexer3@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e"
@ -5356,7 +5391,7 @@ pretty-ms@^7.0.1:
dependencies:
parse-ms "^2.1.0"
prop-types@^15.6.2, prop-types@^15.8.1:
prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@ -5517,6 +5552,11 @@ react-is@^16.13.1, react-is@^16.7.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
react-is@^18.0.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
@ -6485,7 +6525,7 @@ tslib@^1.10.0, tslib@^1.8.1:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0:
tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==