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) => {
if (!props.dragData) {
return;
return null;
}
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,
}}
/>
{withMetadataOverlay && <ImageMetadataOverlay image={imageDTO} />}
{withMetadataOverlay && (
<ImageMetadataOverlay imageDTO={imageDTO} />
)}
<SelectionOverlay
isSelected={isSelected}
isHovered={withHoverOverlay ? isHovered : false}

View File

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

View File

@ -2,17 +2,16 @@ 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 { validateSeedWeights } from 'common/util/seedWeightPairs';
// import { validateSeedWeights } from 'common/util/seedWeightPairs';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { modelsApi } from '../../services/api/endpoints/models';
import { forEach } from 'lodash-es';
import { modelsApi } from '../../services/api/endpoints/models';
const readinessSelector = createSelector(
[stateSelector, activeTabNameSelector],
(state, activeTabName) => {
const { generation, system } = state;
const { shouldGenerateVariations, seedWeights, initialImage, seed } =
generation;
const { initialImage } = generation;
const { isProcessing, isConnected } = system;
@ -44,19 +43,19 @@ const readinessSelector = createSelector(
reasonsWhyNotReady.push('System Disconnected');
}
// Cannot generate variations without valid seed weights
if (
shouldGenerateVariations &&
(!(validateSeedWeights(seedWeights) || seedWeights === '') || seed === -1)
) {
isReady = false;
reasonsWhyNotReady.push('Seed-Weights badly formatted.');
}
// // Cannot generate variations without valid seed weights
// if (
// shouldGenerateVariations &&
// (!(validateSeedWeights(seedWeights) || seedWeights === '') || seed === -1)
// ) {
// isReady = false;
// reasonsWhyNotReady.push('Seed-Weights badly formatted.');
// }
forEach(state.controlNet.controlNets, (controlNet, id) => {
if (!controlNet.model) {
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 = (
string: string
): InvokeAI.SeedWeights | boolean => {
const stringPairs = string.split(',');
const arrPairs = stringPairs.map((p) => p.split(':'));
const pairs = arrPairs.map((p: Array<string>): InvokeAI.SeedWeightPair => {
return { seed: Number(p[0]), weight: Number(p[1]) };
});
// export const stringToSeedWeights = (
// string: string
// ): InvokeAI.SeedWeights | boolean => {
// const stringPairs = string.split(',');
// const arrPairs = stringPairs.map((p) => p.split(':'));
// const pairs = arrPairs.map((p: Array<string>): InvokeAI.SeedWeightPair => {
// return { seed: Number(p[0]), weight: Number(p[1]) };
// });
if (!validateSeedWeights(pairs)) {
return false;
}
// if (!validateSeedWeights(pairs)) {
// return false;
// }
return pairs;
};
// return pairs;
// };
export const validateSeedWeights = (
seedWeights: InvokeAI.SeedWeights | string
): boolean => {
return typeof seedWeights === 'string'
? Boolean(stringToSeedWeights(seedWeights))
: Boolean(
seedWeights.length &&
!seedWeights.some((pair: InvokeAI.SeedWeightPair) => {
const { seed, weight } = pair;
const isSeedValid = !isNaN(parseInt(seed.toString(), 10));
const isWeightValid =
!isNaN(parseInt(weight.toString(), 10)) &&
weight >= 0 &&
weight <= 1;
return !(isSeedValid && isWeightValid);
})
);
};
// export const validateSeedWeights = (
// seedWeights: InvokeAI.SeedWeights | string
// ): boolean => {
// return typeof seedWeights === 'string'
// ? Boolean(stringToSeedWeights(seedWeights))
// : Boolean(
// seedWeights.length &&
// !seedWeights.some((pair: InvokeAI.SeedWeightPair) => {
// const { seed, weight } = pair;
// const isSeedValid = !isNaN(parseInt(seed.toString(), 10));
// const isWeightValid =
// !isNaN(parseInt(weight.toString(), 10)) &&
// weight >= 0 &&
// weight <= 1;
// return !(isSeedValid && isWeightValid);
// })
// );
// };
export const seedWeightsToString = (
seedWeights: InvokeAI.SeedWeights
): string => {
return seedWeights.reduce((acc, pair, i, arr) => {
const { seed, weight } = pair;
acc += `${seed}:${weight}`;
if (i !== arr.length - 1) {
acc += ',';
}
return acc;
}, '');
};
// export const seedWeightsToString = (
// seedWeights: InvokeAI.SeedWeights
// ): string => {
// return seedWeights.reduce((acc, pair, i, arr) => {
// const { seed, weight } = pair;
// acc += `${seed}:${weight}`;
// if (i !== arr.length - 1) {
// acc += ',';
// }
// return acc;
// }, '');
// };
export const seedWeightsToArray = (
seedWeights: InvokeAI.SeedWeights
): Array<Array<number>> => {
return seedWeights.map((pair: InvokeAI.SeedWeightPair) => [
pair.seed,
pair.weight,
]);
};
// export const seedWeightsToArray = (
// seedWeights: InvokeAI.SeedWeights
// ): Array<Array<number>> => {
// return seedWeights.map((pair: InvokeAI.SeedWeightPair) => [
// pair.seed,
// pair.weight,
// ]);
// };
export const stringToSeedWeightsArray = (
string: string
): Array<Array<number>> => {
const stringPairs = string.split(',');
const arrPairs = stringPairs.map((p) => p.split(':'));
return arrPairs.map(
(p: Array<string>): Array<number> => [parseInt(p[0], 10), parseFloat(p[1])]
);
};
// export const stringToSeedWeightsArray = (
// string: string
// ): Array<Array<number>> => {
// const stringPairs = string.split(',');
// const arrPairs = stringPairs.map((p) => p.split(':'));
// return arrPairs.map(
// (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 { RgbaColor } from 'react-colorful';
import { ImageDTO } from 'services/api/types';
export const LAYER_NAMES_DICT = [
{ label: 'Base', value: 'base' },
@ -133,7 +131,6 @@ export interface CanvasState {
cursorPosition: Vector2d | null;
doesCanvasNeedScaling: boolean;
futureLayerStates: CanvasLayerState[];
intermediateImage?: InvokeAI.Image;
isCanvasInitialized: boolean;
isDrawing: 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>
);
}
return null;
};
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)[] = [
'selection',
'entities',
'ids',
'isLoading',
'limit',
'offset',
'selectedBoardId',
'galleryView',
'total',
'isInitialized',
];

View File

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

View File

@ -18,7 +18,13 @@ const selector = createSelector(
const ParamLoraList = () => {
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;

View File

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

View File

@ -22,13 +22,16 @@ export default function ParamAdvancedCollapse() {
const shouldShowAdvancedOptions = useAppSelector(
(state: RootState) => state.ui.shouldShowAdvancedOptions
);
if (!shouldShowAdvancedOptions) {
return null;
}
return (
shouldShowAdvancedOptions && (
<IAICollapse label={'Advanced'} activeLabel={activeLabel}>
<Flex sx={{ flexDir: 'column', gap: 2 }}>
<ParamClipSkip />
</Flex>
</IAICollapse>
)
<IAICollapse label={'Advanced'} activeLabel={activeLabel}>
<Flex sx={{ flexDir: 'column', gap: 2 }}>
<ParamClipSkip />
</Flex>
</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';
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';
// TODO: variations
const selector = createSelector(
stateSelector,
(state) => {
const activeLabel = state.generation.shouldGenerateVariations
? 'Enabled'
: undefined;
// import { Flex } from '@chakra-ui/react';
// 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';
return { activeLabel };
},
defaultSelectorOptions
);
// const selector = createSelector(
// stateSelector,
// (state) => {
// const activeLabel = state.generation.shouldGenerateVariations
// ? 'Enabled'
// : undefined;
const ParamVariationCollapse = () => {
const { t } = useTranslation();
const { activeLabel } = useAppSelector(selector);
// return { activeLabel };
// },
// defaultSelectorOptions
// );
const isVariationEnabled = useFeatureStatus('variation').isFeatureEnabled;
// const ParamVariationCollapse = () => {
// const { t } = useTranslation();
// const { activeLabel } = useAppSelector(selector);
if (!isVariationEnabled) {
return null;
}
// const isVariationEnabled = useFeatureStatus('variation').isFeatureEnabled;
return (
<IAICollapse label={t('parameters.variations')} activeLabel={activeLabel}>
<Flex sx={{ gap: 2, flexDirection: 'column' }}>
<ParamVariationToggle />
<ParamVariationAmount />
<ParamVariationWeights />
</Flex>
</IAICollapse>
);
};
// if (!isVariationEnabled) {
// return null;
// }
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';
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';
// TODO: variations
export default function ParamVariationWeights() {
const seedWeights = useAppSelector(
(state: RootState) => state.generation.seedWeights
);
// import { RootState } from 'app/store/store';
// 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';
const shouldGenerateVariations = useAppSelector(
(state: RootState) => state.generation.shouldGenerateVariations
);
// export default function ParamVariationWeights() {
// 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>) =>
dispatch(setSeedWeights(e.target.value));
// const dispatch = useAppDispatch();
return (
<IAIInput
label={t('parameters.seedWeights')}
value={seedWeights}
isInvalid={
shouldGenerateVariations &&
!(validateSeedWeights(seedWeights) || seedWeights === '')
}
isDisabled={!shouldGenerateVariations}
onChange={handleChangeSeedWeights}
/>
);
}
// const handleChangeSeedWeights = (e: ChangeEvent<HTMLInputElement>) =>
// dispatch(setSeedWeights(e.target.value));
// return (
// <IAIInput
// label={t('parameters.seedWeights')}
// value={seedWeights}
// isInvalid={
// shouldGenerateVariations &&
// !(validateSeedWeights(seedWeights) || seedWeights === '')
// }
// isDisabled={!shouldGenerateVariations}
// onChange={handleChangeSeedWeights}
// />
// );
// }
export default {};

View File

@ -1,47 +1,11 @@
import { createSelector } from '@reduxjs/toolkit';
import { RootState } from 'app/store/store';
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import { pickBy, reduce } from 'lodash-es';
export const systemSelector = (state: RootState) => state.system;
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(
systemSelector,
(system) => system.language,

View File

@ -74,7 +74,8 @@ export interface SystemState {
*/
consoleLogLevel: InvokeLogLevel;
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.
*/
@ -125,7 +126,7 @@ export const systemSlice = createSlice({
setIsProcessing: (state, action: PayloadAction<boolean>) => {
state.isProcessing = action.payload;
},
setCurrentStatus: (state, action: any) => {
setCurrentStatus: (state, action: PayloadAction<string>) => {
state.statusTranslationKey = action.payload;
},
setShouldConfirmOnDelete: (state, action: PayloadAction<boolean>) => {
@ -362,7 +363,7 @@ export const systemSlice = createSlice({
* Session Invoked - REJECTED
* Session Created - REJECTED
*/
builder.addMatcher(isAnySessionRejected, (state, action) => {
builder.addMatcher(isAnySessionRejected, (state) => {
state.isProcessing = false;
state.isCancelable = 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 ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse';
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 { memo } from 'react';
import ImageToImageTabCoreParameters from './ImageToImageTabCoreParameters';
const ImageToImageTabParameters = () => {
@ -22,7 +21,7 @@ const ImageToImageTabParameters = () => {
<ParamControlNetCollapse />
<ParamLoraCollapse />
<ParamDynamicPromptsCollapse />
<ParamVariationCollapse />
{/* <ParamVariationCollapse /> */}
<ParamNoiseCollapse />
<ParamSymmetryCollapse />
<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 = () => {
if (!searchFolder) return;
if (!searchFolder) {
return null;
}
if (!foundModels || foundModels.length === 0) {
return (
@ -242,7 +244,7 @@ const foundModelsFilter = (
const filteredModels: SearchFolderResponse = [];
forEach(data, (model) => {
if (!model) {
return;
return null;
}
if (model.includes(nameFilter)) {

View File

@ -32,66 +32,68 @@ export default function ScanAdvancedAddModels() {
const dispatch = useAppDispatch();
if (!advancedAddScanModel) {
return null;
}
return (
advancedAddScanModel && (
<Box
as={motion.div}
initial={{ x: -100, opacity: 0 }}
animate={{ x: 0, opacity: 1, transition: { duration: 0.2 } }}
sx={{
display: 'flex',
flexDirection: 'column',
minWidth: '40%',
maxHeight: window.innerHeight - 300,
overflow: 'scroll',
p: 4,
gap: 4,
borderRadius: 4,
bg: 'base.200',
_dark: {
bg: 'base.800',
},
}}
>
<Flex justifyContent="space-between" alignItems="center">
<Text size="xl" fontWeight={600}>
{isCheckpoint || advancedAddMode === 'checkpoint'
? 'Add Checkpoint Model'
: 'Add Diffusers Model'}
</Text>
<IAIIconButton
icon={<FaTimes />}
aria-label="Close Advanced"
onClick={() => dispatch(setAdvancedAddScanModel(null))}
size="sm"
/>
</Flex>
<IAIMantineSelect
label="Model Type"
value={advancedAddMode}
data={advancedAddModeData}
onChange={(v) => {
if (!v) return;
setAdvancedAddMode(v as ManualAddMode);
if (v === 'checkpoint') {
setIsCheckpoint(true);
} else {
setIsCheckpoint(false);
}
}}
<Box
as={motion.div}
initial={{ x: -100, opacity: 0 }}
animate={{ x: 0, opacity: 1, transition: { duration: 0.2 } }}
sx={{
display: 'flex',
flexDirection: 'column',
minWidth: '40%',
maxHeight: window.innerHeight - 300,
overflow: 'scroll',
p: 4,
gap: 4,
borderRadius: 4,
bg: 'base.200',
_dark: {
bg: 'base.800',
},
}}
>
<Flex justifyContent="space-between" alignItems="center">
<Text size="xl" fontWeight={600}>
{isCheckpoint || advancedAddMode === 'checkpoint'
? 'Add Checkpoint Model'
: 'Add Diffusers Model'}
</Text>
<IAIIconButton
icon={<FaTimes />}
aria-label="Close Advanced"
onClick={() => dispatch(setAdvancedAddScanModel(null))}
size="sm"
/>
{isCheckpoint ? (
<AdvancedAddCheckpoint
key={advancedAddScanModel}
model_path={advancedAddScanModel}
/>
) : (
<AdvancedAddDiffusers
key={advancedAddScanModel}
model_path={advancedAddScanModel}
/>
)}
</Box>
)
</Flex>
<IAIMantineSelect
label="Model Type"
value={advancedAddMode}
data={advancedAddModeData}
onChange={(v) => {
if (!v) return;
setAdvancedAddMode(v as ManualAddMode);
if (v === 'checkpoint') {
setIsCheckpoint(true);
} else {
setIsCheckpoint(false);
}
}}
/>
{isCheckpoint ? (
<AdvancedAddCheckpoint
key={advancedAddScanModel}
model_path={advancedAddScanModel}
/>
) : (
<AdvancedAddDiffusers
key={advancedAddScanModel}
model_path={advancedAddScanModel}
/>
)}
</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 ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse';
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 { memo } from 'react';
import TextToImageTabCoreParameters from './TextToImageTabCoreParameters';
const TextToImageTabParameters = () => {
@ -22,7 +21,7 @@ const TextToImageTabParameters = () => {
<ParamControlNetCollapse />
<ParamLoraCollapse />
<ParamDynamicPromptsCollapse />
<ParamVariationCollapse />
{/* <ParamVariationCollapse /> */}
<ParamNoiseCollapse />
<ParamSymmetryCollapse />
<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 ParamPositiveConditioning from 'features/parameters/components/Parameters/Core/ParamPositiveConditioning';
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 { memo } from 'react';
import UnifiedCanvasCoreParameters from './UnifiedCanvasCoreParameters';
const UnifiedCanvasParameters = () => {
@ -22,7 +21,7 @@ const UnifiedCanvasParameters = () => {
<ParamControlNetCollapse />
<ParamLoraCollapse />
<ParamDynamicPromptsCollapse />
<ParamVariationCollapse />
{/* <ParamVariationCollapse /> */}
<ParamSymmetryCollapse />
<ParamSeamCorrectionCollapse />
<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 { setActiveTabReducer } from './extraReducers';
import { InvokeTabName } from './tabMap';
import { AddNewModelType, UIState } from './uiTypes';
import { UIState } from './uiTypes';
export const initialUIState: UIState = {
activeTab: 0,
@ -14,7 +14,6 @@ export const initialUIState: UIState = {
shouldUseCanvasBetaLayout: false,
shouldShowExistingModelsInSearch: false,
shouldUseSliders: false,
addNewModelUIOption: null,
shouldPinGallery: true,
shouldShowGallery: true,
shouldHidePreview: false,
@ -57,9 +56,6 @@ export const uiSlice = createSlice({
setShouldUseSliders: (state, action: PayloadAction<boolean>) => {
state.shouldUseSliders = action.payload;
},
setAddNewModelUIOption: (state, action: PayloadAction<AddNewModelType>) => {
state.addNewModelUIOption = action.payload;
},
setShouldShowGallery: (state, action: PayloadAction<boolean>) => {
state.shouldShowGallery = action.payload;
},
@ -124,7 +120,6 @@ export const {
setShouldUseCanvasBetaLayout,
setShouldShowExistingModelsInSearch,
setShouldUseSliders,
setAddNewModelUIOption,
setShouldHidePreview,
setShouldShowGallery,
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;
};