mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): revert tabs to txt2img/img2img
This commit is contained in:
parent
33c69359c2
commit
c4b3a24ed7
@ -9,7 +9,7 @@ import FloatingGalleryButton from 'features/ui/components/FloatingGalleryButton'
|
|||||||
import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons';
|
import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons';
|
||||||
import { Box, Flex, Grid, Portal, useColorMode } from '@chakra-ui/react';
|
import { Box, Flex, Grid, Portal, useColorMode } from '@chakra-ui/react';
|
||||||
import { APP_HEIGHT, APP_WIDTH } from 'theme/util/constants';
|
import { APP_HEIGHT, APP_WIDTH } from 'theme/util/constants';
|
||||||
import ImageGalleryPanel from 'features/gallery/components/ImageGalleryPanel';
|
import GalleryDrawer from 'features/gallery/components/ImageGalleryPanel';
|
||||||
import Lightbox from 'features/lightbox/components/Lightbox';
|
import Lightbox from 'features/lightbox/components/Lightbox';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import {
|
import {
|
||||||
@ -28,9 +28,7 @@ import { configChanged } from 'features/system/store/configSlice';
|
|||||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
import { useLogger } from 'app/logging/useLogger';
|
import { useLogger } from 'app/logging/useLogger';
|
||||||
import ProgressImagePreview from 'features/parameters/components/ProgressImagePreview';
|
import ProgressImagePreview from 'features/parameters/components/ProgressImagePreview';
|
||||||
import ResizableDrawer from 'features/ui/components/common/ResizableDrawer/ResizableDrawer';
|
import ParametersDrawer from 'features/ui/components/ParametersDrawer';
|
||||||
import ImageGalleryContent from 'features/gallery/components/ImageGalleryContent';
|
|
||||||
import CreateParametersDrawer from 'features/ui/components/CreateParametersDrawer';
|
|
||||||
|
|
||||||
const DEFAULT_CONFIG = {};
|
const DEFAULT_CONFIG = {};
|
||||||
|
|
||||||
@ -91,8 +89,8 @@ const App = ({ config = DEFAULT_CONFIG, children }: Props) => {
|
|||||||
</Grid>
|
</Grid>
|
||||||
</ImageUploader>
|
</ImageUploader>
|
||||||
|
|
||||||
<ImageGalleryPanel />
|
<GalleryDrawer />
|
||||||
<CreateParametersDrawer />
|
<ParametersDrawer />
|
||||||
|
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{!isApplicationReady && !loadingOverridden && (
|
{!isApplicationReady && !loadingOverridden && (
|
||||||
|
@ -12,8 +12,9 @@ import { addImageResultReceivedListener } from './listeners/invocationComplete';
|
|||||||
import { addImageUploadedListener } from './listeners/imageUploaded';
|
import { addImageUploadedListener } from './listeners/imageUploaded';
|
||||||
import { addRequestedImageDeletionListener } from './listeners/imageDeleted';
|
import { addRequestedImageDeletionListener } from './listeners/imageDeleted';
|
||||||
import { addUserInvokedCanvasListener } from './listeners/userInvokedCanvas';
|
import { addUserInvokedCanvasListener } from './listeners/userInvokedCanvas';
|
||||||
import { addUserInvokedCreateListener } from './listeners/userInvokedCreate';
|
|
||||||
import { addUserInvokedNodesListener } from './listeners/userInvokedNodes';
|
import { addUserInvokedNodesListener } from './listeners/userInvokedNodes';
|
||||||
|
import { addUserInvokedTextToImageListener } from './listeners/userInvokedTextToImage';
|
||||||
|
import { addUserInvokedImageToImageListener } from './listeners/userInvokedImageToImage';
|
||||||
|
|
||||||
export const listenerMiddleware = createListenerMiddleware();
|
export const listenerMiddleware = createListenerMiddleware();
|
||||||
|
|
||||||
@ -39,5 +40,6 @@ addImageResultReceivedListener();
|
|||||||
addRequestedImageDeletionListener();
|
addRequestedImageDeletionListener();
|
||||||
|
|
||||||
addUserInvokedCanvasListener();
|
addUserInvokedCanvasListener();
|
||||||
addUserInvokedCreateListener();
|
|
||||||
addUserInvokedNodesListener();
|
addUserInvokedNodesListener();
|
||||||
|
addUserInvokedTextToImageListener();
|
||||||
|
addUserInvokedImageToImageListener();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
import { sessionCreated, sessionInvoked } from 'services/thunks/session';
|
import { sessionCreated, sessionInvoked } from 'services/thunks/session';
|
||||||
import { buildCanvasGraphAndBlobs } from 'features/nodes/util/buildCanvasGraph';
|
import { buildCanvasGraphAndBlobs } from 'features/nodes/util/graphBuilders/buildCanvasGraph';
|
||||||
import { log } from 'app/logging/useLogger';
|
import { log } from 'app/logging/useLogger';
|
||||||
import { canvasGraphBuilt } from 'features/nodes/store/actions';
|
import { canvasGraphBuilt } from 'features/nodes/store/actions';
|
||||||
import { imageUploaded } from 'services/thunks/image';
|
import { imageUploaded } from 'services/thunks/image';
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
import { startAppListening } from '..';
|
||||||
|
import { buildImageToImageGraph } from 'features/nodes/util/graphBuilders/buildImageToImageGraph';
|
||||||
|
import { sessionCreated } from 'services/thunks/session';
|
||||||
|
import { log } from 'app/logging/useLogger';
|
||||||
|
import { imageToImageGraphBuilt } from 'features/nodes/store/actions';
|
||||||
|
import { userInvoked } from 'app/store/actions';
|
||||||
|
|
||||||
|
const moduleLog = log.child({ namespace: 'invoke' });
|
||||||
|
|
||||||
|
export const addUserInvokedImageToImageListener = () => {
|
||||||
|
startAppListening({
|
||||||
|
predicate: (action): action is ReturnType<typeof userInvoked> =>
|
||||||
|
userInvoked.match(action) && action.payload === 'image',
|
||||||
|
effect: (action, { getState, dispatch }) => {
|
||||||
|
const state = getState();
|
||||||
|
|
||||||
|
const graph = buildImageToImageGraph(state);
|
||||||
|
dispatch(imageToImageGraphBuilt(graph));
|
||||||
|
moduleLog({ data: graph }, 'Image to Image graph built');
|
||||||
|
|
||||||
|
dispatch(sessionCreated({ graph }));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
@ -1,6 +1,6 @@
|
|||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
import { sessionCreated } from 'services/thunks/session';
|
import { sessionCreated } from 'services/thunks/session';
|
||||||
import { buildNodesGraph } from 'features/nodes/util/buildNodesGraph';
|
import { buildNodesGraph } from 'features/nodes/util/graphBuilders/buildNodesGraph';
|
||||||
import { log } from 'app/logging/useLogger';
|
import { log } from 'app/logging/useLogger';
|
||||||
import { nodesGraphBuilt } from 'features/nodes/store/actions';
|
import { nodesGraphBuilt } from 'features/nodes/store/actions';
|
||||||
import { userInvoked } from 'app/store/actions';
|
import { userInvoked } from 'app/store/actions';
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
import { startAppListening } from '..';
|
import { startAppListening } from '..';
|
||||||
import { buildLinearGraph } from 'features/nodes/util/buildLinearGraph';
|
import { buildTextToImageGraph } from 'features/nodes/util/graphBuilders/buildTextToImageGraph';
|
||||||
import { sessionCreated } from 'services/thunks/session';
|
import { sessionCreated } from 'services/thunks/session';
|
||||||
import { log } from 'app/logging/useLogger';
|
import { log } from 'app/logging/useLogger';
|
||||||
import { createGraphBuilt } from 'features/nodes/store/actions';
|
import { textToImageGraphBuilt } from 'features/nodes/store/actions';
|
||||||
import { userInvoked } from 'app/store/actions';
|
import { userInvoked } from 'app/store/actions';
|
||||||
|
|
||||||
const moduleLog = log.child({ namespace: 'invoke' });
|
const moduleLog = log.child({ namespace: 'invoke' });
|
||||||
|
|
||||||
export const addUserInvokedCreateListener = () => {
|
export const addUserInvokedTextToImageListener = () => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
predicate: (action): action is ReturnType<typeof userInvoked> =>
|
predicate: (action): action is ReturnType<typeof userInvoked> =>
|
||||||
userInvoked.match(action) && action.payload === 'text',
|
userInvoked.match(action) && action.payload === 'text',
|
||||||
effect: (action, { getState, dispatch }) => {
|
effect: (action, { getState, dispatch }) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
|
|
||||||
const graph = buildLinearGraph(state);
|
const graph = buildTextToImageGraph(state);
|
||||||
dispatch(createGraphBuilt(graph));
|
dispatch(textToImageGraphBuilt(graph));
|
||||||
moduleLog({ data: graph }, 'Create graph built');
|
moduleLog({ data: graph }, 'Text to Image graph built');
|
||||||
|
|
||||||
dispatch(sessionCreated({ graph }));
|
dispatch(sessionCreated({ graph }));
|
||||||
},
|
},
|
@ -7,7 +7,7 @@ import { useAppDispatch } from 'app/store/storeHooks';
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { clearInitialImage } from 'features/parameters/store/generationSlice';
|
import { clearInitialImage } from 'features/parameters/store/generationSlice';
|
||||||
|
|
||||||
const ImagePromptHeading = () => {
|
const InitialImageButtons = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@ -38,4 +38,4 @@ const ImagePromptHeading = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ImagePromptHeading;
|
export default InitialImageButtons;
|
@ -7,7 +7,7 @@ const SelectImagePlaceholder = () => {
|
|||||||
sx={{
|
sx={{
|
||||||
w: 'full',
|
w: 'full',
|
||||||
h: 'full',
|
h: 'full',
|
||||||
bg: 'base.800',
|
// bg: 'base.800',
|
||||||
borderRadius: 'base',
|
borderRadius: 'base',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
|
@ -3,6 +3,7 @@ import { RootState } from 'app/store/store';
|
|||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { shiftKeyPressed } from 'features/ui/store/hotkeysSlice';
|
import { shiftKeyPressed } from 'features/ui/store/hotkeysSlice';
|
||||||
import {
|
import {
|
||||||
|
setActiveTab,
|
||||||
toggleGalleryPanel,
|
toggleGalleryPanel,
|
||||||
toggleParametersPanel,
|
toggleParametersPanel,
|
||||||
togglePinGalleryPanel,
|
togglePinGalleryPanel,
|
||||||
@ -58,4 +59,20 @@ export const useGlobalHotkeys = () => {
|
|||||||
useHotkeys(['shift+g'], () => {
|
useHotkeys(['shift+g'], () => {
|
||||||
dispatch(togglePinGalleryPanel());
|
dispatch(togglePinGalleryPanel());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useHotkeys('1', () => {
|
||||||
|
dispatch(setActiveTab('text'));
|
||||||
|
});
|
||||||
|
|
||||||
|
useHotkeys('2', () => {
|
||||||
|
dispatch(setActiveTab('image'));
|
||||||
|
});
|
||||||
|
|
||||||
|
useHotkeys('3', () => {
|
||||||
|
dispatch(setActiveTab('unifiedCanvas'));
|
||||||
|
});
|
||||||
|
|
||||||
|
useHotkeys('4', () => {
|
||||||
|
dispatch(setActiveTab('nodes'));
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
@ -441,13 +441,13 @@ const CurrentImageButtons = (props: CurrentImageButtonsProps) => {
|
|||||||
{t('parameters.sendToUnifiedCanvas')}
|
{t('parameters.sendToUnifiedCanvas')}
|
||||||
</IAIButton>
|
</IAIButton>
|
||||||
|
|
||||||
<IAIButton
|
{/* <IAIButton
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={handleCopyImage}
|
onClick={handleCopyImage}
|
||||||
leftIcon={<FaCopy />}
|
leftIcon={<FaCopy />}
|
||||||
>
|
>
|
||||||
{t('parameters.copyImage')}
|
{t('parameters.copyImage')}
|
||||||
</IAIButton>
|
</IAIButton> */}
|
||||||
<IAIButton
|
<IAIButton
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={handleCopyImageLink}
|
onClick={handleCopyImageLink}
|
||||||
|
@ -30,18 +30,18 @@ import useResolution from 'common/hooks/useResolution';
|
|||||||
import { Flex } from '@chakra-ui/react';
|
import { Flex } from '@chakra-ui/react';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
const GALLERY_TAB_WIDTHS: Record<
|
// const GALLERY_TAB_WIDTHS: Record<
|
||||||
InvokeTabName,
|
// InvokeTabName,
|
||||||
{ galleryMinWidth: number; galleryMaxWidth: number }
|
// { galleryMinWidth: number; galleryMaxWidth: number }
|
||||||
> = {
|
// > = {
|
||||||
// txt2img: { galleryMinWidth: 200, galleryMaxWidth: 500 },
|
// txt2img: { galleryMinWidth: 200, galleryMaxWidth: 500 },
|
||||||
// img2img: { galleryMinWidth: 200, galleryMaxWidth: 500 },
|
// img2img: { galleryMinWidth: 200, galleryMaxWidth: 500 },
|
||||||
generate: { galleryMinWidth: 200, galleryMaxWidth: 500 },
|
// generate: { galleryMinWidth: 200, galleryMaxWidth: 500 },
|
||||||
unifiedCanvas: { galleryMinWidth: 200, galleryMaxWidth: 200 },
|
// unifiedCanvas: { galleryMinWidth: 200, galleryMaxWidth: 200 },
|
||||||
nodes: { galleryMinWidth: 200, galleryMaxWidth: 500 },
|
// nodes: { galleryMinWidth: 200, galleryMaxWidth: 500 },
|
||||||
// postprocessing: { galleryMinWidth: 200, galleryMaxWidth: 500 },
|
// postprocessing: { galleryMinWidth: 200, galleryMaxWidth: 500 },
|
||||||
// training: { galleryMinWidth: 200, galleryMaxWidth: 500 },
|
// training: { galleryMinWidth: 200, galleryMaxWidth: 500 },
|
||||||
};
|
// };
|
||||||
|
|
||||||
const galleryPanelSelector = createSelector(
|
const galleryPanelSelector = createSelector(
|
||||||
[
|
[
|
||||||
@ -73,34 +73,34 @@ const galleryPanelSelector = createSelector(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const ImageGalleryPanel = () => {
|
const GalleryDrawer = () => {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const {
|
const {
|
||||||
shouldPinGallery,
|
shouldPinGallery,
|
||||||
shouldShowGallery,
|
shouldShowGallery,
|
||||||
galleryImageMinimumWidth,
|
galleryImageMinimumWidth,
|
||||||
activeTabName,
|
// activeTabName,
|
||||||
isStaging,
|
// isStaging,
|
||||||
isResizable,
|
// isResizable,
|
||||||
isLightboxOpen,
|
// isLightboxOpen,
|
||||||
} = useAppSelector(galleryPanelSelector);
|
} = useAppSelector(galleryPanelSelector);
|
||||||
|
|
||||||
const handleSetShouldPinGallery = () => {
|
// const handleSetShouldPinGallery = () => {
|
||||||
dispatch(togglePinGalleryPanel());
|
// dispatch(togglePinGalleryPanel());
|
||||||
dispatch(requestCanvasRescale());
|
// dispatch(requestCanvasRescale());
|
||||||
};
|
// };
|
||||||
|
|
||||||
const handleToggleGallery = () => {
|
// const handleToggleGallery = () => {
|
||||||
dispatch(toggleGalleryPanel());
|
// dispatch(toggleGalleryPanel());
|
||||||
shouldPinGallery && dispatch(requestCanvasRescale());
|
// shouldPinGallery && dispatch(requestCanvasRescale());
|
||||||
};
|
// };
|
||||||
|
|
||||||
const handleCloseGallery = () => {
|
const handleCloseGallery = () => {
|
||||||
dispatch(setShouldShowGallery(false));
|
dispatch(setShouldShowGallery(false));
|
||||||
shouldPinGallery && dispatch(requestCanvasRescale());
|
shouldPinGallery && dispatch(requestCanvasRescale());
|
||||||
};
|
};
|
||||||
|
|
||||||
const resolution = useResolution();
|
// const resolution = useResolution();
|
||||||
|
|
||||||
// useHotkeys(
|
// useHotkeys(
|
||||||
// 'g',
|
// 'g',
|
||||||
@ -229,4 +229,4 @@ const ImageGalleryPanel = () => {
|
|||||||
// return renderImageGallery();
|
// return renderImageGallery();
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(ImageGalleryPanel);
|
export default memo(GalleryDrawer);
|
||||||
|
@ -2,7 +2,7 @@ import { Box } from '@chakra-ui/react';
|
|||||||
import { RootState } from 'app/store/store';
|
import { RootState } from 'app/store/store';
|
||||||
import { useAppSelector } from 'app/store/storeHooks';
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { buildNodesGraph } from '../util/buildNodesGraph';
|
import { buildNodesGraph } from '../util/graphBuilders/buildNodesGraph';
|
||||||
|
|
||||||
const NodeGraphOverlay = () => {
|
const NodeGraphOverlay = () => {
|
||||||
const state = useAppSelector((state: RootState) => state);
|
const state = useAppSelector((state: RootState) => state);
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
import { createAction, isAnyOf } from '@reduxjs/toolkit';
|
import { createAction, isAnyOf } from '@reduxjs/toolkit';
|
||||||
import { Graph } from 'services/api';
|
import { Graph } from 'services/api';
|
||||||
|
|
||||||
export const createGraphBuilt = createAction<Graph>('nodes/createGraphBuilt');
|
export const textToImageGraphBuilt = createAction<Graph>(
|
||||||
|
'nodes/textToImageGraphBuilt'
|
||||||
|
);
|
||||||
|
export const imageToImageGraphBuilt = createAction<Graph>(
|
||||||
|
'nodes/imageToImageGraphBuilt'
|
||||||
|
);
|
||||||
export const canvasGraphBuilt = createAction<Graph>('nodes/canvasGraphBuilt');
|
export const canvasGraphBuilt = createAction<Graph>('nodes/canvasGraphBuilt');
|
||||||
export const nodesGraphBuilt = createAction<Graph>('nodes/nodesGraphBuilt');
|
export const nodesGraphBuilt = createAction<Graph>('nodes/nodesGraphBuilt');
|
||||||
|
|
||||||
export const isAnyGraphBuilt = isAnyOf(
|
export const isAnyGraphBuilt = isAnyOf(
|
||||||
createGraphBuilt,
|
textToImageGraphBuilt,
|
||||||
|
imageToImageGraphBuilt,
|
||||||
canvasGraphBuilt,
|
canvasGraphBuilt,
|
||||||
nodesGraphBuilt
|
nodesGraphBuilt
|
||||||
);
|
);
|
||||||
|
@ -10,17 +10,17 @@ import {
|
|||||||
RangeInvocation,
|
RangeInvocation,
|
||||||
TextToImageInvocation,
|
TextToImageInvocation,
|
||||||
} from 'services/api';
|
} from 'services/api';
|
||||||
import { buildImg2ImgNode } from './linearGraphBuilder/buildImageToImageNode';
|
import { buildImg2ImgNode } from '../nodeBuilders/buildImageToImageNode';
|
||||||
import { buildTxt2ImgNode } from './linearGraphBuilder/buildTextToImageNode';
|
import { buildTxt2ImgNode } from '../nodeBuilders/buildTextToImageNode';
|
||||||
import { buildRangeNode } from './linearGraphBuilder/buildRangeNode';
|
import { buildRangeNode } from '../nodeBuilders/buildRangeNode';
|
||||||
import { buildIterateNode } from './linearGraphBuilder/buildIterateNode';
|
import { buildIterateNode } from '../nodeBuilders/buildIterateNode';
|
||||||
import { buildEdges } from './linearGraphBuilder/buildEdges';
|
import { buildEdges } from '../edgeBuilders/buildEdges';
|
||||||
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
|
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
|
||||||
import { getCanvasData } from 'features/canvas/util/getCanvasData';
|
import { getCanvasData } from 'features/canvas/util/getCanvasData';
|
||||||
import { getGenerationMode } from './getGenerationMode';
|
import { getGenerationMode } from '../getGenerationMode';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import { log } from 'app/logging/useLogger';
|
import { log } from 'app/logging/useLogger';
|
||||||
import { buildInpaintNode } from './linearGraphBuilder/buildInpaintNode';
|
import { buildInpaintNode } from '../nodeBuilders/buildInpaintNode';
|
||||||
|
|
||||||
const moduleLog = log.child({ namespace: 'buildCanvasGraph' });
|
const moduleLog = log.child({ namespace: 'buildCanvasGraph' });
|
||||||
|
|
@ -1,19 +1,15 @@
|
|||||||
import { RootState } from 'app/store/store';
|
import { RootState } from 'app/store/store';
|
||||||
import { Graph } from 'services/api';
|
import { Graph } from 'services/api';
|
||||||
import { buildImg2ImgNode } from './linearGraphBuilder/buildImageToImageNode';
|
import { buildImg2ImgNode } from '../nodeBuilders/buildImageToImageNode';
|
||||||
import { buildTxt2ImgNode } from './linearGraphBuilder/buildTextToImageNode';
|
import { buildRangeNode } from '../nodeBuilders/buildRangeNode';
|
||||||
import { buildRangeNode } from './linearGraphBuilder/buildRangeNode';
|
import { buildIterateNode } from '../nodeBuilders/buildIterateNode';
|
||||||
import { buildIterateNode } from './linearGraphBuilder/buildIterateNode';
|
import { buildEdges } from '../edgeBuilders/buildEdges';
|
||||||
import { buildEdges } from './linearGraphBuilder/buildEdges';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the Linear workflow graph.
|
* Builds the Linear workflow graph.
|
||||||
*/
|
*/
|
||||||
export const buildLinearGraph = (state: RootState): Graph => {
|
export const buildImageToImageGraph = (state: RootState): Graph => {
|
||||||
// The base node is either a txt2img or img2img node
|
const baseNode = buildImg2ImgNode(state);
|
||||||
const baseNode = state.generation.isImageToImageEnabled
|
|
||||||
? buildImg2ImgNode(state)
|
|
||||||
: buildTxt2ImgNode(state);
|
|
||||||
|
|
||||||
// We always range and iterate nodes, no matter the iteration count
|
// We always range and iterate nodes, no matter the iteration count
|
||||||
// This is required to provide the correct seeds to the backend engine
|
// This is required to provide the correct seeds to the backend engine
|
@ -2,7 +2,7 @@ import { Graph } from 'services/api';
|
|||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import { cloneDeep, reduce } from 'lodash-es';
|
import { cloneDeep, reduce } from 'lodash-es';
|
||||||
import { RootState } from 'app/store/store';
|
import { RootState } from 'app/store/store';
|
||||||
import { InputFieldValue } from '../types/types';
|
import { InputFieldValue } from 'features/nodes/types/types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We need to do special handling for some fields
|
* We need to do special handling for some fields
|
@ -0,0 +1,35 @@
|
|||||||
|
import { RootState } from 'app/store/store';
|
||||||
|
import { Graph } from 'services/api';
|
||||||
|
import { buildTxt2ImgNode } from '../nodeBuilders/buildTextToImageNode';
|
||||||
|
import { buildRangeNode } from '../nodeBuilders/buildRangeNode';
|
||||||
|
import { buildIterateNode } from '../nodeBuilders/buildIterateNode';
|
||||||
|
import { buildEdges } from '../edgeBuilders/buildEdges';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the Linear workflow graph.
|
||||||
|
*/
|
||||||
|
export const buildTextToImageGraph = (state: RootState): Graph => {
|
||||||
|
const baseNode = buildTxt2ImgNode(state);
|
||||||
|
|
||||||
|
// We always range and iterate nodes, no matter the iteration count
|
||||||
|
// This is required to provide the correct seeds to the backend engine
|
||||||
|
const rangeNode = buildRangeNode(state);
|
||||||
|
const iterateNode = buildIterateNode();
|
||||||
|
|
||||||
|
// Build the edges for the nodes selected.
|
||||||
|
const edges = buildEdges(baseNode, rangeNode, iterateNode);
|
||||||
|
|
||||||
|
// Assemble!
|
||||||
|
const graph = {
|
||||||
|
nodes: {
|
||||||
|
[rangeNode.id]: rangeNode,
|
||||||
|
[iterateNode.id]: iterateNode,
|
||||||
|
[baseNode.id]: baseNode,
|
||||||
|
},
|
||||||
|
edges,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: hires fix requires latent space upscaling; we don't have nodes for this yet
|
||||||
|
|
||||||
|
return graph;
|
||||||
|
};
|
@ -15,8 +15,6 @@ export const buildImg2ImgNode = (
|
|||||||
const nodeId = uuidv4();
|
const nodeId = uuidv4();
|
||||||
const { generation, system, models } = state;
|
const { generation, system, models } = state;
|
||||||
|
|
||||||
const { selectedModelName } = models;
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
prompt,
|
prompt,
|
||||||
negativePrompt,
|
negativePrompt,
|
||||||
@ -26,10 +24,13 @@ export const buildImg2ImgNode = (
|
|||||||
height,
|
height,
|
||||||
cfgScale,
|
cfgScale,
|
||||||
sampler,
|
sampler,
|
||||||
seamless,
|
model,
|
||||||
img2imgStrength: strength,
|
img2imgStrength: strength,
|
||||||
shouldFitToWidthHeight: fit,
|
shouldFitToWidthHeight: fit,
|
||||||
shouldRandomizeSeed,
|
shouldRandomizeSeed,
|
||||||
|
shouldUseSeamless,
|
||||||
|
seamlessXAxis,
|
||||||
|
seamlessYAxis,
|
||||||
} = generation;
|
} = generation;
|
||||||
|
|
||||||
const initialImage = initialImageSelector(state);
|
const initialImage = initialImageSelector(state);
|
||||||
@ -48,9 +49,7 @@ export const buildImg2ImgNode = (
|
|||||||
height,
|
height,
|
||||||
cfg_scale: cfgScale,
|
cfg_scale: cfgScale,
|
||||||
scheduler: sampler as ImageToImageInvocation['scheduler'],
|
scheduler: sampler as ImageToImageInvocation['scheduler'],
|
||||||
seamless,
|
model,
|
||||||
model: selectedModelName,
|
|
||||||
progress_images: true,
|
|
||||||
image: initialImage
|
image: initialImage
|
||||||
? {
|
? {
|
||||||
image_name: initialImage.name,
|
image_name: initialImage.name,
|
@ -10,8 +10,6 @@ export const buildTxt2ImgNode = (
|
|||||||
const nodeId = uuidv4();
|
const nodeId = uuidv4();
|
||||||
const { generation, models } = state;
|
const { generation, models } = state;
|
||||||
|
|
||||||
const { selectedModelName } = models;
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
prompt,
|
prompt,
|
||||||
negativePrompt,
|
negativePrompt,
|
||||||
@ -21,8 +19,8 @@ export const buildTxt2ImgNode = (
|
|||||||
height,
|
height,
|
||||||
cfgScale: cfg_scale,
|
cfgScale: cfg_scale,
|
||||||
sampler,
|
sampler,
|
||||||
seamless,
|
|
||||||
shouldRandomizeSeed,
|
shouldRandomizeSeed,
|
||||||
|
model,
|
||||||
} = generation;
|
} = generation;
|
||||||
|
|
||||||
const textToImageNode: NonNullable<TextToImageInvocation> = {
|
const textToImageNode: NonNullable<TextToImageInvocation> = {
|
||||||
@ -34,9 +32,7 @@ export const buildTxt2ImgNode = (
|
|||||||
height,
|
height,
|
||||||
cfg_scale,
|
cfg_scale,
|
||||||
scheduler: sampler as TextToImageInvocation['scheduler'],
|
scheduler: sampler as TextToImageInvocation['scheduler'],
|
||||||
seamless,
|
model,
|
||||||
model: selectedModelName,
|
|
||||||
progress_images: true,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!shouldRandomizeSeed) {
|
if (!shouldRandomizeSeed) {
|
@ -5,7 +5,7 @@ import { setShouldFitToWidthHeight } from 'features/parameters/store/generationS
|
|||||||
import { ChangeEvent } from 'react';
|
import { ChangeEvent } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export default function ImageFit() {
|
export default function ImageToImageFit() {
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const shouldFitToWidthHeight = useAppSelector(
|
const shouldFitToWidthHeight = useAppSelector(
|
@ -13,7 +13,7 @@ import {
|
|||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
|
|
||||||
import IAIButton from 'common/components/IAIButton';
|
import IAIButton from 'common/components/IAIButton';
|
||||||
import ImageFit from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageFit';
|
import ImageToImageFit from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageFit';
|
||||||
import ImageToImageStrength from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageStrength';
|
import ImageToImageStrength from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageStrength';
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
import IAIIconButton from 'common/components/IAIIconButton';
|
||||||
|
|
||||||
@ -21,16 +21,16 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import InitialImagePreview from './InitialImagePreview';
|
import InitialImagePreview from './InitialImagePreview';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { FaUndo, FaUpload } from 'react-icons/fa';
|
import { FaUndo, FaUpload } from 'react-icons/fa';
|
||||||
import ImagePromptHeading from 'common/components/ImageToImageSettingsHeader';
|
import InitialImageButtons from 'common/components/ImageToImageSettingsHeader';
|
||||||
|
|
||||||
export default function ImageToImageSettings() {
|
export default function ImageToImageSettings() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<VStack gap={2} w="full" alignItems="stretch">
|
<VStack gap={2} w="full" alignItems="stretch">
|
||||||
<ImagePromptHeading />
|
<InitialImageButtons />
|
||||||
<InitialImagePreview />
|
<InitialImagePreview />
|
||||||
<ImageToImageStrength />
|
<ImageToImageStrength />
|
||||||
<ImageFit />
|
<ImageToImageFit />
|
||||||
</VStack>
|
</VStack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
import { Flex } from '@chakra-ui/react';
|
||||||
|
import InitialImagePreview from './InitialImagePreview';
|
||||||
|
import InitialImageButtons from 'common/components/ImageToImageButtons';
|
||||||
|
|
||||||
|
const InitialImageDisplay = () => {
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
sx={{
|
||||||
|
position: 'relative',
|
||||||
|
flexDirection: 'column',
|
||||||
|
height: '100%',
|
||||||
|
width: '100%',
|
||||||
|
rowGap: 4,
|
||||||
|
borderRadius: 'base',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Flex
|
||||||
|
flexDirection="column"
|
||||||
|
sx={{
|
||||||
|
w: 'full',
|
||||||
|
h: 'full',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
gap: 4,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<InitialImageButtons />
|
||||||
|
<InitialImagePreview />
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default InitialImageDisplay;
|
@ -71,6 +71,7 @@ const InitialImagePreview = () => {
|
|||||||
<Flex
|
<Flex
|
||||||
sx={{
|
sx={{
|
||||||
width: 'full',
|
width: 'full',
|
||||||
|
height: 'full',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
@ -115,7 +116,7 @@ const InitialImagePreview = () => {
|
|||||||
)}
|
)}
|
||||||
{!initialImage?.url && <SelectImagePlaceholder />}
|
{!initialImage?.url && <SelectImagePlaceholder />}
|
||||||
</Flex>
|
</Flex>
|
||||||
{!isImageToImageEnabled && (
|
{/* {!isImageToImageEnabled && (
|
||||||
<Flex
|
<Flex
|
||||||
sx={{
|
sx={{
|
||||||
w: 'full',
|
w: 'full',
|
||||||
@ -134,7 +135,7 @@ const InitialImagePreview = () => {
|
|||||||
Image to Image is Disabled
|
Image to Image is Disabled
|
||||||
</Text>
|
</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)} */}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -7,9 +7,6 @@ import { memo } from 'react';
|
|||||||
import { ParamHiresStrength } from './ParamHiresStrength';
|
import { ParamHiresStrength } from './ParamHiresStrength';
|
||||||
import { setHiresFix } from 'features/parameters/store/postprocessingSlice';
|
import { setHiresFix } from 'features/parameters/store/postprocessingSlice';
|
||||||
|
|
||||||
/**
|
|
||||||
* Seed & variation options. Includes iteration, seed, seed randomization, variation options.
|
|
||||||
*/
|
|
||||||
const ParamHiresCollapse = () => {
|
const ParamHiresCollapse = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const hiresFix = useAppSelector(
|
const hiresFix = useAppSelector(
|
||||||
|
@ -61,12 +61,12 @@ export const modelsSlice = createSlice({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const selectedModelSelector = (state: RootState) => {
|
// export const selectedModelSelector = (state: RootState) => {
|
||||||
const { selectedModelName } = state.models;
|
// const { selectedModelName } = state.models;
|
||||||
const selectedModel = selectModelsById(state, selectedModelName);
|
// const selectedModel = selectModelsById(state, selectedModelName);
|
||||||
|
|
||||||
return selectedModel ?? null;
|
// return selectedModel ?? null;
|
||||||
};
|
// };
|
||||||
|
|
||||||
export const {
|
export const {
|
||||||
selectAll: selectModelsAll,
|
selectAll: selectModelsAll,
|
||||||
|
@ -1,115 +0,0 @@
|
|||||||
import { isEqual } from 'lodash-es';
|
|
||||||
import ResizableDrawer from './common/ResizableDrawer/ResizableDrawer';
|
|
||||||
import TextTabParameters from './tabs/text/TextTabParameters';
|
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
|
||||||
import { activeTabNameSelector, uiSelector } from '../store/uiSelectors';
|
|
||||||
import { lightboxSelector } from 'features/lightbox/store/lightboxSelectors';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
|
||||||
import {
|
|
||||||
setShouldShowParametersPanel,
|
|
||||||
toggleParametersPanel,
|
|
||||||
} from '../store/uiSlice';
|
|
||||||
import { memo } from 'react';
|
|
||||||
import { Flex } from '@chakra-ui/react';
|
|
||||||
import InvokeAILogoComponent from 'features/system/components/InvokeAILogoComponent';
|
|
||||||
import PinParametersPanelButton from './PinParametersPanelButton';
|
|
||||||
import { Panel, PanelGroup } from 'react-resizable-panels';
|
|
||||||
import CreateSidePanelPinned from './tabs/text/TextTabSettingsPinned';
|
|
||||||
import CreateTextParameters from './tabs/text/TextTabParameters';
|
|
||||||
import ResizeHandle from './tabs/ResizeHandle';
|
|
||||||
import CreateImageSettings from './tabs/image/ImageTabSettings';
|
|
||||||
|
|
||||||
const selector = createSelector(
|
|
||||||
[uiSelector, activeTabNameSelector, lightboxSelector],
|
|
||||||
(ui, activeTabName, lightbox) => {
|
|
||||||
const {
|
|
||||||
shouldPinParametersPanel,
|
|
||||||
shouldShowParametersPanel,
|
|
||||||
shouldShowImageParameters,
|
|
||||||
} = ui;
|
|
||||||
const { isLightboxOpen } = lightbox;
|
|
||||||
|
|
||||||
return {
|
|
||||||
shouldPinParametersPanel,
|
|
||||||
shouldShowParametersPanel,
|
|
||||||
shouldShowImageParameters,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{
|
|
||||||
memoizeOptions: {
|
|
||||||
resultEqualityCheck: isEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const CreateParametersPanel = () => {
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const {
|
|
||||||
shouldPinParametersPanel,
|
|
||||||
shouldShowParametersPanel,
|
|
||||||
shouldShowImageParameters,
|
|
||||||
} = useAppSelector(selector);
|
|
||||||
|
|
||||||
const handleClosePanel = () => {
|
|
||||||
dispatch(setShouldShowParametersPanel(false));
|
|
||||||
};
|
|
||||||
|
|
||||||
if (shouldPinParametersPanel) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ResizableDrawer
|
|
||||||
direction="left"
|
|
||||||
isResizable={true}
|
|
||||||
isOpen={shouldShowParametersPanel}
|
|
||||||
onClose={handleClosePanel}
|
|
||||||
minWidth={500}
|
|
||||||
>
|
|
||||||
<Flex flexDir="column" position="relative" h="full" w="full">
|
|
||||||
<Flex
|
|
||||||
paddingTop={1.5}
|
|
||||||
paddingBottom={4}
|
|
||||||
justifyContent="space-between"
|
|
||||||
alignItems="center"
|
|
||||||
>
|
|
||||||
<InvokeAILogoComponent />
|
|
||||||
<PinParametersPanelButton />
|
|
||||||
</Flex>
|
|
||||||
<PanelGroup
|
|
||||||
autoSaveId="createTab_floatingParameters"
|
|
||||||
direction="horizontal"
|
|
||||||
style={{ height: '100%', width: '100%' }}
|
|
||||||
>
|
|
||||||
<>
|
|
||||||
<Panel
|
|
||||||
id="createTab_textParameters"
|
|
||||||
order={0}
|
|
||||||
defaultSize={25}
|
|
||||||
minSize={25}
|
|
||||||
style={{ position: 'relative' }}
|
|
||||||
>
|
|
||||||
<CreateTextParameters />
|
|
||||||
</Panel>
|
|
||||||
{shouldShowImageParameters && (
|
|
||||||
<>
|
|
||||||
<ResizeHandle />
|
|
||||||
<Panel
|
|
||||||
id="createTab_imageParameters"
|
|
||||||
order={1}
|
|
||||||
defaultSize={25}
|
|
||||||
minSize={25}
|
|
||||||
style={{ position: 'relative' }}
|
|
||||||
>
|
|
||||||
<CreateImageSettings />
|
|
||||||
</Panel>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
</PanelGroup>
|
|
||||||
</Flex>
|
|
||||||
</ResizableDrawer>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default memo(CreateParametersPanel);
|
|
@ -33,7 +33,6 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { ResourceKey } from 'i18next';
|
import { ResourceKey } from 'i18next';
|
||||||
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
|
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
|
||||||
import NodeEditor from 'features/nodes/components/NodeEditor';
|
import NodeEditor from 'features/nodes/components/NodeEditor';
|
||||||
import GenerateWorkspace from './tabs/text/GenerateWorkspace';
|
|
||||||
import { createSelector } from '@reduxjs/toolkit';
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
import { BsLightningChargeFill } from 'react-icons/bs';
|
import { BsLightningChargeFill } from 'react-icons/bs';
|
||||||
import { configSelector } from 'features/system/store/configSelectors';
|
import { configSelector } from 'features/system/store/configSelectors';
|
||||||
@ -43,7 +42,7 @@ import Scrollable from './common/Scrollable';
|
|||||||
import TextTabParameters from './tabs/text/TextTabParameters';
|
import TextTabParameters from './tabs/text/TextTabParameters';
|
||||||
import PinParametersPanelButton from './PinParametersPanelButton';
|
import PinParametersPanelButton from './PinParametersPanelButton';
|
||||||
import ParametersSlide from './common/ParametersSlide';
|
import ParametersSlide from './common/ParametersSlide';
|
||||||
import ImageGalleryPanel from 'features/gallery/components/ImageGalleryPanel';
|
import GalleryDrawer from 'features/gallery/components/ImageGalleryPanel';
|
||||||
import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
|
import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
|
||||||
import ImageGalleryContent from 'features/gallery/components/ImageGalleryContent';
|
import ImageGalleryContent from 'features/gallery/components/ImageGalleryContent';
|
||||||
import TextTabMain from './tabs/text/TextTabMain';
|
import TextTabMain from './tabs/text/TextTabMain';
|
||||||
@ -54,6 +53,7 @@ import UnifiedCanvasTab from './tabs/UnifiedCanvas/UnifiedCanvasTab';
|
|||||||
import NodesTab from './tabs/Nodes/NodesTab';
|
import NodesTab from './tabs/Nodes/NodesTab';
|
||||||
import { FaImage } from 'react-icons/fa';
|
import { FaImage } from 'react-icons/fa';
|
||||||
import ResizeHandle from './tabs/ResizeHandle';
|
import ResizeHandle from './tabs/ResizeHandle';
|
||||||
|
import ImageTab from './tabs/image/ImageTab';
|
||||||
|
|
||||||
export interface InvokeTabInfo {
|
export interface InvokeTabInfo {
|
||||||
id: InvokeTabName;
|
id: InvokeTabName;
|
||||||
@ -70,7 +70,7 @@ const tabs: InvokeTabInfo[] = [
|
|||||||
{
|
{
|
||||||
id: 'image',
|
id: 'image',
|
||||||
icon: <Icon as={FaImage} sx={{ boxSize: 5 }} />,
|
icon: <Icon as={FaImage} sx={{ boxSize: 5 }} />,
|
||||||
content: <TextTab />,
|
content: <ImageTab />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'unifiedCanvas',
|
id: 'unifiedCanvas',
|
||||||
@ -114,22 +114,6 @@ const InvokeTabs = () => {
|
|||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
useHotkeys('1', () => {
|
|
||||||
dispatch(setActiveTab('text'));
|
|
||||||
});
|
|
||||||
|
|
||||||
useHotkeys('2', () => {
|
|
||||||
dispatch(setActiveTab('image'));
|
|
||||||
});
|
|
||||||
|
|
||||||
useHotkeys('3', () => {
|
|
||||||
dispatch(setActiveTab('unifiedCanvas'));
|
|
||||||
});
|
|
||||||
|
|
||||||
useHotkeys('4', () => {
|
|
||||||
dispatch(setActiveTab('nodes'));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Lightbox Hotkey
|
// Lightbox Hotkey
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
'z',
|
'z',
|
||||||
@ -200,7 +184,7 @@ const InvokeTabs = () => {
|
|||||||
direction="horizontal"
|
direction="horizontal"
|
||||||
style={{ height: '100%', width: '100%' }}
|
style={{ height: '100%', width: '100%' }}
|
||||||
>
|
>
|
||||||
<Panel id="tabContent">
|
<Panel id="main">
|
||||||
<TabPanels style={{ height: '100%', width: '100%' }}>
|
<TabPanels style={{ height: '100%', width: '100%' }}>
|
||||||
{tabPanels}
|
{tabPanels}
|
||||||
</TabPanels>
|
</TabPanels>
|
||||||
@ -208,7 +192,13 @@ const InvokeTabs = () => {
|
|||||||
{shouldPinGallery && shouldShowGallery && (
|
{shouldPinGallery && shouldShowGallery && (
|
||||||
<>
|
<>
|
||||||
<ResizeHandle />
|
<ResizeHandle />
|
||||||
<Panel id="gallery" order={3} defaultSize={10} minSize={10}>
|
<Panel
|
||||||
|
id="gallery"
|
||||||
|
order={3}
|
||||||
|
defaultSize={10}
|
||||||
|
minSize={10}
|
||||||
|
maxSize={50}
|
||||||
|
>
|
||||||
<ImageGalleryContent />
|
<ImageGalleryContent />
|
||||||
</Panel>
|
</Panel>
|
||||||
</>
|
</>
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { activeTabNameSelector } from '../store/uiSelectors';
|
||||||
|
import TextTabParametersDrawer from './tabs/text/TextTabParametersDrawer';
|
||||||
|
import { RootState } from 'app/store/store';
|
||||||
|
|
||||||
|
const ParametersDrawer = () => {
|
||||||
|
const activeTabName = useAppSelector(activeTabNameSelector);
|
||||||
|
const shouldPinParametersPanel = useAppSelector(
|
||||||
|
(state: RootState) => state.ui.shouldPinParametersPanel
|
||||||
|
);
|
||||||
|
|
||||||
|
if (shouldPinParametersPanel) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeTabName === 'text') {
|
||||||
|
return <TextTabParametersDrawer />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeTabName === 'image') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeTabName === 'unifiedCanvas') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(ParametersDrawer);
|
@ -7,6 +7,11 @@ import { uiSelector } from 'features/ui/store/uiSelectors';
|
|||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
|
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
|
||||||
import ResizeHandle from '../ResizeHandle';
|
import ResizeHandle from '../ResizeHandle';
|
||||||
|
import ImageTabParameters from './ImageTabParameters';
|
||||||
|
import ImageTabImageParameters from './ImageTabImageParameters';
|
||||||
|
import TextTabMain from '../text/TextTabMain';
|
||||||
|
import InitialImagePreview from 'features/parameters/components/AdvancedParameters/ImageToImage/InitialImagePreview';
|
||||||
|
import InitialImageDisplay from 'features/parameters/components/AdvancedParameters/ImageToImage/InitialImageDisplay';
|
||||||
|
|
||||||
const selector = createSelector(uiSelector, (ui) => {
|
const selector = createSelector(uiSelector, (ui) => {
|
||||||
const {
|
const {
|
||||||
@ -38,20 +43,20 @@ const TextTab = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<PanelGroup
|
<PanelGroup
|
||||||
autoSaveId="textTab"
|
autoSaveId="imageTab"
|
||||||
direction="horizontal"
|
direction="horizontal"
|
||||||
style={{ height: '100%', width: '100%' }}
|
style={{ height: '100%', width: '100%' }}
|
||||||
>
|
>
|
||||||
{shouldPinParametersPanel && shouldShowParametersPanel && (
|
{shouldPinParametersPanel && shouldShowParametersPanel && (
|
||||||
<>
|
<>
|
||||||
<Panel
|
<Panel
|
||||||
id="textTab_settings"
|
id="imageTab_parameters"
|
||||||
order={0}
|
order={0}
|
||||||
defaultSize={25}
|
defaultSize={25}
|
||||||
minSize={25}
|
minSize={25}
|
||||||
style={{ position: 'relative' }}
|
style={{ position: 'relative' }}
|
||||||
>
|
>
|
||||||
{/* <TextTabSettings /> */}
|
<ImageTabParameters />
|
||||||
<PinParametersPanelButton
|
<PinParametersPanelButton
|
||||||
sx={{ position: 'absolute', top: 0, insetInlineEnd: 0 }}
|
sx={{ position: 'absolute', top: 0, insetInlineEnd: 0 }}
|
||||||
/>
|
/>
|
||||||
@ -59,15 +64,34 @@ const TextTab = () => {
|
|||||||
<ResizeHandle />
|
<ResizeHandle />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<Panel
|
<Panel id="imageTab_content" order={1}>
|
||||||
id="textTab_main"
|
<PanelGroup
|
||||||
order={2}
|
autoSaveId="imageTab_contentWrapper"
|
||||||
minSize={30}
|
direction="horizontal"
|
||||||
onResize={() => {
|
style={{ height: '100%', width: '100%' }}
|
||||||
dispatch(requestCanvasRescale());
|
>
|
||||||
}}
|
<Panel
|
||||||
>
|
id="imageTab_initImage"
|
||||||
{/* <TextTabMain /> */}
|
order={0}
|
||||||
|
defaultSize={50}
|
||||||
|
minSize={25}
|
||||||
|
style={{ position: 'relative' }}
|
||||||
|
>
|
||||||
|
<InitialImageDisplay />
|
||||||
|
</Panel>
|
||||||
|
<ResizeHandle />
|
||||||
|
<Panel
|
||||||
|
id="imageTab_selectedImage"
|
||||||
|
order={1}
|
||||||
|
defaultSize={50}
|
||||||
|
minSize={25}
|
||||||
|
onResize={() => {
|
||||||
|
dispatch(requestCanvasRescale());
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextTabMain />
|
||||||
|
</Panel>
|
||||||
|
</PanelGroup>
|
||||||
</Panel>
|
</Panel>
|
||||||
</PanelGroup>
|
</PanelGroup>
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
import { Box, Flex } from '@chakra-ui/react';
|
||||||
|
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import OverlayScrollable from '../../common/OverlayScrollable';
|
||||||
|
import ParamPositiveConditioning from 'features/parameters/components/Parameters/ParamPositiveConditioning';
|
||||||
|
import ParamNegativeConditioning from 'features/parameters/components/Parameters/ParamNegativeConditioning';
|
||||||
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
|
import { uiSelector } from 'features/ui/store/uiSelectors';
|
||||||
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
import ParamIterations from 'features/parameters/components/Parameters/ParamIterations';
|
||||||
|
import ParamSteps from 'features/parameters/components/Parameters/ParamSteps';
|
||||||
|
import ParamCFGScale from 'features/parameters/components/Parameters/ParamCFGScale';
|
||||||
|
import ParamWidth from 'features/parameters/components/Parameters/ParamWidth';
|
||||||
|
import ParamHeight from 'features/parameters/components/Parameters/ParamHeight';
|
||||||
|
import ParamScheduler from 'features/parameters/components/Parameters/ParamScheduler';
|
||||||
|
import ModelSelect from 'features/system/components/ModelSelect';
|
||||||
|
import ParamSeedCollapse from 'features/parameters/components/Parameters/Seed/ParamSeedCollapse';
|
||||||
|
import ParamVariationCollapse from 'features/parameters/components/Parameters/Variations/ParamVariationCollapse';
|
||||||
|
import ParamNoiseCollapse from 'features/parameters/components/Parameters/Noise/ParamNoiseCollapse';
|
||||||
|
import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse';
|
||||||
|
import ParamHiresCollapse from 'features/parameters/components/Parameters/Hires/ParamHiresCollapse';
|
||||||
|
import ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse';
|
||||||
|
import InitialImagePreview from 'features/parameters/components/AdvancedParameters/ImageToImage/InitialImagePreview';
|
||||||
|
import ImageToImageStrength from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageStrength';
|
||||||
|
import ImageToImageFit from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageFit';
|
||||||
|
import InitialImageButtons from 'common/components/ImageToImageButtons';
|
||||||
|
|
||||||
|
const selector = createSelector(
|
||||||
|
uiSelector,
|
||||||
|
(ui) => {
|
||||||
|
const { shouldUseSliders } = ui;
|
||||||
|
|
||||||
|
return { shouldUseSliders };
|
||||||
|
},
|
||||||
|
defaultSelectorOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
const ImageTabParameters = () => {
|
||||||
|
const { shouldUseSliders } = useAppSelector(selector);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<OverlayScrollable>
|
||||||
|
<Flex
|
||||||
|
sx={{
|
||||||
|
gap: 2,
|
||||||
|
flexDirection: 'column',
|
||||||
|
h: 'full',
|
||||||
|
w: 'full',
|
||||||
|
position: 'absolute',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<InitialImageButtons />
|
||||||
|
<InitialImagePreview />
|
||||||
|
<ImageToImageFit />
|
||||||
|
</Flex>
|
||||||
|
</OverlayScrollable>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(ImageTabParameters);
|
@ -0,0 +1,113 @@
|
|||||||
|
import { Box, Flex } from '@chakra-ui/react';
|
||||||
|
import ProcessButtons from 'features/parameters/components/ProcessButtons/ProcessButtons';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import OverlayScrollable from '../../common/OverlayScrollable';
|
||||||
|
import ParamPositiveConditioning from 'features/parameters/components/Parameters/ParamPositiveConditioning';
|
||||||
|
import ParamNegativeConditioning from 'features/parameters/components/Parameters/ParamNegativeConditioning';
|
||||||
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
|
import { uiSelector } from 'features/ui/store/uiSelectors';
|
||||||
|
import { useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
||||||
|
import ParamIterations from 'features/parameters/components/Parameters/ParamIterations';
|
||||||
|
import ParamSteps from 'features/parameters/components/Parameters/ParamSteps';
|
||||||
|
import ParamCFGScale from 'features/parameters/components/Parameters/ParamCFGScale';
|
||||||
|
import ParamWidth from 'features/parameters/components/Parameters/ParamWidth';
|
||||||
|
import ParamHeight from 'features/parameters/components/Parameters/ParamHeight';
|
||||||
|
import ParamScheduler from 'features/parameters/components/Parameters/ParamScheduler';
|
||||||
|
import ModelSelect from 'features/system/components/ModelSelect';
|
||||||
|
import ParamSeedCollapse from 'features/parameters/components/Parameters/Seed/ParamSeedCollapse';
|
||||||
|
import ParamVariationCollapse from 'features/parameters/components/Parameters/Variations/ParamVariationCollapse';
|
||||||
|
import ParamNoiseCollapse from 'features/parameters/components/Parameters/Noise/ParamNoiseCollapse';
|
||||||
|
import ParamSymmetryCollapse from 'features/parameters/components/Parameters/Symmetry/ParamSymmetryCollapse';
|
||||||
|
import ParamHiresCollapse from 'features/parameters/components/Parameters/Hires/ParamHiresCollapse';
|
||||||
|
import ParamSeamlessCollapse from 'features/parameters/components/Parameters/Seamless/ParamSeamlessCollapse';
|
||||||
|
import ImageToImageStrength from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageStrength';
|
||||||
|
import ImageToImageFit from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageFit';
|
||||||
|
|
||||||
|
const selector = createSelector(
|
||||||
|
uiSelector,
|
||||||
|
(ui) => {
|
||||||
|
const { shouldUseSliders } = ui;
|
||||||
|
|
||||||
|
return { shouldUseSliders };
|
||||||
|
},
|
||||||
|
defaultSelectorOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
const ImageTabParameters = () => {
|
||||||
|
const { shouldUseSliders } = useAppSelector(selector);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<OverlayScrollable>
|
||||||
|
<Flex
|
||||||
|
sx={{
|
||||||
|
gap: 2,
|
||||||
|
flexDirection: 'column',
|
||||||
|
h: 'full',
|
||||||
|
w: 'full',
|
||||||
|
position: 'absolute',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ParamPositiveConditioning />
|
||||||
|
<ParamNegativeConditioning />
|
||||||
|
<ProcessButtons />
|
||||||
|
<Flex
|
||||||
|
sx={{
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: 2,
|
||||||
|
bg: 'base.800',
|
||||||
|
p: 4,
|
||||||
|
borderRadius: 'base',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{shouldUseSliders ? (
|
||||||
|
<Flex sx={{ gap: 3, flexDirection: 'column' }}>
|
||||||
|
<ParamIterations />
|
||||||
|
<ParamSteps />
|
||||||
|
<ParamCFGScale />
|
||||||
|
<ParamWidth />
|
||||||
|
<ParamHeight />
|
||||||
|
<ImageToImageStrength />
|
||||||
|
<ImageToImageFit />
|
||||||
|
<Flex gap={3} w="full">
|
||||||
|
<Box flexGrow={2}>
|
||||||
|
<ParamScheduler />
|
||||||
|
</Box>
|
||||||
|
<Box flexGrow={3}>
|
||||||
|
<ModelSelect />
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
) : (
|
||||||
|
<Flex sx={{ gap: 2, flexDirection: 'column' }}>
|
||||||
|
<Flex gap={3}>
|
||||||
|
<ParamIterations />
|
||||||
|
<ParamSteps />
|
||||||
|
<ParamCFGScale />
|
||||||
|
</Flex>
|
||||||
|
<ParamWidth />
|
||||||
|
<ParamHeight />
|
||||||
|
<Flex gap={3} w="full">
|
||||||
|
<Box flexGrow={2}>
|
||||||
|
<ParamScheduler />
|
||||||
|
</Box>
|
||||||
|
<Box flexGrow={3}>
|
||||||
|
<ModelSelect />
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
<ImageToImageStrength />
|
||||||
|
<ImageToImageFit />
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
<ParamSeedCollapse />
|
||||||
|
<ParamVariationCollapse />
|
||||||
|
<ParamNoiseCollapse />
|
||||||
|
<ParamSymmetryCollapse />
|
||||||
|
<ParamSeamlessCollapse />
|
||||||
|
</Flex>
|
||||||
|
</OverlayScrollable>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(ImageTabParameters);
|
@ -1,53 +0,0 @@
|
|||||||
import { memo } from 'react';
|
|
||||||
import OverlayScrollable from '../../common/OverlayScrollable';
|
|
||||||
import ImageToImageSettings from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageSettings';
|
|
||||||
import {
|
|
||||||
Box,
|
|
||||||
ButtonGroup,
|
|
||||||
Collapse,
|
|
||||||
Flex,
|
|
||||||
Heading,
|
|
||||||
HStack,
|
|
||||||
Image,
|
|
||||||
Spacer,
|
|
||||||
useDisclosure,
|
|
||||||
VStack,
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { motion } from 'framer-motion';
|
|
||||||
|
|
||||||
import IAIButton from 'common/components/IAIButton';
|
|
||||||
import ImageFit from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageFit';
|
|
||||||
import ImageToImageStrength from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageStrength';
|
|
||||||
import IAIIconButton from 'common/components/IAIIconButton';
|
|
||||||
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import { FaUndo, FaUpload } from 'react-icons/fa';
|
|
||||||
import ImagePromptHeading from 'common/components/ImageToImageSettingsHeader';
|
|
||||||
import InitialImagePreview from 'features/parameters/components/AdvancedParameters/ImageToImage/InitialImagePreview';
|
|
||||||
|
|
||||||
const CreateImageSettings = () => {
|
|
||||||
return (
|
|
||||||
<OverlayScrollable>
|
|
||||||
<Flex
|
|
||||||
sx={{
|
|
||||||
gap: 2,
|
|
||||||
flexDirection: 'column',
|
|
||||||
h: 'full',
|
|
||||||
w: 'full',
|
|
||||||
position: 'absolute',
|
|
||||||
borderRadius: 'base',
|
|
||||||
// bg: 'base.850',
|
|
||||||
// p: 2,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ImagePromptHeading />
|
|
||||||
<InitialImagePreview />
|
|
||||||
<ImageToImageStrength />
|
|
||||||
<ImageFit />
|
|
||||||
</Flex>
|
|
||||||
</OverlayScrollable>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default memo(CreateImageSettings);
|
|
@ -8,7 +8,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
|||||||
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
|
import { requestCanvasRescale } from 'features/canvas/store/thunks/requestCanvasScale';
|
||||||
import TextTabMain from './TextTabMain';
|
import TextTabMain from './TextTabMain';
|
||||||
import ResizeHandle from '../ResizeHandle';
|
import ResizeHandle from '../ResizeHandle';
|
||||||
import TextTabSettings from './TextTabParameters';
|
import TextTabParameters from './TextTabParameters';
|
||||||
|
|
||||||
const selector = createSelector(uiSelector, (ui) => {
|
const selector = createSelector(uiSelector, (ui) => {
|
||||||
const {
|
const {
|
||||||
@ -47,13 +47,13 @@ const TextTab = () => {
|
|||||||
{shouldPinParametersPanel && shouldShowParametersPanel && (
|
{shouldPinParametersPanel && shouldShowParametersPanel && (
|
||||||
<>
|
<>
|
||||||
<Panel
|
<Panel
|
||||||
id="textTab_settings"
|
id="textTab_parameters"
|
||||||
order={0}
|
order={0}
|
||||||
defaultSize={25}
|
defaultSize={25}
|
||||||
minSize={25}
|
minSize={25}
|
||||||
style={{ position: 'relative' }}
|
style={{ position: 'relative' }}
|
||||||
>
|
>
|
||||||
<TextTabSettings />
|
<TextTabParameters />
|
||||||
<PinParametersPanelButton
|
<PinParametersPanelButton
|
||||||
sx={{ position: 'absolute', top: 0, insetInlineEnd: 0 }}
|
sx={{ position: 'absolute', top: 0, insetInlineEnd: 0 }}
|
||||||
/>
|
/>
|
||||||
@ -61,14 +61,7 @@ const TextTab = () => {
|
|||||||
<ResizeHandle />
|
<ResizeHandle />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<Panel
|
<Panel id="textTab_content" order={2} minSize={30}>
|
||||||
id="textTab_main"
|
|
||||||
order={2}
|
|
||||||
minSize={30}
|
|
||||||
onResize={() => {
|
|
||||||
dispatch(requestCanvasRescale());
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TextTabMain />
|
<TextTabMain />
|
||||||
</Panel>
|
</Panel>
|
||||||
</PanelGroup>
|
</PanelGroup>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Box, Flex } from '@chakra-ui/react';
|
import { Box, Flex } from '@chakra-ui/react';
|
||||||
import CurrentImageDisplay from 'features/gallery/components/CurrentImageDisplay';
|
import CurrentImageDisplay from 'features/gallery/components/CurrentImageDisplay';
|
||||||
import ProgressImagePreview from 'features/parameters/components/ProgressImagePreview';
|
|
||||||
|
|
||||||
const TextTabMain = () => {
|
const TextTabMain = () => {
|
||||||
return (
|
return (
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
import { isEqual } from 'lodash-es';
|
||||||
|
import ResizableDrawer from '../../common/ResizableDrawer/ResizableDrawer';
|
||||||
|
import TextTabParameters from './TextTabParameters';
|
||||||
|
import { createSelector } from '@reduxjs/toolkit';
|
||||||
|
import { activeTabNameSelector, uiSelector } from '../../../store/uiSelectors';
|
||||||
|
import { lightboxSelector } from 'features/lightbox/store/lightboxSelectors';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
|
import { setShouldShowParametersPanel } from '../../../store/uiSlice';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { Flex } from '@chakra-ui/react';
|
||||||
|
import InvokeAILogoComponent from 'features/system/components/InvokeAILogoComponent';
|
||||||
|
import PinParametersPanelButton from '../../PinParametersPanelButton';
|
||||||
|
import { Panel, PanelGroup } from 'react-resizable-panels';
|
||||||
|
|
||||||
|
const selector = createSelector(
|
||||||
|
[uiSelector, activeTabNameSelector, lightboxSelector],
|
||||||
|
(ui, activeTabName, lightbox) => {
|
||||||
|
const {
|
||||||
|
shouldPinParametersPanel,
|
||||||
|
shouldShowParametersPanel,
|
||||||
|
shouldShowImageParameters,
|
||||||
|
} = ui;
|
||||||
|
|
||||||
|
const { isLightboxOpen } = lightbox;
|
||||||
|
|
||||||
|
return {
|
||||||
|
activeTabName,
|
||||||
|
shouldPinParametersPanel,
|
||||||
|
shouldShowParametersPanel,
|
||||||
|
shouldShowImageParameters,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
memoizeOptions: {
|
||||||
|
resultEqualityCheck: isEqual,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const TextTabParametersDrawer = () => {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const { shouldPinParametersPanel, shouldShowParametersPanel } =
|
||||||
|
useAppSelector(selector);
|
||||||
|
|
||||||
|
const handleClosePanel = () => {
|
||||||
|
dispatch(setShouldShowParametersPanel(false));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ResizableDrawer
|
||||||
|
direction="left"
|
||||||
|
isResizable={true}
|
||||||
|
isOpen={shouldShowParametersPanel}
|
||||||
|
onClose={handleClosePanel}
|
||||||
|
minWidth={500}
|
||||||
|
>
|
||||||
|
<Flex flexDir="column" position="relative" h="full" w="full">
|
||||||
|
<Flex
|
||||||
|
paddingTop={1.5}
|
||||||
|
paddingBottom={4}
|
||||||
|
justifyContent="space-between"
|
||||||
|
alignItems="center"
|
||||||
|
>
|
||||||
|
<InvokeAILogoComponent />
|
||||||
|
<PinParametersPanelButton />
|
||||||
|
</Flex>
|
||||||
|
<TextTabParameters />
|
||||||
|
</Flex>
|
||||||
|
</ResizableDrawer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(TextTabParametersDrawer);
|
@ -1,69 +0,0 @@
|
|||||||
import { createSelector } from '@reduxjs/toolkit';
|
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
|
||||||
import { uiSelector } from 'features/ui/store/uiSelectors';
|
|
||||||
import { memo } from 'react';
|
|
||||||
import { Panel } from 'react-resizable-panels';
|
|
||||||
import CreateTextParameters from './TextTabParameters';
|
|
||||||
import PinParametersPanelButton from '../../PinParametersPanelButton';
|
|
||||||
import ResizeHandle from '../ResizeHandle';
|
|
||||||
import ImageToImageSettings from 'features/parameters/components/AdvancedParameters/ImageToImage/ImageToImageSettings';
|
|
||||||
import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
|
|
||||||
import CreateImageSettings from '../image/ImageTabSettings';
|
|
||||||
|
|
||||||
const selector = createSelector(
|
|
||||||
uiSelector,
|
|
||||||
(ui) => {
|
|
||||||
const {
|
|
||||||
shouldPinParametersPanel,
|
|
||||||
shouldShowParametersPanel,
|
|
||||||
shouldShowImageParameters,
|
|
||||||
} = ui;
|
|
||||||
|
|
||||||
return {
|
|
||||||
shouldPinParametersPanel,
|
|
||||||
shouldShowParametersPanel,
|
|
||||||
shouldShowImageParameters,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
defaultSelectorOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
const CreateSidePanelPinned = () => {
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const {
|
|
||||||
shouldPinParametersPanel,
|
|
||||||
shouldShowParametersPanel,
|
|
||||||
shouldShowImageParameters,
|
|
||||||
} = useAppSelector(selector);
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Panel
|
|
||||||
order={0}
|
|
||||||
defaultSize={25}
|
|
||||||
minSize={25}
|
|
||||||
style={{ position: 'relative' }}
|
|
||||||
>
|
|
||||||
<CreateTextParameters />
|
|
||||||
<PinParametersPanelButton
|
|
||||||
sx={{ position: 'absolute', top: 0, insetInlineEnd: 0 }}
|
|
||||||
/>
|
|
||||||
</Panel>
|
|
||||||
{shouldShowImageParameters && (
|
|
||||||
<>
|
|
||||||
<ResizeHandle />
|
|
||||||
<Panel
|
|
||||||
order={1}
|
|
||||||
defaultSize={25}
|
|
||||||
minSize={25}
|
|
||||||
style={{ position: 'relative' }}
|
|
||||||
>
|
|
||||||
<CreateImageSettings />
|
|
||||||
</Panel>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
<ResizeHandle />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default memo(CreateSidePanelPinned);
|
|
@ -24,7 +24,8 @@
|
|||||||
"src/**/*.ts",
|
"src/**/*.ts",
|
||||||
"src/**/*.tsx",
|
"src/**/*.tsx",
|
||||||
"*.d.ts",
|
"*.d.ts",
|
||||||
"src/app/store/middleware/listenerMiddleware"
|
"src/app/store/middleware/listenerMiddleware",
|
||||||
|
"src/features/nodes/util/edgeBuilders"
|
||||||
],
|
],
|
||||||
"exclude": ["src/services/fixtures/*", "node_modules", "dist"],
|
"exclude": ["src/services/fixtures/*", "node_modules", "dist"],
|
||||||
"references": [{ "path": "./tsconfig.node.json" }]
|
"references": [{ "path": "./tsconfig.node.json" }]
|
||||||
|
Loading…
Reference in New Issue
Block a user