mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
fix(ui): resolve all typescript issues
This commit is contained in:
parent
75863e7181
commit
5468d9a9fc
@ -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') {
|
||||||
|
@ -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);
|
|
@ -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);
|
|
@ -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}
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -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.`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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];
|
|
||||||
}
|
|
@ -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;
|
|
@ -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 {};
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
|
@ -159,6 +159,8 @@ const GalleryImageGrid = () => {
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(GalleryImageGrid);
|
export default memo(GalleryImageGrid);
|
||||||
|
@ -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())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
@ -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',
|
|
||||||
];
|
];
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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 />}
|
||||||
|
@ -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>
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
@ -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);
|
|
@ -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 {};
|
||||||
|
@ -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 {};
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
|
@ -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;
|
||||||
|
@ -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)) {
|
||||||
|
@ -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>
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
|
||||||
};
|
|
Loading…
x
Reference in New Issue
Block a user