mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-02-17 05:01:27 -05:00
181 lines
5.7 KiB
TypeScript
181 lines
5.7 KiB
TypeScript
import {
|
|
Box,
|
|
Flex,
|
|
FormControl,
|
|
FormLabel,
|
|
Icon,
|
|
IconButton,
|
|
Switch,
|
|
} from '@invoke-ai/ui-library';
|
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
|
import { useControlAdapterIsEnabled } from 'features/controlAdapters/hooks/useControlAdapterIsEnabled';
|
|
import { useControlAdapterType } from 'features/controlAdapters/hooks/useControlAdapterType';
|
|
import {
|
|
controlAdapterDuplicated,
|
|
controlAdapterIsEnabledChanged,
|
|
controlAdapterRemoved,
|
|
} from 'features/controlAdapters/store/controlAdaptersSlice';
|
|
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
|
import type { ChangeEvent } from 'react';
|
|
import { memo, useCallback } from 'react';
|
|
import { useTranslation } from 'react-i18next';
|
|
import { PiCaretUpBold, PiCopyBold, PiTrashSimpleBold } from 'react-icons/pi';
|
|
import { useToggle } from 'react-use';
|
|
|
|
import ControlAdapterImagePreview from './ControlAdapterImagePreview';
|
|
import ControlAdapterProcessorComponent from './ControlAdapterProcessorComponent';
|
|
import ControlAdapterShouldAutoConfig from './ControlAdapterShouldAutoConfig';
|
|
import ControlNetCanvasImageImports from './imports/ControlNetCanvasImageImports';
|
|
import { ParamControlAdapterBeginEnd } from './parameters/ParamControlAdapterBeginEnd';
|
|
import ParamControlAdapterControlMode from './parameters/ParamControlAdapterControlMode';
|
|
import ParamControlAdapterModel from './parameters/ParamControlAdapterModel';
|
|
import ParamControlAdapterProcessorSelect from './parameters/ParamControlAdapterProcessorSelect';
|
|
import ParamControlAdapterResizeMode from './parameters/ParamControlAdapterResizeMode';
|
|
import ParamControlAdapterWeight from './parameters/ParamControlAdapterWeight';
|
|
|
|
const ControlAdapterConfig = (props: { id: string; number: number }) => {
|
|
const { id, number } = props;
|
|
const controlAdapterType = useControlAdapterType(id);
|
|
const dispatch = useAppDispatch();
|
|
const { t } = useTranslation();
|
|
|
|
const activeTabName = useAppSelector(activeTabNameSelector);
|
|
const isEnabled = useControlAdapterIsEnabled(id);
|
|
const [isExpanded, toggleIsExpanded] = useToggle(false);
|
|
|
|
const handleDelete = useCallback(() => {
|
|
dispatch(controlAdapterRemoved({ id }));
|
|
}, [id, dispatch]);
|
|
|
|
const handleDuplicate = useCallback(() => {
|
|
dispatch(controlAdapterDuplicated(id));
|
|
}, [id, dispatch]);
|
|
|
|
const handleToggleIsEnabled = useCallback(
|
|
(e: ChangeEvent<HTMLInputElement>) => {
|
|
dispatch(
|
|
controlAdapterIsEnabledChanged({
|
|
id,
|
|
isEnabled: e.target.checked,
|
|
})
|
|
);
|
|
},
|
|
[id, dispatch]
|
|
);
|
|
|
|
if (!controlAdapterType) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<Flex
|
|
flexDir="column"
|
|
gap={4}
|
|
p={4}
|
|
borderRadius="base"
|
|
position="relative"
|
|
bg="base.750"
|
|
>
|
|
<Flex gap={2} alignItems="center" justifyContent="space-between">
|
|
<FormControl>
|
|
<FormLabel flexGrow={1}>
|
|
{t(`controlnet.${controlAdapterType}`, { number })}
|
|
</FormLabel>
|
|
<Switch
|
|
aria-label={t('controlnet.toggleControlNet')}
|
|
isChecked={isEnabled}
|
|
onChange={handleToggleIsEnabled}
|
|
/>
|
|
</FormControl>
|
|
</Flex>
|
|
<Flex gap={4} alignItems="center">
|
|
<Box
|
|
minW={0}
|
|
w="full"
|
|
transitionProperty="common"
|
|
transitionDuration="0.1s"
|
|
>
|
|
<ParamControlAdapterModel id={id} />
|
|
</Box>
|
|
{activeTabName === 'unifiedCanvas' && (
|
|
<ControlNetCanvasImageImports id={id} />
|
|
)}
|
|
<IconButton
|
|
size="sm"
|
|
tooltip={t('controlnet.duplicate')}
|
|
aria-label={t('controlnet.duplicate')}
|
|
onClick={handleDuplicate}
|
|
icon={<PiCopyBold />}
|
|
/>
|
|
<IconButton
|
|
size="sm"
|
|
tooltip={t('controlnet.delete')}
|
|
aria-label={t('controlnet.delete')}
|
|
colorScheme="error"
|
|
onClick={handleDelete}
|
|
icon={<PiTrashSimpleBold />}
|
|
/>
|
|
<IconButton
|
|
size="sm"
|
|
tooltip={
|
|
isExpanded
|
|
? t('controlnet.hideAdvanced')
|
|
: t('controlnet.showAdvanced')
|
|
}
|
|
aria-label={
|
|
isExpanded
|
|
? t('controlnet.hideAdvanced')
|
|
: t('controlnet.showAdvanced')
|
|
}
|
|
onClick={toggleIsExpanded}
|
|
variant="ghost"
|
|
icon={
|
|
<Icon
|
|
boxSize={4}
|
|
as={PiCaretUpBold}
|
|
transform={isExpanded ? 'rotate(0deg)' : 'rotate(180deg)'}
|
|
transitionProperty="common"
|
|
transitionDuration="normal"
|
|
/>
|
|
}
|
|
/>
|
|
</Flex>
|
|
|
|
<Flex w="full" flexDir="column" gap={4}>
|
|
<Flex gap={8} w="full" alignItems="center">
|
|
<Flex flexDir="column" gap={2} h={32} w="full">
|
|
<ParamControlAdapterWeight id={id} />
|
|
<ParamControlAdapterBeginEnd id={id} />
|
|
</Flex>
|
|
{!isExpanded && (
|
|
<Flex
|
|
alignItems="center"
|
|
justifyContent="center"
|
|
h={32}
|
|
w={32}
|
|
aspectRatio="1/1"
|
|
>
|
|
<ControlAdapterImagePreview id={id} isSmall />
|
|
</Flex>
|
|
)}
|
|
</Flex>
|
|
</Flex>
|
|
|
|
{isExpanded && (
|
|
<>
|
|
<Flex gap={2}>
|
|
<ParamControlAdapterControlMode id={id} />
|
|
<ParamControlAdapterResizeMode id={id} />
|
|
</Flex>
|
|
<ParamControlAdapterProcessorSelect id={id} />
|
|
<ControlAdapterImagePreview id={id} />
|
|
<ControlAdapterShouldAutoConfig id={id} />
|
|
<ControlAdapterProcessorComponent id={id} />
|
|
</>
|
|
)}
|
|
</Flex>
|
|
);
|
|
};
|
|
|
|
export default memo(ControlAdapterConfig);
|