Partial migration of UI to nodes API (#3195)

* feat(ui): add axios client generator and simple example

* fix(ui): update client & nodes test code w/ new Edge type

* chore(ui): organize generated files

* chore(ui): update .eslintignore, .prettierignore

* chore(ui): update openapi.json

* feat(backend): fixes for nodes/generator

* feat(ui): generate object args for api client

* feat(ui): more nodes api prototyping

* feat(ui): nodes cancel

* chore(ui): regenerate api client

* fix(ui): disable OG web server socket connection

* fix(ui): fix scrollbar styles typing and prop

just noticed the typo, and made the types stronger.

* feat(ui): add socketio types

* feat(ui): wip nodes

- extract api client method arg types instead of manually declaring them
- update example to display images
- general tidy up

* start building out node translations from frontend state and add notes about missing features

* use reference to sampler_name

* use reference to sampler_name

* add optional apiUrl prop

* feat(ui): start hooking up dynamic txt2img node generation, create middleware for session invocation

* feat(ui): write separate nodes socket layer, txt2img generating and rendering w single node

* feat(ui): img2img implementation

* feat(ui): get intermediate images working but types are stubbed out

* chore(ui): add support for package mode

* feat(ui): add nodes mode script

* feat(ui): handle random seeds

* fix(ui): fix middleware types

* feat(ui): add rtk action type guard

* feat(ui): disable NodeAPITest

This was polluting the network/socket logs.

* feat(ui): fix parameters panel border color

This commit should be elsewhere but I don't want to break my flow

* feat(ui): make thunk types more consistent

* feat(ui): add type guards for outputs

* feat(ui): load images on socket connect

Rudimentary

* chore(ui): bump redux-toolkit

* docs(ui): update readme

* chore(ui): regenerate api client

* chore(ui): add typescript as dev dependency

I am having trouble with TS versions after vscode updated and now uses TS 5. `madge` has installed 3.9.10 and for whatever reason my vscode wants to use that. Manually specifying 4.9.5 and then setting vscode to use that as the workspace TS fixes the issue.

* feat(ui): begin migrating gallery to nodes

Along the way, migrate to use RTK `createEntityAdapter` for gallery images, and separate `results` and `uploads` into separate slices. Much cleaner this way.

* feat(ui): clean up & comment results slice

* fix(ui): separate thunk for initial gallery load so it properly gets index 0

* feat(ui): POST upload working

* fix(ui): restore removed type

* feat(ui): patch api generation for headers access

* chore(ui): regenerate api

* feat(ui): wip gallery migration

* feat(ui): wip gallery migration

* chore(ui): regenerate api

* feat(ui): wip refactor socket events

* feat(ui): disable panels based on app props

* feat(ui): invert logic to be disabled

* disable panels when app mounts

* feat(ui): add support to disableTabs

* docs(ui): organise and update docs

* lang(ui): add toast strings

* feat(ui): wip events, comments, and general refactoring

* feat(ui): add optional token for auth

* feat(ui): export StatusIndicator and ModelSelect for header use

* feat(ui) working on making socket URL dynamic

* feat(ui): dynamic middleware loading

* feat(ui): prep for socket jwt

* feat(ui): migrate cancelation

also updated action names to be event-like instead of declaration-like

sorry, i was scattered and this commit has a lot of unrelated stuff in it.

* fix(ui): fix img2img type

* chore(ui): regenerate api client

* feat(ui): improve InvocationCompleteEvent types

* feat(ui): increase StatusIndicator font size

* fix(ui): fix middleware order for multi-node graphs

* feat(ui): add exampleGraphs object w/ iterations example

* feat(ui): generate iterations graph

* feat(ui): update ModelSelect for nodes API

* feat(ui): add hi-res functionality for txt2img generations

* feat(ui): "subscribe" to particular nodes

feels like a dirty hack but oh well it works

* feat(ui): first steps to node editor ui

* fix(ui): disable event subscription

it is not fully baked just yet

* feat(ui): wip node editor

* feat(ui): remove extraneous field types

* feat(ui): nodes before deleting stuff

* feat(ui): cleanup nodes ui stuff

* feat(ui): hook up nodes to redux

* fix(ui): fix handle

* fix(ui): add basic node edges & connection validation

* feat(ui): add connection validation styling

* feat(ui): increase edge width

* feat(ui): it blends

* feat(ui): wip model handling and graph topology validation

* feat(ui): validation connections w/ graphlib

* docs(ui): update nodes doc

* feat(ui): wip node editor

* chore(ui): rebuild api, update types

* add redux-dynamic-middlewares as a dependency

* feat(ui): add url host transformation

* feat(ui): handle already-connected fields

* feat(ui): rewrite SqliteItemStore in sqlalchemy

* fix(ui): fix sqlalchemy dynamic model instantiation

* feat(ui, nodes): metadata wip

* feat(ui, nodes): models

* feat(ui, nodes): more metadata wip

* feat(ui): wip range/iterate

* fix(nodes): fix sqlite typing

* feat(ui): export new type for invoke component

* tests(nodes): fix test instantiation of ImageField

* feat(nodes): fix LoadImageInvocation

* feat(nodes): add `title` ui hint

* feat(nodes): make ImageField attrs optional

* feat(ui): wip nodes etc

* feat(nodes): roll back sqlalchemy

* fix(nodes): partially address feedback

* fix(backend): roll back changes to pngwriter

* feat(nodes): wip address metadata feedback

* feat(nodes): add seeded rng to RandomRange

* feat(nodes): address feedback

* feat(nodes): move GET images error handling to DiskImageStorage

* feat(nodes): move GET images error handling to DiskImageStorage

* fix(nodes): fix image output schema customization

* feat(ui): img2img/txt2img -> linear

- remove txt2img and img2img tabs
- add linear tab
- add initial image selection to linear parameters accordion

* feat(ui): tidy graph builders

* feat(ui): tidy misc

* feat(ui): improve invocation union types

* feat(ui): wip metadata viewer recall

* feat(ui): move fonts to normal deps

* feat(nodes): fix broken upload

* feat(nodes): add metadata module + tests, thumbnails

- `MetadataModule` is stateless and needed in places where the `InvocationContext` is not available, so have not made it a `service`
- Handles loading/parsing/building metadata, and creating png info objects
- added tests for MetadataModule
- Lifted thumbnail stuff to util

* fix(nodes): revert change to RandomRangeInvocation

* feat(nodes): address feedback

- make metadata a service
- rip out pydantic validation, implement metadata parsing as simple functions
- update tests
- address other minor feedback items

* fix(nodes): fix other tests

* fix(nodes): add metadata service to cli

* fix(nodes): fix latents/image field parsing

* feat(nodes): customise LatentsField schema

* feat(nodes): move metadata parsing to frontend

* fix(nodes): fix metadata test

---------

Co-authored-by: maryhipp <maryhipp@gmail.com>
Co-authored-by: Mary Hipp <maryhipp@Marys-MacBook-Air.local>
This commit is contained in:
psychedelicious
2023-04-22 13:10:20 +10:00
committed by GitHub
parent fdad62e88b
commit 5f498e10bd
324 changed files with 13051 additions and 1400 deletions

View File

@@ -15,9 +15,7 @@ const floatingGalleryButtonSelector = createSelector(
return {
shouldPinGallery,
shouldShowGalleryButton:
(!shouldPinGallery || !shouldShowGallery) &&
['txt2img', 'img2img', 'unifiedCanvas'].includes(activeTabName),
shouldShowGalleryButton: !shouldPinGallery || !shouldShowGallery,
};
},
{ memoizeOptions: { resultEqualityCheck: isEqual } }

View File

@@ -39,7 +39,7 @@ export const floatingParametersPanelButtonSelector = createSelector(
const shouldShowParametersPanelButton =
!canvasBetaLayoutCheck &&
(!shouldPinParametersPanel || !shouldShowParametersPanel) &&
['txt2img', 'img2img', 'unifiedCanvas'].includes(activeTabName);
['linear', 'unifiedCanvas'].includes(activeTabName);
return {
shouldPinParametersPanel,

View File

@@ -11,29 +11,20 @@ import {
} from '@chakra-ui/react';
import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import NodesWIP from 'common/components/WorkInProgress/NodesWIP';
import { PostProcessingWIP } from 'common/components/WorkInProgress/PostProcessingWIP';
import TrainingWIP from 'common/components/WorkInProgress/Training';
import { setIsLightboxOpen } from 'features/lightbox/store/lightboxSlice';
import { InvokeTabName } from 'features/ui/store/tabMap';
import { setActiveTab, togglePanels } from 'features/ui/store/uiSlice';
import { ReactNode, useMemo } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import {
MdDeviceHub,
MdFlashOn,
MdGridOn,
MdPhotoFilter,
MdPhotoLibrary,
MdTextFields,
} from 'react-icons/md';
import { MdDeviceHub, MdGridOn } from 'react-icons/md';
import { activeTabIndexSelector } from '../store/uiSelectors';
import ImageToImageWorkarea from 'features/ui/components/tabs/ImageToImage/ImageToImageWorkarea';
import TextToImageWorkarea from 'features/ui/components/tabs/TextToImage/TextToImageWorkarea';
import UnifiedCanvasWorkarea from 'features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasWorkarea';
import { useTranslation } from 'react-i18next';
import { ResourceKey } from 'i18next';
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
import NodeEditor from 'features/nodes/components/NodeEditor';
import LinearWorkarea from './tabs/Linear/LinearWorkarea';
import { FaImage } from 'react-icons/fa';
export interface InvokeTabInfo {
id: InvokeTabName;
@@ -45,38 +36,26 @@ const tabIconStyles: ChakraProps['sx'] = {
boxSize: 6,
};
const tabInfo: InvokeTabInfo[] = [
{
id: 'txt2img',
icon: <Icon as={MdTextFields} sx={tabIconStyles} />,
workarea: <TextToImageWorkarea />,
},
{
id: 'img2img',
icon: <Icon as={MdPhotoLibrary} sx={tabIconStyles} />,
workarea: <ImageToImageWorkarea />,
},
{
id: 'unifiedCanvas',
icon: <Icon as={MdGridOn} sx={tabIconStyles} />,
workarea: <UnifiedCanvasWorkarea />,
},
{
id: 'nodes',
icon: <Icon as={MdDeviceHub} sx={tabIconStyles} />,
workarea: <NodesWIP />,
},
{
id: 'postprocessing',
icon: <Icon as={MdPhotoFilter} sx={tabIconStyles} />,
workarea: <PostProcessingWIP />,
},
{
id: 'training',
icon: <Icon as={MdFlashOn} sx={tabIconStyles} />,
workarea: <TrainingWIP />,
},
];
const buildTabs = (disabledTabs: InvokeTabName[]): InvokeTabInfo[] => {
const tabs: InvokeTabInfo[] = [
{
id: 'linear',
icon: <Icon as={FaImage} sx={tabIconStyles} />,
workarea: <LinearWorkarea />,
},
{
id: 'unifiedCanvas',
icon: <Icon as={MdGridOn} sx={tabIconStyles} />,
workarea: <UnifiedCanvasWorkarea />,
},
{
id: 'nodes',
icon: <Icon as={MdDeviceHub} sx={tabIconStyles} />,
workarea: <NodeEditor />,
},
];
return tabs.filter((tab) => !disabledTabs.includes(tab.id));
};
export default function InvokeTabs() {
const activeTab = useAppSelector(activeTabIndexSelector);
@@ -85,13 +64,10 @@ export default function InvokeTabs() {
(state: RootState) => state.lightbox.isLightboxOpen
);
const shouldPinGallery = useAppSelector(
(state: RootState) => state.ui.shouldPinGallery
);
const { shouldPinGallery, disabledTabs, shouldPinParametersPanel } =
useAppSelector((state: RootState) => state.ui);
const shouldPinParametersPanel = useAppSelector(
(state: RootState) => state.ui.shouldPinParametersPanel
);
const activeTabs = buildTabs(disabledTabs);
const { t } = useTranslation();
@@ -109,18 +85,6 @@ export default function InvokeTabs() {
dispatch(setActiveTab(2));
});
useHotkeys('4', () => {
dispatch(setActiveTab(3));
});
useHotkeys('5', () => {
dispatch(setActiveTab(4));
});
useHotkeys('6', () => {
dispatch(setActiveTab(5));
});
// Lightbox Hotkey
useHotkeys(
'z',
@@ -142,7 +106,7 @@ export default function InvokeTabs() {
const tabs = useMemo(
() =>
tabInfo.map((tab) => (
activeTabs.map((tab) => (
<Tooltip
key={tab.id}
hasArrow
@@ -157,13 +121,13 @@ export default function InvokeTabs() {
</Tab>
</Tooltip>
)),
[t]
[t, activeTabs]
);
const tabPanels = useMemo(
() =>
tabInfo.map((tab) => <TabPanel key={tab.id}>{tab.workarea}</TabPanel>),
[]
activeTabs.map((tab) => <TabPanel key={tab.id}>{tab.workarea}</TabPanel>),
[activeTabs]
);
return (
@@ -174,8 +138,11 @@ export default function InvokeTabs() {
dispatch(setActiveTab(index));
}}
flexGrow={1}
isLazy
>
<TabList>{tabs}</TabList>
<TabList pt={2} gap={4}>
{tabs}
</TabList>
<TabPanels>{tabPanels}</TabPanels>
</Tabs>
);

View File

@@ -1,7 +1,7 @@
import { Box, BoxProps, Flex } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import { setInitialImage } from 'features/parameters/store/generationSlice';
import { initialImageSelected } from 'features/parameters/store/generationSlice';
import {
activeTabNameSelector,
uiSelector,
@@ -46,9 +46,7 @@ const InvokeWorkarea = (props: InvokeWorkareaProps) => {
const uuid = e.dataTransfer.getData('invokeai/imageUuid');
const image = getImageByUuid(uuid);
if (!image) return;
if (activeTabName === 'img2img') {
dispatch(setInitialImage(image));
} else if (activeTabName === 'unifiedCanvas') {
if (activeTabName === 'unifiedCanvas') {
dispatch(setInitialCanvasImage(image));
}
};

View File

@@ -96,7 +96,6 @@ const ParametersPanel = ({ children }: ParametersPanelProps) => {
onClose={closeParametersPanel}
isPinned={shouldPinParametersPanel || isLightboxOpen}
sx={{
borderColor: 'base.700',
p: shouldPinParametersPanel ? 0 : 4,
bg: 'base.900',
}}

View File

@@ -1,50 +0,0 @@
import { ChakraProps, Flex, Grid } from '@chakra-ui/react';
import { RootState } from 'app/store';
import { useAppSelector } from 'app/storeHooks';
import ImageUploadButton from 'common/components/ImageUploaderButton';
import CurrentImageDisplay from 'features/gallery/components/CurrentImageDisplay';
import InitImagePreview from './InitImagePreview';
const workareaSplitViewStyle: ChakraProps['sx'] = {
flexDirection: 'column',
height: '100%',
width: '100%',
gap: 4,
padding: 4,
};
const ImageToImageContent = () => {
const initialImage = useAppSelector(
(state: RootState) => state.generation.initialImage
);
const imageToImageComponent = initialImage ? (
<Flex flexDirection="column" gap={4} w="100%" h="100%">
<InitImagePreview />
</Flex>
) : (
<ImageUploadButton />
);
return (
<Grid
sx={{
w: '100%',
h: '100%',
gridTemplateColumns: '1fr 1fr',
borderRadius: 'base',
bg: 'base.850',
}}
>
<Flex sx={{ ...workareaSplitViewStyle, paddingInlineEnd: 2 }}>
{imageToImageComponent}
</Flex>
<Flex sx={{ ...workareaSplitViewStyle, paddingInlineStart: 2 }}>
<CurrentImageDisplay />
</Flex>
</Grid>
);
};
export default ImageToImageContent;

View File

@@ -1,81 +0,0 @@
import { Flex } from '@chakra-ui/react';
import { Feature } from 'app/features';
import FaceRestoreSettings from 'features/parameters/components/AdvancedParameters/FaceRestore/FaceRestoreSettings';
import FaceRestoreToggle from 'features/parameters/components/AdvancedParameters/FaceRestore/FaceRestoreToggle';
import ImageToImageOutputSettings from 'features/parameters/components/AdvancedParameters/Output/ImageToImageOutputSettings';
import SymmetrySettings from 'features/parameters/components/AdvancedParameters/Output/SymmetrySettings';
import SymmetryToggle from 'features/parameters/components/AdvancedParameters/Output/SymmetryToggle';
import SeedSettings from 'features/parameters/components/AdvancedParameters/Seed/SeedSettings';
import UpscaleSettings from 'features/parameters/components/AdvancedParameters/Upscale/UpscaleSettings';
import UpscaleToggle from 'features/parameters/components/AdvancedParameters/Upscale/UpscaleToggle';
import GenerateVariationsToggle from 'features/parameters/components/AdvancedParameters/Variations/GenerateVariations';
import VariationsSettings from 'features/parameters/components/AdvancedParameters/Variations/VariationsSettings';
import MainSettings from 'features/parameters/components/MainParameters/MainSettings';
import ParametersAccordion from 'features/parameters/components/ParametersAccordion';
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
import NegativePromptInput from 'features/parameters/components/PromptInput/NegativePromptInput';
import PromptInput from 'features/parameters/components/PromptInput/PromptInput';
import { useTranslation } from 'react-i18next';
import ImageToImageSettings from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageSettings';
import { memo } from 'react';
const ImageToImageParameters = () => {
const { t } = useTranslation();
const imageToImageAccordions = {
general: {
header: `${t('parameters.general')}`,
feature: undefined,
content: <MainSettings />,
},
imageToImage: {
header: `${t('parameters.imageToImage')}`,
feature: undefined,
content: <ImageToImageSettings />,
},
seed: {
header: `${t('parameters.seed')}`,
feature: Feature.SEED,
content: <SeedSettings />,
},
variations: {
header: `${t('parameters.variations')}`,
feature: Feature.VARIATIONS,
content: <VariationsSettings />,
additionalHeaderComponents: <GenerateVariationsToggle />,
},
face_restore: {
header: `${t('parameters.faceRestoration')}`,
feature: Feature.FACE_CORRECTION,
content: <FaceRestoreSettings />,
additionalHeaderComponents: <FaceRestoreToggle />,
},
upscale: {
header: `${t('parameters.upscaling')}`,
feature: Feature.UPSCALE,
content: <UpscaleSettings />,
additionalHeaderComponents: <UpscaleToggle />,
},
symmetry: {
header: `${t('parameters.symmetry')}`,
content: <SymmetrySettings />,
additionalHeaderComponents: <SymmetryToggle />,
},
other: {
header: `${t('parameters.otherOptions')}`,
feature: Feature.OTHER,
content: <ImageToImageOutputSettings />,
},
};
return (
<Flex flexDir="column" gap={2} position="relative">
<PromptInput />
<NegativePromptInput />
<ProcessButtons />
<ParametersAccordion accordionInfo={imageToImageAccordions} />
</Flex>
);
};
export default memo(ImageToImageParameters);

View File

@@ -1,11 +0,0 @@
import InvokeWorkarea from 'features/ui/components/InvokeWorkarea';
import ImageToImageContent from './ImageToImageContent';
import ImageToImageParameters from './ImageToImageParameters';
export default function ImageToImageWorkarea() {
return (
<InvokeWorkarea parametersPanelContent={<ImageToImageParameters />}>
<ImageToImageContent />
</InvokeWorkarea>
);
}

View File

@@ -1,85 +0,0 @@
import { Flex, Image, Text, useToast } from '@chakra-ui/react';
import { RootState } from 'app/store';
import { useAppDispatch, useAppSelector } from 'app/storeHooks';
import ImageUploaderIconButton from 'common/components/ImageUploaderIconButton';
import CurrentImageHidden from 'features/gallery/components/CurrentImageHidden';
import { clearInitialImage } from 'features/parameters/store/generationSlice';
import { useTranslation } from 'react-i18next';
export default function InitImagePreview() {
const initialImage = useAppSelector(
(state: RootState) => state.generation.initialImage
);
const { shouldHidePreview } = useAppSelector((state: RootState) => state.ui);
const { t } = useTranslation();
const dispatch = useAppDispatch();
const toast = useToast();
const alertMissingInitImage = () => {
toast({
title: t('toast.parametersFailed'),
description: t('toast.parametersFailedDesc'),
status: 'error',
isClosable: true,
});
dispatch(clearInitialImage());
};
return (
<>
<Flex
sx={{
alignItems: 'center',
justifyContent: 'center',
w: '100%',
gap: 4,
}}
>
<Text
sx={{
fontSize: 'lg',
}}
variant="subtext"
>
{t('parameters.initialImage')}
</Text>
<ImageUploaderIconButton />
</Flex>
{initialImage && (
<Flex
sx={{
position: 'relative',
height: '100%',
width: '100%',
alignItems: 'center',
justifyContent: 'center',
}}
>
<Image
sx={{
fit: 'contain',
maxWidth: '100%',
maxHeight: '100%',
borderRadius: 'base',
objectFit: 'contain',
position: 'absolute',
}}
src={
shouldHidePreview
? undefined
: typeof initialImage === 'string'
? initialImage
: initialImage.url
}
fallback={<CurrentImageHidden />}
onError={alertMissingInitImage}
/>
</Flex>
)}
</>
);
}

View File

@@ -1,7 +1,7 @@
import { Box, Flex } from '@chakra-ui/react';
import CurrentImageDisplay from 'features/gallery/components/CurrentImageDisplay';
const TextToImageContent = () => {
const LinearContent = () => {
return (
<Box
sx={{
@@ -18,4 +18,4 @@ const TextToImageContent = () => {
);
};
export default TextToImageContent;
export default LinearContent;

View File

@@ -1,61 +1,61 @@
import { Flex } from '@chakra-ui/react';
import { Feature } from 'app/features';
import FaceRestoreSettings from 'features/parameters/components/AdvancedParameters/FaceRestore/FaceRestoreSettings';
import FaceRestoreToggle from 'features/parameters/components/AdvancedParameters/FaceRestore/FaceRestoreToggle';
import ImageToImageSettings from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageSettings';
import ImageToImageToggle from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageToggle';
import OutputSettings from 'features/parameters/components/AdvancedParameters/Output/OutputSettings';
import SymmetrySettings from 'features/parameters/components/AdvancedParameters/Output/SymmetrySettings';
import SymmetryToggle from 'features/parameters/components/AdvancedParameters/Output/SymmetryToggle';
import SeedSettings from 'features/parameters/components/AdvancedParameters/Seed/SeedSettings';
import UpscaleSettings from 'features/parameters/components/AdvancedParameters/Upscale/UpscaleSettings';
import UpscaleToggle from 'features/parameters/components/AdvancedParameters/Upscale/UpscaleToggle';
import GenerateVariationsToggle from 'features/parameters/components/AdvancedParameters/Variations/GenerateVariations';
import VariationsSettings from 'features/parameters/components/AdvancedParameters/Variations/VariationsSettings';
import MainSettings from 'features/parameters/components/MainParameters/MainSettings';
import ParametersAccordion from 'features/parameters/components/ParametersAccordion';
import ParametersAccordion, {
ParametersAccordionItems,
} from 'features/parameters/components/ParametersAccordion';
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
import NegativePromptInput from 'features/parameters/components/PromptInput/NegativePromptInput';
import PromptInput from 'features/parameters/components/PromptInput/PromptInput';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
const TextToImageParameters = () => {
const LinearParameters = () => {
const { t } = useTranslation();
const textToImageAccordions = {
const linearAccordions: ParametersAccordionItems = {
general: {
name: 'general',
header: `${t('parameters.general')}`,
feature: undefined,
content: <MainSettings />,
},
seed: {
name: 'seed',
header: `${t('parameters.seed')}`,
feature: Feature.SEED,
content: <SeedSettings />,
},
imageToImage: {
name: 'imageToImage',
header: `${t('parameters.imageToImage')}`,
feature: undefined,
content: <ImageToImageSettings />,
additionalHeaderComponents: <ImageToImageToggle />,
},
variations: {
name: 'variations',
header: `${t('parameters.variations')}`,
feature: Feature.VARIATIONS,
content: <VariationsSettings />,
additionalHeaderComponents: <GenerateVariationsToggle />,
},
face_restore: {
header: `${t('parameters.faceRestoration')}`,
feature: Feature.FACE_CORRECTION,
content: <FaceRestoreSettings />,
additionalHeaderComponents: <FaceRestoreToggle />,
},
upscale: {
header: `${t('parameters.upscaling')}`,
feature: Feature.UPSCALE,
content: <UpscaleSettings />,
additionalHeaderComponents: <UpscaleToggle />,
},
symmetry: {
name: 'symmetry',
header: `${t('parameters.symmetry')}`,
content: <SymmetrySettings />,
additionalHeaderComponents: <SymmetryToggle />,
},
other: {
name: 'other',
header: `${t('parameters.otherOptions')}`,
feature: Feature.OTHER,
content: <OutputSettings />,
@@ -67,9 +67,9 @@ const TextToImageParameters = () => {
<PromptInput />
<NegativePromptInput />
<ProcessButtons />
<ParametersAccordion accordionInfo={textToImageAccordions} />
<ParametersAccordion accordionItems={linearAccordions} />
</Flex>
);
};
export default memo(TextToImageParameters);
export default memo(LinearParameters);

View File

@@ -0,0 +1,11 @@
import InvokeWorkarea from 'features/ui/components/InvokeWorkarea';
import LinearContent from './LinearContent';
import LinearParameters from './LinearParameters';
export default function LinearWorkarea() {
return (
<InvokeWorkarea parametersPanelContent={<LinearParameters />}>
<LinearContent />
</InvokeWorkarea>
);
}

View File

@@ -1,11 +0,0 @@
import InvokeWorkarea from 'features/ui/components/InvokeWorkarea';
import TextToImageContent from './TextToImageContent';
import TextToImageParameters from './TextToImageParameters';
export default function TextToImageWorkarea() {
return (
<InvokeWorkarea parametersPanelContent={<TextToImageParameters />}>
<TextToImageContent />
</InvokeWorkarea>
);
}

View File

@@ -10,7 +10,9 @@ import SeedSettings from 'features/parameters/components/AdvancedParameters/Seed
import GenerateVariationsToggle from 'features/parameters/components/AdvancedParameters/Variations/GenerateVariations';
import VariationsSettings from 'features/parameters/components/AdvancedParameters/Variations/VariationsSettings';
import MainSettings from 'features/parameters/components/MainParameters/MainSettings';
import ParametersAccordion from 'features/parameters/components/ParametersAccordion';
import ParametersAccordion, {
ParametersAccordionItems,
} from 'features/parameters/components/ParametersAccordion';
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
import NegativePromptInput from 'features/parameters/components/PromptInput/NegativePromptInput';
import PromptInput from 'features/parameters/components/PromptInput/PromptInput';
@@ -19,44 +21,52 @@ import { useTranslation } from 'react-i18next';
export default function UnifiedCanvasParameters() {
const { t } = useTranslation();
const unifiedCanvasAccordions = {
const unifiedCanvasAccordions: ParametersAccordionItems = {
general: {
name: 'general',
header: `${t('parameters.general')}`,
feature: undefined,
content: <MainSettings />,
},
unifiedCanvasImg2Img: {
name: 'unifiedCanvasImg2Img',
header: `${t('parameters.imageToImage')}`,
feature: undefined,
content: <ImageToImageStrength label={t('parameters.img2imgStrength')} />,
},
seed: {
name: 'seed',
header: `${t('parameters.seed')}`,
feature: Feature.SEED,
content: <SeedSettings />,
},
boundingBox: {
name: 'boundingBox',
header: `${t('parameters.boundingBoxHeader')}`,
feature: Feature.BOUNDING_BOX,
content: <BoundingBoxSettings />,
},
seamCorrection: {
name: 'seamCorrection',
header: `${t('parameters.seamCorrectionHeader')}`,
feature: Feature.SEAM_CORRECTION,
content: <SeamCorrectionSettings />,
},
infillAndScaling: {
name: 'infillAndScaling',
header: `${t('parameters.infillScalingHeader')}`,
feature: Feature.INFILL_AND_SCALING,
content: <InfillAndScalingSettings />,
},
variations: {
name: 'variations',
header: `${t('parameters.variations')}`,
feature: Feature.VARIATIONS,
content: <VariationsSettings />,
additionalHeaderComponents: <GenerateVariationsToggle />,
},
symmetry: {
name: 'symmetry',
header: `${t('parameters.symmetry')}`,
content: <SymmetrySettings />,
additionalHeaderComponents: <SymmetryToggle />,
@@ -68,7 +78,7 @@ export default function UnifiedCanvasParameters() {
<PromptInput />
<NegativePromptInput />
<ProcessButtons />
<ParametersAccordion accordionInfo={unifiedCanvasAccordions} />
<ParametersAccordion accordionItems={unifiedCanvasAccordions} />
</Flex>
);
}