fix(ui): resolve all typescript issues

This commit is contained in:
psychedelicious 2023-07-22 21:38:50 +10:00
parent 75863e7181
commit 5468d9a9fc
33 changed files with 280 additions and 1116 deletions

View File

@ -27,7 +27,7 @@ const STYLES: ChakraProps['sx'] = {
const DragPreview = (props: OverlayDragImageProps) => { const DragPreview = (props: OverlayDragImageProps) => {
if (!props.dragData) { if (!props.dragData) {
return; return null;
} }
if (props.dragData.payloadType === 'IMAGE_DTO') { if (props.dragData.payloadType === 'IMAGE_DTO') {

View File

@ -1,23 +0,0 @@
import { Box, forwardRef, Icon } from '@chakra-ui/react';
import { Feature } from 'app/features';
import { memo } from 'react';
import { IconType } from 'react-icons';
import { MdHelp } from 'react-icons/md';
import GuidePopover from './GuidePopover';
type GuideIconProps = {
feature: Feature;
icon?: IconType;
};
const GuideIcon = forwardRef(
({ feature, icon = MdHelp }: GuideIconProps, ref) => (
<GuidePopover feature={feature}>
<Box ref={ref}>
<Icon marginBottom="-.15rem" as={icon} />
</Box>
</GuidePopover>
)
);
export default memo(GuideIcon);

View File

@ -1,49 +0,0 @@
import {
Box,
Popover,
PopoverArrow,
PopoverBody,
PopoverContent,
PopoverTrigger,
} from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { Feature, useFeatureHelpInfo } from 'app/features';
import { useAppSelector } from 'app/store/storeHooks';
import { systemSelector } from 'features/system/store/systemSelectors';
import { SystemState } from 'features/system/store/systemSlice';
import { memo, ReactElement } from 'react';
type GuideProps = {
children: ReactElement;
feature: Feature;
};
const guidePopoverSelector = createSelector(
systemSelector,
(system: SystemState) => system.shouldDisplayGuides
);
const GuidePopover = ({ children, feature }: GuideProps) => {
const shouldDisplayGuides = useAppSelector(guidePopoverSelector);
const { text } = useFeatureHelpInfo(feature);
if (!shouldDisplayGuides) return null;
return (
<Popover trigger="hover" isLazy>
<PopoverTrigger>
<Box>{children}</Box>
</PopoverTrigger>
<PopoverContent
maxWidth="400px"
onClick={(e) => e.preventDefault()}
cursor="initial"
>
<PopoverArrow />
<PopoverBody>{text}</PopoverBody>
</PopoverContent>
</Popover>
);
};
export default memo(GuidePopover);

View File

@ -169,7 +169,9 @@ const IAIDndImage = (props: IAIDndImageProps) => {
...imageSx, ...imageSx,
}} }}
/> />
{withMetadataOverlay && <ImageMetadataOverlay image={imageDTO} />} {withMetadataOverlay && (
<ImageMetadataOverlay imageDTO={imageDTO} />
)}
<SelectionOverlay <SelectionOverlay
isSelected={isSelected} isSelected={isSelected}
isHovered={withHoverOverlay ? isHovered : false} isHovered={withHoverOverlay ? isHovered : false}

View File

@ -1,21 +1,11 @@
import { Badge, Flex } from '@chakra-ui/react'; import { Badge, Flex } from '@chakra-ui/react';
import { isString } from 'lodash-es';
import { useMemo } from 'react';
import { ImageDTO } from 'services/api/types'; import { ImageDTO } from 'services/api/types';
type ImageMetadataOverlayProps = { type ImageMetadataOverlayProps = {
image: ImageDTO; imageDTO: ImageDTO;
}; };
const ImageMetadataOverlay = ({ image }: ImageMetadataOverlayProps) => { const ImageMetadataOverlay = ({ imageDTO }: ImageMetadataOverlayProps) => {
const model = useMemo(() => {
if (!isString(image.metadata?.model)) {
return;
}
return image.metadata?.model;
}, [image.metadata]);
return ( return (
<Flex <Flex
sx={{ sx={{
@ -30,13 +20,8 @@ const ImageMetadataOverlay = ({ image }: ImageMetadataOverlayProps) => {
}} }}
> >
<Badge variant="solid" colorScheme="base"> <Badge variant="solid" colorScheme="base">
{image.width} × {image.height} {imageDTO.width} × {imageDTO.height}
</Badge> </Badge>
{model && (
<Badge variant="solid" colorScheme="base">
{model}
</Badge>
)}
</Flex> </Flex>
); );
}; };

View File

@ -2,17 +2,16 @@ import { createSelector } from '@reduxjs/toolkit';
import { stateSelector } from 'app/store/store'; import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks'; import { useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import { validateSeedWeights } from 'common/util/seedWeightPairs'; // import { validateSeedWeights } from 'common/util/seedWeightPairs';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { modelsApi } from '../../services/api/endpoints/models';
import { forEach } from 'lodash-es'; import { forEach } from 'lodash-es';
import { modelsApi } from '../../services/api/endpoints/models';
const readinessSelector = createSelector( const readinessSelector = createSelector(
[stateSelector, activeTabNameSelector], [stateSelector, activeTabNameSelector],
(state, activeTabName) => { (state, activeTabName) => {
const { generation, system } = state; const { generation, system } = state;
const { shouldGenerateVariations, seedWeights, initialImage, seed } = const { initialImage } = generation;
generation;
const { isProcessing, isConnected } = system; const { isProcessing, isConnected } = system;
@ -44,19 +43,19 @@ const readinessSelector = createSelector(
reasonsWhyNotReady.push('System Disconnected'); reasonsWhyNotReady.push('System Disconnected');
} }
// Cannot generate variations without valid seed weights // // Cannot generate variations without valid seed weights
if ( // if (
shouldGenerateVariations && // shouldGenerateVariations &&
(!(validateSeedWeights(seedWeights) || seedWeights === '') || seed === -1) // (!(validateSeedWeights(seedWeights) || seedWeights === '') || seed === -1)
) { // ) {
isReady = false; // isReady = false;
reasonsWhyNotReady.push('Seed-Weights badly formatted.'); // reasonsWhyNotReady.push('Seed-Weights badly formatted.');
} // }
forEach(state.controlNet.controlNets, (controlNet, id) => { forEach(state.controlNet.controlNets, (controlNet, id) => {
if (!controlNet.model) { if (!controlNet.model) {
isReady = false; isReady = false;
reasonsWhyNotReady.push('ControlNet ${id} has no model selected.'); reasonsWhyNotReady.push(`ControlNet ${id} has no model selected.`);
} }
}); });

View File

@ -1,31 +0,0 @@
import * as InvokeAI from 'app/types/invokeai';
import promptToString from './promptToString';
export function getPromptAndNegative(inputPrompt: InvokeAI.Prompt) {
let prompt: string =
typeof inputPrompt === 'string' ? inputPrompt : promptToString(inputPrompt);
let negativePrompt = '';
// Matches all negative prompts, 1st capturing group is the prompt itself
const negativePromptRegExp = new RegExp(/\[([^\][]*)]/, 'gi');
// Grab the actual prompt matches (capturing group 1 is 1st index of match)
const negativePromptMatches = [...prompt.matchAll(negativePromptRegExp)].map(
(match) => match[1]
);
if (negativePromptMatches.length) {
// Build the negative prompt itself
negativePrompt = negativePromptMatches.join(' ');
// Replace each match, including its surrounding brackets
// Remove each pair of empty brackets
// Trim whitespace
negativePromptMatches.forEach((match) => {
prompt = prompt.replace(`[${match}]`, '').replaceAll('[]', '').trim();
});
}
return [prompt, negativePrompt];
}

View File

@ -1,20 +0,0 @@
import * as InvokeAI from 'app/types/invokeai';
const promptToString = (prompt: InvokeAI.Prompt): string => {
if (typeof prompt === 'string') {
return prompt;
}
if (prompt.length === 1) {
return prompt[0].prompt;
}
return prompt
.map(
(promptItem: InvokeAI.PromptItem): string =>
`${promptItem.prompt}:${promptItem.weight}`
)
.join(' ');
};
export default promptToString;

View File

@ -1,68 +1,71 @@
import * as InvokeAI from 'app/types/invokeai'; // TODO: Restore variations
// Support code from v2.3 in here.
export const stringToSeedWeights = ( // export const stringToSeedWeights = (
string: string // string: string
): InvokeAI.SeedWeights | boolean => { // ): InvokeAI.SeedWeights | boolean => {
const stringPairs = string.split(','); // const stringPairs = string.split(',');
const arrPairs = stringPairs.map((p) => p.split(':')); // const arrPairs = stringPairs.map((p) => p.split(':'));
const pairs = arrPairs.map((p: Array<string>): InvokeAI.SeedWeightPair => { // const pairs = arrPairs.map((p: Array<string>): InvokeAI.SeedWeightPair => {
return { seed: Number(p[0]), weight: Number(p[1]) }; // return { seed: Number(p[0]), weight: Number(p[1]) };
}); // });
if (!validateSeedWeights(pairs)) { // if (!validateSeedWeights(pairs)) {
return false; // return false;
} // }
return pairs; // return pairs;
}; // };
export const validateSeedWeights = ( // export const validateSeedWeights = (
seedWeights: InvokeAI.SeedWeights | string // seedWeights: InvokeAI.SeedWeights | string
): boolean => { // ): boolean => {
return typeof seedWeights === 'string' // return typeof seedWeights === 'string'
? Boolean(stringToSeedWeights(seedWeights)) // ? Boolean(stringToSeedWeights(seedWeights))
: Boolean( // : Boolean(
seedWeights.length && // seedWeights.length &&
!seedWeights.some((pair: InvokeAI.SeedWeightPair) => { // !seedWeights.some((pair: InvokeAI.SeedWeightPair) => {
const { seed, weight } = pair; // const { seed, weight } = pair;
const isSeedValid = !isNaN(parseInt(seed.toString(), 10)); // const isSeedValid = !isNaN(parseInt(seed.toString(), 10));
const isWeightValid = // const isWeightValid =
!isNaN(parseInt(weight.toString(), 10)) && // !isNaN(parseInt(weight.toString(), 10)) &&
weight >= 0 && // weight >= 0 &&
weight <= 1; // weight <= 1;
return !(isSeedValid && isWeightValid); // return !(isSeedValid && isWeightValid);
}) // })
); // );
}; // };
export const seedWeightsToString = ( // export const seedWeightsToString = (
seedWeights: InvokeAI.SeedWeights // seedWeights: InvokeAI.SeedWeights
): string => { // ): string => {
return seedWeights.reduce((acc, pair, i, arr) => { // return seedWeights.reduce((acc, pair, i, arr) => {
const { seed, weight } = pair; // const { seed, weight } = pair;
acc += `${seed}:${weight}`; // acc += `${seed}:${weight}`;
if (i !== arr.length - 1) { // if (i !== arr.length - 1) {
acc += ','; // acc += ',';
} // }
return acc; // return acc;
}, ''); // }, '');
}; // };
export const seedWeightsToArray = ( // export const seedWeightsToArray = (
seedWeights: InvokeAI.SeedWeights // seedWeights: InvokeAI.SeedWeights
): Array<Array<number>> => { // ): Array<Array<number>> => {
return seedWeights.map((pair: InvokeAI.SeedWeightPair) => [ // return seedWeights.map((pair: InvokeAI.SeedWeightPair) => [
pair.seed, // pair.seed,
pair.weight, // pair.weight,
]); // ]);
}; // };
export const stringToSeedWeightsArray = ( // export const stringToSeedWeightsArray = (
string: string // string: string
): Array<Array<number>> => { // ): Array<Array<number>> => {
const stringPairs = string.split(','); // const stringPairs = string.split(',');
const arrPairs = stringPairs.map((p) => p.split(':')); // const arrPairs = stringPairs.map((p) => p.split(':'));
return arrPairs.map( // return arrPairs.map(
(p: Array<string>): Array<number> => [parseInt(p[0], 10), parseFloat(p[1])] // (p: Array<string>): Array<number> => [parseInt(p[0], 10), parseFloat(p[1])]
); // );
}; // };
export default {};

View File

@ -1,7 +1,5 @@
import * as InvokeAI from 'app/types/invokeai';
import { IRect, Vector2d } from 'konva/lib/types'; import { IRect, Vector2d } from 'konva/lib/types';
import { RgbaColor } from 'react-colorful'; import { RgbaColor } from 'react-colorful';
import { ImageDTO } from 'services/api/types';
export const LAYER_NAMES_DICT = [ export const LAYER_NAMES_DICT = [
{ label: 'Base', value: 'base' }, { label: 'Base', value: 'base' },
@ -133,7 +131,6 @@ export interface CanvasState {
cursorPosition: Vector2d | null; cursorPosition: Vector2d | null;
doesCanvasNeedScaling: boolean; doesCanvasNeedScaling: boolean;
futureLayerStates: CanvasLayerState[]; futureLayerStates: CanvasLayerState[];
intermediateImage?: InvokeAI.Image;
isCanvasInitialized: boolean; isCanvasInitialized: boolean;
isDrawing: boolean; isDrawing: boolean;
isMaskEnabled: boolean; isMaskEnabled: boolean;

View File

@ -1,73 +0,0 @@
import { Flex, Image, Spinner } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import { systemSelector } from 'features/system/store/systemSelectors';
import { memo } from 'react';
import { gallerySelector } from '../store/gallerySelectors';
const selector = createSelector(
[systemSelector, gallerySelector],
(system, gallery) => {
const { shouldUseSingleGalleryColumn, galleryImageObjectFit } = gallery;
const { progressImage, shouldAntialiasProgressImage } = system;
return {
progressImage,
shouldUseSingleGalleryColumn,
galleryImageObjectFit,
shouldAntialiasProgressImage,
};
},
defaultSelectorOptions
);
const GalleryProgressImage = () => {
const {
progressImage,
shouldUseSingleGalleryColumn,
galleryImageObjectFit,
shouldAntialiasProgressImage,
} = useAppSelector(selector);
if (!progressImage) {
return null;
}
return (
<Flex
sx={{
w: 'full',
h: 'full',
alignItems: 'center',
justifyContent: 'center',
aspectRatio: '1/1',
position: 'relative',
}}
>
<Image
draggable={false}
src={progressImage.dataURL}
width={progressImage.width}
height={progressImage.height}
sx={{
objectFit: shouldUseSingleGalleryColumn
? 'contain'
: galleryImageObjectFit,
width: '100%',
height: '100%',
maxWidth: '100%',
maxHeight: '100%',
borderRadius: 'base',
imageRendering: shouldAntialiasProgressImage ? 'auto' : 'pixelated',
}}
/>
<Spinner
sx={{ position: 'absolute', top: 1, right: 1, opacity: 0.7 }}
speed="1.2s"
/>
</Flex>
);
};
export default memo(GalleryProgressImage);

View File

@ -159,6 +159,8 @@ const GalleryImageGrid = () => {
</Box> </Box>
); );
} }
return null;
}; };
export default memo(GalleryImageGrid); export default memo(GalleryImageGrid);

View File

@ -1,23 +0,0 @@
import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'app/store/store';
import { selectBoardsAll } from './boardSlice';
export const boardSelector = (state: RootState) => state.boards.entities;
export const searchBoardsSelector = createSelector(
(state: RootState) => state,
(state) => {
const {
boards: { searchText },
} = state;
if (!searchText) {
// If no search text provided, return all entities
return selectBoardsAll(state);
}
return selectBoardsAll(state).filter((i) =>
i.board_name.toLowerCase().includes(searchText.toLowerCase())
);
}
);

View File

@ -5,13 +5,6 @@ import { initialGalleryState } from './gallerySlice';
*/ */
export const galleryPersistDenylist: (keyof typeof initialGalleryState)[] = [ export const galleryPersistDenylist: (keyof typeof initialGalleryState)[] = [
'selection', 'selection',
'entities',
'ids',
'isLoading',
'limit',
'offset',
'selectedBoardId', 'selectedBoardId',
'galleryView', 'galleryView',
'total',
'isInitialized',
]; ];

View File

@ -45,7 +45,7 @@ export const gallerySlice = createSlice({
initialState: initialGalleryState, initialState: initialGalleryState,
reducers: { reducers: {
imageRangeEndSelected: (state, action: PayloadAction<string>) => { imageRangeEndSelected: (state, action: PayloadAction<string>) => {
// MULTI SELECT LOGIC // TODO: multiselect
// const rangeEndImageName = action.payload; // const rangeEndImageName = action.payload;
// const lastSelectedImage = state.selection[state.selection.length - 1]; // const lastSelectedImage = state.selection[state.selection.length - 1];
// const filteredImages = selectFilteredImagesLocal(state); // const filteredImages = selectFilteredImagesLocal(state);
@ -66,7 +66,7 @@ export const gallerySlice = createSlice({
// } // }
}, },
imageSelectionToggled: (state, action: PayloadAction<string>) => { imageSelectionToggled: (state, action: PayloadAction<string>) => {
// MULTI SELECT LOGIC // TODO: multiselect
// if ( // if (
// state.selection.includes(action.payload) && // state.selection.includes(action.payload) &&
// state.selection.length > 1 // state.selection.length > 1
@ -157,7 +157,6 @@ export const gallerySlice = createSlice({
}); });
export const { export const {
imagesRemoved,
imageRangeEndSelected, imageRangeEndSelected,
imageSelectionToggled, imageSelectionToggled,
imageSelected, imageSelected,

View File

@ -18,7 +18,13 @@ const selector = createSelector(
const ParamLoraList = () => { const ParamLoraList = () => {
const { loras } = useAppSelector(selector); const { loras } = useAppSelector(selector);
return map(loras, (lora) => <ParamLora key={lora.model_name} lora={lora} />); return (
<>
{map(loras, (lora) => (
<ParamLora key={lora.model_name} lora={lora} />
))}
</>
);
}; };
export default ParamLoraList; export default ParamLoraList;

View File

@ -59,13 +59,25 @@ const ViewportControls = () => {
return ( return (
<ButtonGroup isAttached orientation="vertical"> <ButtonGroup isAttached orientation="vertical">
<Tooltip label={t('nodes.zoomInNodes')}> <Tooltip label={t('nodes.zoomInNodes')}>
<IAIIconButton onClick={handleClickedZoomIn} icon={<FaPlus />} /> <IAIIconButton
aria-label="Zoom in "
onClick={handleClickedZoomIn}
icon={<FaPlus />}
/>
</Tooltip> </Tooltip>
<Tooltip label={t('nodes.zoomOutNodes')}> <Tooltip label={t('nodes.zoomOutNodes')}>
<IAIIconButton onClick={handleClickedZoomOut} icon={<FaMinus />} /> <IAIIconButton
aria-label="Zoom out"
onClick={handleClickedZoomOut}
icon={<FaMinus />}
/>
</Tooltip> </Tooltip>
<Tooltip label={t('nodes.fitViewportNodes')}> <Tooltip label={t('nodes.fitViewportNodes')}>
<IAIIconButton onClick={handleClickedFitView} icon={<FaExpand />} /> <IAIIconButton
aria-label="Fit viewport"
onClick={handleClickedFitView}
icon={<FaExpand />}
/>
</Tooltip> </Tooltip>
<Tooltip <Tooltip
label={ label={
@ -75,6 +87,7 @@ const ViewportControls = () => {
} }
> >
<IAIIconButton <IAIIconButton
aria-label="Toggle nodes graph overlay"
isChecked={shouldShowGraphOverlay} isChecked={shouldShowGraphOverlay}
onClick={handleClickedToggleGraphOverlay} onClick={handleClickedToggleGraphOverlay}
icon={<FaCode />} icon={<FaCode />}
@ -88,6 +101,7 @@ const ViewportControls = () => {
} }
> >
<IAIIconButton <IAIIconButton
aria-label="Toggle field type legend"
isChecked={shouldShowFieldTypeLegend} isChecked={shouldShowFieldTypeLegend}
onClick={handleClickedToggleFieldTypeLegend} onClick={handleClickedToggleFieldTypeLegend}
icon={<FaInfo />} icon={<FaInfo />}
@ -101,6 +115,7 @@ const ViewportControls = () => {
} }
> >
<IAIIconButton <IAIIconButton
aria-label="Toggle minimap"
isChecked={shouldShowMinimapPanel} isChecked={shouldShowMinimapPanel}
onClick={handleClickedToggleMiniMapPanel} onClick={handleClickedToggleMiniMapPanel}
icon={<FaMapMarkerAlt />} icon={<FaMapMarkerAlt />}

View File

@ -22,13 +22,16 @@ export default function ParamAdvancedCollapse() {
const shouldShowAdvancedOptions = useAppSelector( const shouldShowAdvancedOptions = useAppSelector(
(state: RootState) => state.ui.shouldShowAdvancedOptions (state: RootState) => state.ui.shouldShowAdvancedOptions
); );
if (!shouldShowAdvancedOptions) {
return null;
}
return ( return (
shouldShowAdvancedOptions && (
<IAICollapse label={'Advanced'} activeLabel={activeLabel}> <IAICollapse label={'Advanced'} activeLabel={activeLabel}>
<Flex sx={{ flexDir: 'column', gap: 2 }}> <Flex sx={{ flexDir: 'column', gap: 2 }}>
<ParamClipSkip /> <ParamClipSkip />
</Flex> </Flex>
</IAICollapse> </IAICollapse>
)
); );
} }

View File

@ -1,33 +0,0 @@
import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISwitch from 'common/components/IAISwitch';
import { setSeamless } from 'features/parameters/store/generationSlice';
import { ChangeEvent } from 'react';
import { useTranslation } from 'react-i18next';
/**
* Seamless tiling toggle
*/
const ParamSeamlessToggle = () => {
const dispatch = useAppDispatch();
const seamless = useAppSelector(
(state: RootState) => state.generation.seamless
);
const handleChangeSeamless = (e: ChangeEvent<HTMLInputElement>) =>
dispatch(setSeamless(e.target.checked));
const { t } = useTranslation();
return (
<IAISwitch
label={t('parameters.seamlessTiling')}
fontSize="md"
isChecked={seamless}
onChange={handleChangeSeamless}
/>
);
};
export default ParamSeamlessToggle;

View File

@ -1,48 +0,0 @@
import { Flex } from '@chakra-ui/react';
import ParamSeed from './ParamSeed';
import { memo, useCallback } from 'react';
import ParamSeedShuffle from './ParamSeedShuffle';
import { useTranslation } from 'react-i18next';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { createSelector } from '@reduxjs/toolkit';
import { generationSelector } from 'features/parameters/store/generationSelectors';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import { setShouldRandomizeSeed } from 'features/parameters/store/generationSlice';
import IAICollapse from 'common/components/IAICollapse';
const selector = createSelector(
generationSelector,
(generation) => {
const { shouldRandomizeSeed } = generation;
return { shouldRandomizeSeed };
},
defaultSelectorOptions
);
const ParamSeedSettings = () => {
const { t } = useTranslation();
const dispatch = useAppDispatch();
const { shouldRandomizeSeed } = useAppSelector(selector);
const handleToggle = useCallback(
() => dispatch(setShouldRandomizeSeed(!shouldRandomizeSeed)),
[dispatch, shouldRandomizeSeed]
);
return (
<IAICollapse
label={t('parameters.seed')}
isOpen={!shouldRandomizeSeed}
onToggle={handleToggle}
withSwitch
>
<Flex sx={{ gap: 4 }}>
<ParamSeed />
<ParamSeedShuffle />
</Flex>
</IAICollapse>
);
};
export default memo(ParamSeedSettings);

View File

@ -1,47 +1,51 @@
import { Flex } from '@chakra-ui/react'; // TODO: variations
import { createSelector } from '@reduxjs/toolkit';
import { stateSelector } from 'app/store/store';
import { useAppSelector } from 'app/store/storeHooks';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import IAICollapse from 'common/components/IAICollapse';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import ParamVariationAmount from './ParamVariationAmount';
import { ParamVariationToggle } from './ParamVariationToggle';
import ParamVariationWeights from './ParamVariationWeights';
const selector = createSelector( // import { Flex } from '@chakra-ui/react';
stateSelector, // import { createSelector } from '@reduxjs/toolkit';
(state) => { // import { stateSelector } from 'app/store/store';
const activeLabel = state.generation.shouldGenerateVariations // import { useAppSelector } from 'app/store/storeHooks';
? 'Enabled' // import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
: undefined; // import IAICollapse from 'common/components/IAICollapse';
// import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
// import { memo } from 'react';
// import { useTranslation } from 'react-i18next';
// import ParamVariationAmount from './ParamVariationAmount';
// import { ParamVariationToggle } from './ParamVariationToggle';
// import ParamVariationWeights from './ParamVariationWeights';
return { activeLabel }; // const selector = createSelector(
}, // stateSelector,
defaultSelectorOptions // (state) => {
); // const activeLabel = state.generation.shouldGenerateVariations
// ? 'Enabled'
// : undefined;
const ParamVariationCollapse = () => { // return { activeLabel };
const { t } = useTranslation(); // },
const { activeLabel } = useAppSelector(selector); // defaultSelectorOptions
// );
const isVariationEnabled = useFeatureStatus('variation').isFeatureEnabled; // const ParamVariationCollapse = () => {
// const { t } = useTranslation();
// const { activeLabel } = useAppSelector(selector);
if (!isVariationEnabled) { // const isVariationEnabled = useFeatureStatus('variation').isFeatureEnabled;
return null;
}
return ( // if (!isVariationEnabled) {
<IAICollapse label={t('parameters.variations')} activeLabel={activeLabel}> // return null;
<Flex sx={{ gap: 2, flexDirection: 'column' }}> // }
<ParamVariationToggle />
<ParamVariationAmount />
<ParamVariationWeights />
</Flex>
</IAICollapse>
);
};
export default memo(ParamVariationCollapse); // return (
// <IAICollapse label={t('parameters.variations')} activeLabel={activeLabel}>
// <Flex sx={{ gap: 2, flexDirection: 'column' }}>
// <ParamVariationToggle />
// <ParamVariationAmount />
// <ParamVariationWeights />
// </Flex>
// </IAICollapse>
// );
// };
// export default memo(ParamVariationCollapse);
export default {};

View File

@ -1,37 +1,41 @@
import { RootState } from 'app/store/store'; // TODO: variations
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIInput from 'common/components/IAIInput';
import { validateSeedWeights } from 'common/util/seedWeightPairs';
import { setSeedWeights } from 'features/parameters/store/generationSlice';
import { ChangeEvent } from 'react';
import { useTranslation } from 'react-i18next';
export default function ParamVariationWeights() { // import { RootState } from 'app/store/store';
const seedWeights = useAppSelector( // import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
(state: RootState) => state.generation.seedWeights // import IAIInput from 'common/components/IAIInput';
); // import { validateSeedWeights } from 'common/util/seedWeightPairs';
// import { setSeedWeights } from 'features/parameters/store/generationSlice';
// import { ChangeEvent } from 'react';
// import { useTranslation } from 'react-i18next';
const shouldGenerateVariations = useAppSelector( // export default function ParamVariationWeights() {
(state: RootState) => state.generation.shouldGenerateVariations // const seedWeights = useAppSelector(
); // (state: RootState) => state.generation.seedWeights
// );
const { t } = useTranslation(); // const shouldGenerateVariations = useAppSelector(
// (state: RootState) => state.generation.shouldGenerateVariations
// );
const dispatch = useAppDispatch(); // const { t } = useTranslation();
const handleChangeSeedWeights = (e: ChangeEvent<HTMLInputElement>) => // const dispatch = useAppDispatch();
dispatch(setSeedWeights(e.target.value));
return ( // const handleChangeSeedWeights = (e: ChangeEvent<HTMLInputElement>) =>
<IAIInput // dispatch(setSeedWeights(e.target.value));
label={t('parameters.seedWeights')}
value={seedWeights} // return (
isInvalid={ // <IAIInput
shouldGenerateVariations && // label={t('parameters.seedWeights')}
!(validateSeedWeights(seedWeights) || seedWeights === '') // value={seedWeights}
} // isInvalid={
isDisabled={!shouldGenerateVariations} // shouldGenerateVariations &&
onChange={handleChangeSeedWeights} // !(validateSeedWeights(seedWeights) || seedWeights === '')
/> // }
); // isDisabled={!shouldGenerateVariations}
} // onChange={handleChangeSeedWeights}
// />
// );
// }
export default {};

View File

@ -1,47 +1,11 @@
import { createSelector } from '@reduxjs/toolkit'; import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'app/store/store'; import { RootState } from 'app/store/store';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import { pickBy, reduce } from 'lodash-es';
export const systemSelector = (state: RootState) => state.system; export const systemSelector = (state: RootState) => state.system;
export const toastQueueSelector = (state: RootState) => state.system.toastQueue; export const toastQueueSelector = (state: RootState) => state.system.toastQueue;
export const activeModelSelector = createSelector(
systemSelector,
(system) => {
const { model_list } = system;
const activeModel = reduce(
model_list,
(acc, model, key) => {
if (model.status === 'active') {
acc = key;
}
return acc;
},
''
);
return { ...model_list[activeModel], name: activeModel };
},
defaultSelectorOptions
);
export const diffusersModelsSelector = createSelector(
systemSelector,
(system) => {
const { model_list } = system;
const diffusersModels = pickBy(model_list, (model, key) => {
if (model.format === 'diffusers') {
return { name: key, ...model };
}
});
return diffusersModels;
},
defaultSelectorOptions
);
export const languageSelector = createSelector( export const languageSelector = createSelector(
systemSelector, systemSelector,
(system) => system.language, (system) => system.language,

View File

@ -74,7 +74,8 @@ export interface SystemState {
*/ */
consoleLogLevel: InvokeLogLevel; consoleLogLevel: InvokeLogLevel;
shouldLogToConsole: boolean; shouldLogToConsole: boolean;
statusTranslationKey: any; // TODO: probably better to not store keys here, should just be a string that maps to the translation key
statusTranslationKey: string;
/** /**
* When a session is canceled, its ID is stored here until a new session is created. * When a session is canceled, its ID is stored here until a new session is created.
*/ */
@ -125,7 +126,7 @@ export const systemSlice = createSlice({
setIsProcessing: (state, action: PayloadAction<boolean>) => { setIsProcessing: (state, action: PayloadAction<boolean>) => {
state.isProcessing = action.payload; state.isProcessing = action.payload;
}, },
setCurrentStatus: (state, action: any) => { setCurrentStatus: (state, action: PayloadAction<string>) => {
state.statusTranslationKey = action.payload; state.statusTranslationKey = action.payload;
}, },
setShouldConfirmOnDelete: (state, action: PayloadAction<boolean>) => { setShouldConfirmOnDelete: (state, action: PayloadAction<boolean>) => {
@ -362,7 +363,7 @@ export const systemSlice = createSlice({
* Session Invoked - REJECTED * Session Invoked - REJECTED
* Session Created - REJECTED * Session Created - REJECTED
*/ */
builder.addMatcher(isAnySessionRejected, (state, action) => { builder.addMatcher(isAnySessionRejected, (state) => {
state.isProcessing = false; state.isProcessing = false;
state.isCancelable = false; state.isCancelable = false;
state.isCancelScheduled = false; state.isCancelScheduled = false;

View File

@ -1,43 +0,0 @@
import { Box, Flex } from '@chakra-ui/react';
import { useAppDispatch } from 'app/store/storeHooks';
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
import InitialImageDisplay from 'features/parameters/components/Parameters/ImageToImage/InitialImageDisplay';
import { memo, useCallback, useRef } from 'react';
import {
ImperativePanelGroupHandle,
Panel,
PanelGroup,
} from 'react-resizable-panels';
import ResizeHandle from '../ResizeHandle';
import TextToImageTabMain from '../TextToImage/TextToImageTabMain';
import BatchManager from 'features/batch/components/BatchManager';
const ImageToImageTab = () => {
const dispatch = useAppDispatch();
const panelGroupRef = useRef<ImperativePanelGroupHandle>(null);
const handleDoubleClickHandle = useCallback(() => {
if (!panelGroupRef.current) {
return;
}
panelGroupRef.current.setLayout([50, 50]);
}, []);
return (
<Flex
layerStyle={'first'}
sx={{
gap: 4,
p: 4,
w: 'full',
h: 'full',
borderRadius: 'base',
}}
>
<BatchManager />
</Flex>
);
};
export default memo(ImageToImageTab);

View File

@ -7,9 +7,8 @@ import ParamPositiveConditioning from 'features/parameters/components/Parameters
import ParamNoiseCollapse from 'features/parameters/components/Parameters/Noise/ParamNoiseCollapse'; import ParamNoiseCollapse from 'features/parameters/components/Parameters/Noise/ParamNoiseCollapse';
import ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse'; import ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse';
import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse'; import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse';
import ParamVariationCollapse from 'features/parameters/components/Parameters/Variations/ParamVariationCollapse'; // import ParamVariationCollapse from 'features/parameters/components/Parameters/Variations/ParamVariationCollapse';
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons'; import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
import { memo } from 'react';
import ImageToImageTabCoreParameters from './ImageToImageTabCoreParameters'; import ImageToImageTabCoreParameters from './ImageToImageTabCoreParameters';
const ImageToImageTabParameters = () => { const ImageToImageTabParameters = () => {
@ -22,7 +21,7 @@ const ImageToImageTabParameters = () => {
<ParamControlNetCollapse /> <ParamControlNetCollapse />
<ParamLoraCollapse /> <ParamLoraCollapse />
<ParamDynamicPromptsCollapse /> <ParamDynamicPromptsCollapse />
<ParamVariationCollapse /> {/* <ParamVariationCollapse /> */}
<ParamNoiseCollapse /> <ParamNoiseCollapse />
<ParamSymmetryCollapse /> <ParamSymmetryCollapse />
<ParamSeamlessCollapse /> <ParamSeamlessCollapse />
@ -31,4 +30,4 @@ const ImageToImageTabParameters = () => {
); );
}; };
export default memo(ImageToImageTabParameters); export default ImageToImageTabParameters;

View File

@ -168,7 +168,9 @@ export default function FoundModelsList() {
}; };
const renderFoundModels = () => { const renderFoundModels = () => {
if (!searchFolder) return; if (!searchFolder) {
return null;
}
if (!foundModels || foundModels.length === 0) { if (!foundModels || foundModels.length === 0) {
return ( return (
@ -242,7 +244,7 @@ const foundModelsFilter = (
const filteredModels: SearchFolderResponse = []; const filteredModels: SearchFolderResponse = [];
forEach(data, (model) => { forEach(data, (model) => {
if (!model) { if (!model) {
return; return null;
} }
if (model.includes(nameFilter)) { if (model.includes(nameFilter)) {

View File

@ -32,8 +32,11 @@ export default function ScanAdvancedAddModels() {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
if (!advancedAddScanModel) {
return null;
}
return ( return (
advancedAddScanModel && (
<Box <Box
as={motion.div} as={motion.div}
initial={{ x: -100, opacity: 0 }} initial={{ x: -100, opacity: 0 }}
@ -92,6 +95,5 @@ export default function ScanAdvancedAddModels() {
/> />
)} )}
</Box> </Box>
)
); );
} }

View File

@ -1,430 +0,0 @@
import IAIButton from 'common/components/IAIButton';
import IAISimpleCheckbox from 'common/components/IAISimpleCheckbox';
import IAIIconButton from 'common/components/IAIIconButton';
import React from 'react';
import {
Badge,
Flex,
FormControl,
HStack,
Radio,
RadioGroup,
Spacer,
Text,
} from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { systemSelector } from 'features/system/store/systemSelectors';
import { useTranslation } from 'react-i18next';
import { FaSearch, FaTrash } from 'react-icons/fa';
// import { addNewModel, searchForModels } from 'app/socketio/actions';
import {
setFoundModels,
setSearchFolder,
} from 'features/system/store/systemSlice';
import { setShouldShowExistingModelsInSearch } from 'features/ui/store/uiSlice';
import type { FoundModel } from 'app/types/invokeai';
import type { RootState } from 'app/store/store';
import IAIInput from 'common/components/IAIInput';
import { Field, Formik } from 'formik';
import { forEach, remove } from 'lodash-es';
import type { ChangeEvent, ReactNode } from 'react';
import IAIForm from 'common/components/IAIForm';
const existingModelsSelector = createSelector([systemSelector], (system) => {
const { model_list } = system;
const existingModels: string[] = [];
forEach(model_list, (value) => {
existingModels.push(value.weights);
});
return existingModels;
});
interface SearchModelEntry {
model: FoundModel;
modelsToAdd: string[];
setModelsToAdd: React.Dispatch<React.SetStateAction<string[]>>;
}
function SearchModelEntry({
model,
modelsToAdd,
setModelsToAdd,
}: SearchModelEntry) {
const { t } = useTranslation();
const existingModels = useAppSelector(existingModelsSelector);
const foundModelsChangeHandler = (e: ChangeEvent<HTMLInputElement>) => {
if (!modelsToAdd.includes(e.target.value)) {
setModelsToAdd([...modelsToAdd, e.target.value]);
} else {
setModelsToAdd(remove(modelsToAdd, (v) => v !== e.target.value));
}
};
return (
<Flex
flexDirection="column"
gap={2}
backgroundColor={
modelsToAdd.includes(model.name) ? 'accent.650' : 'base.800'
}
paddingX={4}
paddingY={2}
borderRadius={4}
>
<Flex gap={4} alignItems="center" justifyContent="space-between">
<IAISimpleCheckbox
value={model.name}
label={<Text fontWeight={500}>{model.name}</Text>}
isChecked={modelsToAdd.includes(model.name)}
isDisabled={existingModels.includes(model.location)}
onChange={foundModelsChangeHandler}
></IAISimpleCheckbox>
{existingModels.includes(model.location) && (
<Badge colorScheme="accent">{t('modelManager.modelExists')}</Badge>
)}
</Flex>
<Text fontStyle="italic" variant="subtext">
{model.location}
</Text>
</Flex>
);
}
export default function SearchModels() {
const dispatch = useAppDispatch();
const { t } = useTranslation();
const searchFolder = useAppSelector(
(state: RootState) => state.system.searchFolder
);
const foundModels = useAppSelector(
(state: RootState) => state.system.foundModels
);
const existingModels = useAppSelector(existingModelsSelector);
const shouldShowExistingModelsInSearch = useAppSelector(
(state: RootState) => state.ui.shouldShowExistingModelsInSearch
);
const isProcessing = useAppSelector(
(state: RootState) => state.system.isProcessing
);
const [modelsToAdd, setModelsToAdd] = React.useState<string[]>([]);
const [modelType, setModelType] = React.useState<string>('v1');
const [pathToConfig, setPathToConfig] = React.useState<string>('');
const resetSearchModelHandler = () => {
dispatch(setSearchFolder(null));
dispatch(setFoundModels(null));
setModelsToAdd([]);
};
const findModelsHandler = (values: { checkpointFolder: string }) => {
dispatch(searchForModels(values.checkpointFolder));
};
const addAllToSelected = () => {
setModelsToAdd([]);
if (foundModels) {
foundModels.forEach((model) => {
if (!existingModels.includes(model.location)) {
setModelsToAdd((currentModels) => {
return [...currentModels, model.name];
});
}
});
}
};
const removeAllFromSelected = () => {
setModelsToAdd([]);
};
const addSelectedModels = () => {
const modelsToBeAdded = foundModels?.filter((foundModel) =>
modelsToAdd.includes(foundModel.name)
);
const configFiles = {
v1: 'configs/stable-diffusion/v1-inference.yaml',
v2_base: 'configs/stable-diffusion/v2-inference-v.yaml',
v2_768: 'configs/stable-diffusion/v2-inference-v.yaml',
inpainting: 'configs/stable-diffusion/v1-inpainting-inference.yaml',
custom: pathToConfig,
};
modelsToBeAdded?.forEach((model) => {
const modelFormat = {
name: model.name,
description: '',
config: configFiles[modelType as keyof typeof configFiles],
weights: model.location,
vae: '',
width: 512,
height: 512,
default: false,
format: 'ckpt',
};
dispatch(addNewModel(modelFormat));
});
setModelsToAdd([]);
};
const renderFoundModels = () => {
const newFoundModels: ReactNode[] = [];
const existingFoundModels: ReactNode[] = [];
if (foundModels) {
foundModels.forEach((model, index) => {
if (existingModels.includes(model.location)) {
existingFoundModels.push(
<SearchModelEntry
key={index}
model={model}
modelsToAdd={modelsToAdd}
setModelsToAdd={setModelsToAdd}
/>
);
} else {
newFoundModels.push(
<SearchModelEntry
key={index}
model={model}
modelsToAdd={modelsToAdd}
setModelsToAdd={setModelsToAdd}
/>
);
}
});
}
return (
<Flex flexDirection="column" rowGap={4}>
{newFoundModels}
{shouldShowExistingModelsInSearch && existingFoundModels}
</Flex>
);
};
return (
<>
{searchFolder ? (
<Flex
sx={{
padding: 4,
gap: 2,
position: 'relative',
borderRadius: 'base',
alignItems: 'center',
w: 'full',
bg: 'base.900',
}}
>
<Flex
sx={{
flexDir: 'column',
gap: 2,
}}
>
<Text
sx={{
fontWeight: 500,
}}
variant="subtext"
>
{t('modelManager.checkpointFolder')}
</Text>
<Text sx={{ fontWeight: 500 }}>{searchFolder}</Text>
</Flex>
<Spacer />
<IAIIconButton
aria-label={t('modelManager.scanAgain')}
tooltip={t('modelManager.scanAgain')}
icon={<FaSearch />}
fontSize={18}
disabled={isProcessing}
onClick={() => dispatch(searchForModels(searchFolder))}
/>
<IAIIconButton
aria-label={t('modelManager.clearCheckpointFolder')}
tooltip={t('modelManager.clearCheckpointFolder')}
icon={<FaTrash />}
onClick={resetSearchModelHandler}
/>
</Flex>
) : (
<Formik
initialValues={{ checkpointFolder: '' }}
onSubmit={(values) => {
findModelsHandler(values);
}}
>
{({ handleSubmit }) => (
<IAIForm onSubmit={handleSubmit} width="100%">
<HStack columnGap={2} alignItems="flex-end">
<FormControl flexGrow={1}>
<Field
as={IAIInput}
id="checkpointFolder"
name="checkpointFolder"
type="text"
size="md"
label={t('modelManager.checkpointFolder')}
/>
</FormControl>
<IAIButton
leftIcon={<FaSearch />}
aria-label={t('modelManager.findModels')}
tooltip={t('modelManager.findModels')}
type="submit"
disabled={isProcessing}
px={8}
>
{t('modelManager.findModels')}
</IAIButton>
</HStack>
</IAIForm>
)}
</Formik>
)}
{foundModels && (
<Flex flexDirection="column" rowGap={4} width="full">
<Flex justifyContent="space-between" alignItems="center">
<p>
{t('modelManager.modelsFound')}: {foundModels.length}
</p>
<p>
{t('modelManager.selected')}: {modelsToAdd.length}
</p>
</Flex>
<Flex columnGap={2} justifyContent="space-between">
<Flex columnGap={2}>
<IAIButton
isDisabled={modelsToAdd.length === foundModels.length}
onClick={addAllToSelected}
>
{t('modelManager.selectAll')}
</IAIButton>
<IAIButton
isDisabled={modelsToAdd.length === 0}
onClick={removeAllFromSelected}
>
{t('modelManager.deselectAll')}
</IAIButton>
<IAISimpleCheckbox
label={t('modelManager.showExisting')}
isChecked={shouldShowExistingModelsInSearch}
onChange={() =>
dispatch(
setShouldShowExistingModelsInSearch(
!shouldShowExistingModelsInSearch
)
)
}
/>
</Flex>
<IAIButton
isDisabled={modelsToAdd.length === 0}
onClick={addSelectedModels}
colorScheme="accent"
>
{t('modelManager.addSelected')}
</IAIButton>
</Flex>
<Flex
sx={{
flexDirection: 'column',
padding: 4,
rowGap: 4,
borderRadius: 'base',
width: 'full',
bg: 'base.900',
}}
>
<Flex gap={4}>
<Text fontWeight={500} variant="subtext">
{t('modelManager.pickModelType')}
</Text>
<RadioGroup
value={modelType}
onChange={(v) => setModelType(v)}
defaultValue="v1"
name="model_type"
>
<Flex gap={4}>
<Radio value="v1">
<Text fontSize="sm">{t('modelManager.v1')}</Text>
</Radio>
<Radio value="v2_base">
<Text fontSize="sm">{t('modelManager.v2_base')}</Text>
</Radio>
<Radio value="v2_768">
<Text fontSize="sm">{t('modelManager.v2_768')}</Text>
</Radio>
<Radio value="inpainting">
<Text fontSize="sm">{t('modelManager.inpainting')}</Text>
</Radio>
<Radio value="custom">
<Text fontSize="sm">{t('modelManager.customConfig')}</Text>
</Radio>
</Flex>
</RadioGroup>
</Flex>
{modelType === 'custom' && (
<Flex flexDirection="column" rowGap={2}>
<Text fontWeight="500" fontSize="sm" variant="subtext">
{t('modelManager.pathToCustomConfig')}
</Text>
<IAIInput
value={pathToConfig}
onChange={(e) => {
if (e.target.value !== '') setPathToConfig(e.target.value);
}}
width="full"
/>
</Flex>
)}
</Flex>
<Flex
flexDirection="column"
maxHeight={72}
overflowY="scroll"
borderRadius="sm"
gap={2}
>
{foundModels.length > 0 ? (
renderFoundModels()
) : (
<Text
fontWeight="500"
padding={2}
borderRadius="sm"
textAlign="center"
variant="subtext"
>
{t('modelManager.noModelsFound')}
</Text>
)}
</Flex>
</Flex>
)}
</>
);
}

View File

@ -7,9 +7,8 @@ import ParamPositiveConditioning from 'features/parameters/components/Parameters
import ParamNoiseCollapse from 'features/parameters/components/Parameters/Noise/ParamNoiseCollapse'; import ParamNoiseCollapse from 'features/parameters/components/Parameters/Noise/ParamNoiseCollapse';
import ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse'; import ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse';
import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse'; import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse';
import ParamVariationCollapse from 'features/parameters/components/Parameters/Variations/ParamVariationCollapse'; // import ParamVariationCollapse from 'features/parameters/components/Parameters/Variations/ParamVariationCollapse';
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons'; import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
import { memo } from 'react';
import TextToImageTabCoreParameters from './TextToImageTabCoreParameters'; import TextToImageTabCoreParameters from './TextToImageTabCoreParameters';
const TextToImageTabParameters = () => { const TextToImageTabParameters = () => {
@ -22,7 +21,7 @@ const TextToImageTabParameters = () => {
<ParamControlNetCollapse /> <ParamControlNetCollapse />
<ParamLoraCollapse /> <ParamLoraCollapse />
<ParamDynamicPromptsCollapse /> <ParamDynamicPromptsCollapse />
<ParamVariationCollapse /> {/* <ParamVariationCollapse /> */}
<ParamNoiseCollapse /> <ParamNoiseCollapse />
<ParamSymmetryCollapse /> <ParamSymmetryCollapse />
<ParamSeamlessCollapse /> <ParamSeamlessCollapse />
@ -31,4 +30,4 @@ const TextToImageTabParameters = () => {
); );
}; };
export default memo(TextToImageTabParameters); export default TextToImageTabParameters;

View File

@ -7,9 +7,8 @@ import ParamControlNetCollapse from 'features/parameters/components/Parameters/C
import ParamNegativeConditioning from 'features/parameters/components/Parameters/Core/ParamNegativeConditioning'; import ParamNegativeConditioning from 'features/parameters/components/Parameters/Core/ParamNegativeConditioning';
import ParamPositiveConditioning from 'features/parameters/components/Parameters/Core/ParamPositiveConditioning'; import ParamPositiveConditioning from 'features/parameters/components/Parameters/Core/ParamPositiveConditioning';
import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse'; import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse';
import ParamVariationCollapse from 'features/parameters/components/Parameters/Variations/ParamVariationCollapse'; // import ParamVariationCollapse from 'features/parameters/components/Parameters/Variations/ParamVariationCollapse';
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons'; import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
import { memo } from 'react';
import UnifiedCanvasCoreParameters from './UnifiedCanvasCoreParameters'; import UnifiedCanvasCoreParameters from './UnifiedCanvasCoreParameters';
const UnifiedCanvasParameters = () => { const UnifiedCanvasParameters = () => {
@ -22,7 +21,7 @@ const UnifiedCanvasParameters = () => {
<ParamControlNetCollapse /> <ParamControlNetCollapse />
<ParamLoraCollapse /> <ParamLoraCollapse />
<ParamDynamicPromptsCollapse /> <ParamDynamicPromptsCollapse />
<ParamVariationCollapse /> {/* <ParamVariationCollapse /> */}
<ParamSymmetryCollapse /> <ParamSymmetryCollapse />
<ParamSeamCorrectionCollapse /> <ParamSeamCorrectionCollapse />
<ParamInfillAndScalingCollapse /> <ParamInfillAndScalingCollapse />
@ -31,4 +30,4 @@ const UnifiedCanvasParameters = () => {
); );
}; };
export default memo(UnifiedCanvasParameters); export default UnifiedCanvasParameters;

View File

@ -4,7 +4,7 @@ import { initialImageChanged } from 'features/parameters/store/generationSlice';
import { SchedulerParam } from 'features/parameters/types/parameterSchemas'; import { SchedulerParam } from 'features/parameters/types/parameterSchemas';
import { setActiveTabReducer } from './extraReducers'; import { setActiveTabReducer } from './extraReducers';
import { InvokeTabName } from './tabMap'; import { InvokeTabName } from './tabMap';
import { AddNewModelType, UIState } from './uiTypes'; import { UIState } from './uiTypes';
export const initialUIState: UIState = { export const initialUIState: UIState = {
activeTab: 0, activeTab: 0,
@ -14,7 +14,6 @@ export const initialUIState: UIState = {
shouldUseCanvasBetaLayout: false, shouldUseCanvasBetaLayout: false,
shouldShowExistingModelsInSearch: false, shouldShowExistingModelsInSearch: false,
shouldUseSliders: false, shouldUseSliders: false,
addNewModelUIOption: null,
shouldPinGallery: true, shouldPinGallery: true,
shouldShowGallery: true, shouldShowGallery: true,
shouldHidePreview: false, shouldHidePreview: false,
@ -57,9 +56,6 @@ export const uiSlice = createSlice({
setShouldUseSliders: (state, action: PayloadAction<boolean>) => { setShouldUseSliders: (state, action: PayloadAction<boolean>) => {
state.shouldUseSliders = action.payload; state.shouldUseSliders = action.payload;
}, },
setAddNewModelUIOption: (state, action: PayloadAction<AddNewModelType>) => {
state.addNewModelUIOption = action.payload;
},
setShouldShowGallery: (state, action: PayloadAction<boolean>) => { setShouldShowGallery: (state, action: PayloadAction<boolean>) => {
state.shouldShowGallery = action.payload; state.shouldShowGallery = action.payload;
}, },
@ -124,7 +120,6 @@ export const {
setShouldUseCanvasBetaLayout, setShouldUseCanvasBetaLayout,
setShouldShowExistingModelsInSearch, setShouldShowExistingModelsInSearch,
setShouldUseSliders, setShouldUseSliders,
setAddNewModelUIOption,
setShouldHidePreview, setShouldHidePreview,
setShouldShowGallery, setShouldShowGallery,
togglePanels, togglePanels,

View File

@ -1,36 +0,0 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ImageField } from './ImageField';
/**
* Applies HED edge detection to image
*/
export type HedImageProcessorInvocation = {
/**
* The id of this node. Must be unique among all nodes.
*/
id: string;
/**
* Whether or not this node is an intermediate node.
*/
is_intermediate?: boolean;
type?: 'hed_image_processor';
/**
* The image to process
*/
image?: ImageField;
/**
* The pixel resolution for detection
*/
detect_resolution?: number;
/**
* The pixel resolution for the output image
*/
image_resolution?: number;
/**
* Whether to use scribble mode
*/
scribble?: boolean;
};