mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): rename tab identifiers
- "txt2img" -> "generation" - "unifiedCanvas" -> "canvas" - "modelManager" -> "models" - "nodes" -> "workflows" - Add UI slice migration setting the active tab to "generation"
This commit is contained in:
parent
7c1f1076b4
commit
0f7fdabe9b
@ -20,8 +20,7 @@ export type LoggerNamespace =
|
|||||||
| 'models'
|
| 'models'
|
||||||
| 'config'
|
| 'config'
|
||||||
| 'canvas'
|
| 'canvas'
|
||||||
| 'txt2img'
|
| 'generation'
|
||||||
| 'img2img'
|
|
||||||
| 'nodes'
|
| 'nodes'
|
||||||
| 'system'
|
| 'system'
|
||||||
| 'socketio'
|
| 'socketio'
|
||||||
|
@ -30,7 +30,7 @@ import type { ImageDTO } from 'services/api/types';
|
|||||||
export const addEnqueueRequestedCanvasListener = (startAppListening: AppStartListening) => {
|
export const addEnqueueRequestedCanvasListener = (startAppListening: AppStartListening) => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
predicate: (action): action is ReturnType<typeof enqueueRequested> =>
|
predicate: (action): action is ReturnType<typeof enqueueRequested> =>
|
||||||
enqueueRequested.match(action) && action.payload.tabName === 'unifiedCanvas',
|
enqueueRequested.match(action) && action.payload.tabName === 'canvas',
|
||||||
effect: async (action, { getState, dispatch }) => {
|
effect: async (action, { getState, dispatch }) => {
|
||||||
const log = logger('queue');
|
const log = logger('queue');
|
||||||
const { prepend } = action.payload;
|
const { prepend } = action.payload;
|
||||||
|
@ -8,7 +8,7 @@ import { queueApi } from 'services/api/endpoints/queue';
|
|||||||
export const addEnqueueRequestedLinear = (startAppListening: AppStartListening) => {
|
export const addEnqueueRequestedLinear = (startAppListening: AppStartListening) => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
predicate: (action): action is ReturnType<typeof enqueueRequested> =>
|
predicate: (action): action is ReturnType<typeof enqueueRequested> =>
|
||||||
enqueueRequested.match(action) && action.payload.tabName === 'txt2img',
|
enqueueRequested.match(action) && action.payload.tabName === 'generation',
|
||||||
effect: async (action, { getState, dispatch }) => {
|
effect: async (action, { getState, dispatch }) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const model = state.generation.model;
|
const model = state.generation.model;
|
||||||
|
@ -8,7 +8,7 @@ import type { BatchConfig } from 'services/api/types';
|
|||||||
export const addEnqueueRequestedNodes = (startAppListening: AppStartListening) => {
|
export const addEnqueueRequestedNodes = (startAppListening: AppStartListening) => {
|
||||||
startAppListening({
|
startAppListening({
|
||||||
predicate: (action): action is ReturnType<typeof enqueueRequested> =>
|
predicate: (action): action is ReturnType<typeof enqueueRequested> =>
|
||||||
enqueueRequested.match(action) && action.payload.tabName === 'nodes',
|
enqueueRequested.match(action) && action.payload.tabName === 'workflows',
|
||||||
effect: async (action, { getState, dispatch }) => {
|
effect: async (action, { getState, dispatch }) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const { nodes, edges } = state.nodes;
|
const { nodes, edges } = state.nodes;
|
||||||
|
@ -17,7 +17,7 @@ const accept: Accept = {
|
|||||||
const selectPostUploadAction = createMemoizedSelector(activeTabNameSelector, (activeTabName) => {
|
const selectPostUploadAction = createMemoizedSelector(activeTabNameSelector, (activeTabName) => {
|
||||||
let postUploadAction: PostUploadAction = { type: 'TOAST' };
|
let postUploadAction: PostUploadAction = { type: 'TOAST' };
|
||||||
|
|
||||||
if (activeTabName === 'unifiedCanvas') {
|
if (activeTabName === 'canvas') {
|
||||||
postUploadAction = { type: 'SET_CANVAS_INITIAL_IMAGE' };
|
postUploadAction = { type: 'SET_CANVAS_INITIAL_IMAGE' };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ export const useGlobalHotkeys = () => {
|
|||||||
useHotkeys(
|
useHotkeys(
|
||||||
'1',
|
'1',
|
||||||
() => {
|
() => {
|
||||||
dispatch(setActiveTab('txt2img'));
|
dispatch(setActiveTab('generation'));
|
||||||
},
|
},
|
||||||
[dispatch]
|
[dispatch]
|
||||||
);
|
);
|
||||||
@ -75,7 +75,7 @@ export const useGlobalHotkeys = () => {
|
|||||||
useHotkeys(
|
useHotkeys(
|
||||||
'2',
|
'2',
|
||||||
() => {
|
() => {
|
||||||
dispatch(setActiveTab('unifiedCanvas'));
|
dispatch(setActiveTab('canvas'));
|
||||||
},
|
},
|
||||||
[dispatch]
|
[dispatch]
|
||||||
);
|
);
|
||||||
@ -83,7 +83,7 @@ export const useGlobalHotkeys = () => {
|
|||||||
useHotkeys(
|
useHotkeys(
|
||||||
'3',
|
'3',
|
||||||
() => {
|
() => {
|
||||||
dispatch(setActiveTab('nodes'));
|
dispatch(setActiveTab('workflows'));
|
||||||
},
|
},
|
||||||
[dispatch]
|
[dispatch]
|
||||||
);
|
);
|
||||||
@ -92,7 +92,7 @@ export const useGlobalHotkeys = () => {
|
|||||||
'4',
|
'4',
|
||||||
() => {
|
() => {
|
||||||
if (isModelManagerEnabled) {
|
if (isModelManagerEnabled) {
|
||||||
dispatch(setActiveTab('modelManager'));
|
dispatch(setActiveTab('models'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[dispatch, isModelManagerEnabled]
|
[dispatch, isModelManagerEnabled]
|
||||||
|
@ -40,7 +40,7 @@ const selector = createMemoizedSelector(
|
|||||||
reasons.push(i18n.t('parameters.invoke.systemDisconnected'));
|
reasons.push(i18n.t('parameters.invoke.systemDisconnected'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeTabName === 'nodes') {
|
if (activeTabName === 'workflows') {
|
||||||
if (nodes.shouldValidateGraph) {
|
if (nodes.shouldValidateGraph) {
|
||||||
if (!nodes.nodes.length) {
|
if (!nodes.nodes.length) {
|
||||||
reasons.push(i18n.t('parameters.invoke.noNodesInGraph'));
|
reasons.push(i18n.t('parameters.invoke.noNodesInGraph'));
|
||||||
@ -93,8 +93,8 @@ const selector = createMemoizedSelector(
|
|||||||
reasons.push(i18n.t('parameters.invoke.noModelSelected'));
|
reasons.push(i18n.t('parameters.invoke.noModelSelected'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeTabName === 'txt2img') {
|
if (activeTabName === 'generation') {
|
||||||
// Handling for Control Layers - only exists on txt2img tab now
|
// Handling for generation tab
|
||||||
controlLayers.present.layers
|
controlLayers.present.layers
|
||||||
.filter((l) => l.isEnabled)
|
.filter((l) => l.isEnabled)
|
||||||
.flatMap((l) => {
|
.flatMap((l) => {
|
||||||
|
@ -75,7 +75,7 @@ const useInpaintingCanvasHotkeys = () => {
|
|||||||
|
|
||||||
const onKeyDown = useCallback(
|
const onKeyDown = useCallback(
|
||||||
(e: KeyboardEvent) => {
|
(e: KeyboardEvent) => {
|
||||||
if (e.repeat || e.key !== ' ' || isInteractiveTarget(e.target) || activeTabName !== 'unifiedCanvas') {
|
if (e.repeat || e.key !== ' ' || isInteractiveTarget(e.target) || activeTabName !== 'canvas') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ($toolStash.get() || $tool.get() === 'move') {
|
if ($toolStash.get() || $tool.get() === 'move') {
|
||||||
@ -90,7 +90,7 @@ const useInpaintingCanvasHotkeys = () => {
|
|||||||
);
|
);
|
||||||
const onKeyUp = useCallback(
|
const onKeyUp = useCallback(
|
||||||
(e: KeyboardEvent) => {
|
(e: KeyboardEvent) => {
|
||||||
if (e.repeat || e.key !== ' ' || isInteractiveTarget(e.target) || activeTabName !== 'unifiedCanvas') {
|
if (e.repeat || e.key !== ' ' || isInteractiveTarget(e.target) || activeTabName !== 'canvas') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!$toolStash.get() || $tool.get() !== 'move') {
|
if (!$toolStash.get() || $tool.get() !== 'move') {
|
||||||
|
@ -76,7 +76,7 @@ const ControlAdapterConfig = (props: { id: string; number: number }) => {
|
|||||||
<Box minW={0} w="full" transitionProperty="common" transitionDuration="0.1s">
|
<Box minW={0} w="full" transitionProperty="common" transitionDuration="0.1s">
|
||||||
<ParamControlAdapterModel id={id} />
|
<ParamControlAdapterModel id={id} />
|
||||||
</Box>
|
</Box>
|
||||||
{activeTabName === 'unifiedCanvas' && <ControlNetCanvasImageImports id={id} />}
|
{activeTabName === 'canvas' && <ControlNetCanvasImageImports id={id} />}
|
||||||
<IconButton
|
<IconButton
|
||||||
size="sm"
|
size="sm"
|
||||||
tooltip={t('controlnet.duplicate')}
|
tooltip={t('controlnet.duplicate')}
|
||||||
|
@ -93,7 +93,7 @@ const ControlAdapterImagePreview = ({ isSmall, id }: Props) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeTabName === 'unifiedCanvas') {
|
if (activeTabName === 'canvas') {
|
||||||
dispatch(setBoundingBoxDimensions({ width: controlImage.width, height: controlImage.height }, optimalDimension));
|
dispatch(setBoundingBoxDimensions({ width: controlImage.width, height: controlImage.height }, optimalDimension));
|
||||||
} else {
|
} else {
|
||||||
const options = { updateAspectRatio: true, clamp: true };
|
const options = { updateAspectRatio: true, clamp: true };
|
||||||
|
@ -80,7 +80,7 @@ export const ControlAdapterImagePreview = memo(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeTabName === 'unifiedCanvas') {
|
if (activeTabName === 'canvas') {
|
||||||
dispatch(
|
dispatch(
|
||||||
setBoundingBoxDimensions({ width: controlImage.width, height: controlImage.height }, optimalDimension)
|
setBoundingBoxDimensions({ width: controlImage.width, height: controlImage.height }, optimalDimension)
|
||||||
);
|
);
|
||||||
|
@ -46,7 +46,7 @@ export const IPAdapterImagePreview = memo(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeTabName === 'unifiedCanvas') {
|
if (activeTabName === 'canvas') {
|
||||||
dispatch(
|
dispatch(
|
||||||
setBoundingBoxDimensions({ width: controlImage.width, height: controlImage.height }, optimalDimension)
|
setBoundingBoxDimensions({ width: controlImage.width, height: controlImage.height }, optimalDimension)
|
||||||
);
|
);
|
||||||
|
@ -43,7 +43,7 @@ export const InitialImagePreview = memo(({ image, onChangeImage, droppableData,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeTabName === 'unifiedCanvas') {
|
if (activeTabName === 'canvas') {
|
||||||
dispatch(setBoundingBoxDimensions({ width: imageDTO.width, height: imageDTO.height }, optimalDimension));
|
dispatch(setBoundingBoxDimensions({ width: imageDTO.width, height: imageDTO.height }, optimalDimension));
|
||||||
} else {
|
} else {
|
||||||
const options = { updateAspectRatio: true, clamp: true };
|
const options = { updateAspectRatio: true, clamp: true };
|
||||||
|
@ -7,7 +7,7 @@ import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
const selectZoom = createSelector([selectNodesSlice, activeTabNameSelector], (nodes, activeTabName) =>
|
const selectZoom = createSelector([selectNodesSlice, activeTabNameSelector], (nodes, activeTabName) =>
|
||||||
activeTabName === 'nodes' ? nodes.viewport.zoom : 1
|
activeTabName === 'workflows' ? nodes.viewport.zoom : 1
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +45,7 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => {
|
|||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const toaster = useAppToaster();
|
const toaster = useAppToaster();
|
||||||
const isCanvasEnabled = useFeatureStatus('unifiedCanvas');
|
const isCanvasEnabled = useFeatureStatus('canvas');
|
||||||
const customStarUi = useStore($customStarUI);
|
const customStarUi = useStore($customStarUI);
|
||||||
const { downloadImage } = useDownloadImage();
|
const { downloadImage } = useDownloadImage();
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ const SingleSelectionMenuItems = (props: SingleSelectionMenuItemsProps) => {
|
|||||||
const handleSendToCanvas = useCallback(() => {
|
const handleSendToCanvas = useCallback(() => {
|
||||||
dispatch(sentImageToCanvas());
|
dispatch(sentImageToCanvas());
|
||||||
flushSync(() => {
|
flushSync(() => {
|
||||||
dispatch(setActiveTab('unifiedCanvas'));
|
dispatch(setActiveTab('canvas'));
|
||||||
});
|
});
|
||||||
dispatch(setInitialCanvasImage(imageDTO, optimalDimension));
|
dispatch(setInitialCanvasImage(imageDTO, optimalDimension));
|
||||||
|
|
||||||
|
@ -52,12 +52,12 @@ const ImageMetadataActions = (props: Props) => {
|
|||||||
<MetadataItem metadata={metadata} handlers={handlers.refinerStart} />
|
<MetadataItem metadata={metadata} handlers={handlers.refinerStart} />
|
||||||
<MetadataItem metadata={metadata} handlers={handlers.refinerSteps} />
|
<MetadataItem metadata={metadata} handlers={handlers.refinerSteps} />
|
||||||
<MetadataLoRAs metadata={metadata} />
|
<MetadataLoRAs metadata={metadata} />
|
||||||
{activeTabName !== 'txt2img' && <MetadataControlNets metadata={metadata} />}
|
{activeTabName !== 'generation' && <MetadataControlNets metadata={metadata} />}
|
||||||
{activeTabName !== 'txt2img' && <MetadataT2IAdapters metadata={metadata} />}
|
{activeTabName !== 'generation' && <MetadataT2IAdapters metadata={metadata} />}
|
||||||
{activeTabName !== 'txt2img' && <MetadataIPAdapters metadata={metadata} />}
|
{activeTabName !== 'generation' && <MetadataIPAdapters metadata={metadata} />}
|
||||||
{activeTabName === 'txt2img' && <MetadataControlNetsV2 metadata={metadata} />}
|
{activeTabName === 'generation' && <MetadataControlNetsV2 metadata={metadata} />}
|
||||||
{activeTabName === 'txt2img' && <MetadataT2IAdaptersV2 metadata={metadata} />}
|
{activeTabName === 'generation' && <MetadataT2IAdaptersV2 metadata={metadata} />}
|
||||||
{activeTabName === 'txt2img' && <MetadataIPAdaptersV2 metadata={metadata} />}
|
{activeTabName === 'generation' && <MetadataIPAdaptersV2 metadata={metadata} />}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -11,11 +11,11 @@ import { useTranslation } from 'react-i18next';
|
|||||||
import { PiArrowLeftBold } from 'react-icons/pi';
|
import { PiArrowLeftBold } from 'react-icons/pi';
|
||||||
|
|
||||||
const TAB_NAME_TO_TKEY: Record<InvokeTabName, string> = {
|
const TAB_NAME_TO_TKEY: Record<InvokeTabName, string> = {
|
||||||
txt2img: 'common.txt2img',
|
generation: 'ui.tabs.generation',
|
||||||
unifiedCanvas: 'common.unifiedCanvas',
|
canvas: 'ui.tabs.canvas',
|
||||||
nodes: 'common.nodes',
|
workflows: 'ui.tabs.workflows',
|
||||||
modelManager: 'modelManager.modelManager',
|
models: 'ui.tabs.models',
|
||||||
queue: 'queue.queue',
|
queue: 'ui.tabs.queue',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ImageViewer = memo(() => {
|
export const ImageViewer = memo(() => {
|
||||||
|
@ -14,7 +14,7 @@ export const useGalleryHotkeys = () => {
|
|||||||
const isStaging = useAppSelector(isStagingSelector);
|
const isStaging = useAppSelector(isStagingSelector);
|
||||||
// block navigation on Unified Canvas tab when staging new images
|
// block navigation on Unified Canvas tab when staging new images
|
||||||
const canNavigateGallery = useMemo(() => {
|
const canNavigateGallery = useMemo(() => {
|
||||||
return activeTabName !== 'unifiedCanvas' || !isStaging;
|
return activeTabName !== 'canvas' || !isStaging;
|
||||||
}, [activeTabName, isStaging]);
|
}, [activeTabName, isStaging]);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -43,12 +43,12 @@ export const useImageActions = (image_name?: string) => {
|
|||||||
}, [metadata]);
|
}, [metadata]);
|
||||||
|
|
||||||
const recallAll = useCallback(() => {
|
const recallAll = useCallback(() => {
|
||||||
parseAndRecallAllMetadata(metadata, activeTabName === 'txt2img');
|
parseAndRecallAllMetadata(metadata, activeTabName === 'generation');
|
||||||
}, [activeTabName, metadata]);
|
}, [activeTabName, metadata]);
|
||||||
|
|
||||||
const remix = useCallback(() => {
|
const remix = useCallback(() => {
|
||||||
// Recalls all metadata parameters except seed
|
// Recalls all metadata parameters except seed
|
||||||
parseAndRecallAllMetadata(metadata, activeTabName === 'txt2img', ['seed']);
|
parseAndRecallAllMetadata(metadata, activeTabName === 'generation', ['seed']);
|
||||||
}, [activeTabName, metadata]);
|
}, [activeTabName, metadata]);
|
||||||
|
|
||||||
const recallSeed = useCallback(() => {
|
const recallSeed = useCallback(() => {
|
||||||
|
@ -39,7 +39,7 @@ const ToastDescription = () => {
|
|||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
const onClick = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
dispatch(setActiveTab('modelManager'));
|
dispatch(setActiveTab('models'));
|
||||||
toast.close(TOAST_ID);
|
toast.close(TOAST_ID);
|
||||||
}, [dispatch, toast]);
|
}, [dispatch, toast]);
|
||||||
|
|
||||||
|
@ -31,9 +31,9 @@ export const addControlNetToLinearGraph = async (
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// The txt2img tab has special handling - its control adapters are set up in the Control Layers graph helper.
|
// The generation tab has special handling - its control adapters are set up in the Control Layers graph helper.
|
||||||
const activeTabName = activeTabNameSelector(state);
|
const activeTabName = activeTabNameSelector(state);
|
||||||
assert(activeTabName !== 'txt2img', 'Tried to use addControlNetToLinearGraph on txt2img tab');
|
assert(activeTabName !== 'generation', 'Tried to use addControlNetToLinearGraph on generation tab');
|
||||||
|
|
||||||
if (controlNets.length) {
|
if (controlNets.length) {
|
||||||
// Even though denoise_latents' control input is collection or scalar, keep it simple and always use a collect
|
// Even though denoise_latents' control input is collection or scalar, keep it simple and always use a collect
|
||||||
|
@ -106,7 +106,7 @@ export const addHrfToGraph = (state: RootState, graph: NonNullableGraph): void =
|
|||||||
if (!state.hrf.hrfEnabled || state.config.disabledSDFeatures.includes('hrf')) {
|
if (!state.hrf.hrfEnabled || state.config.disabledSDFeatures.includes('hrf')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const log = logger('txt2img');
|
const log = logger('generation');
|
||||||
|
|
||||||
const { vae, seamlessXAxis, seamlessYAxis } = state.generation;
|
const { vae, seamlessXAxis, seamlessYAxis } = state.generation;
|
||||||
const { hrfStrength, hrfEnabled, hrfMethod } = state.hrf;
|
const { hrfStrength, hrfEnabled, hrfMethod } = state.hrf;
|
||||||
|
@ -20,9 +20,9 @@ export const addIPAdapterToLinearGraph = async (
|
|||||||
graph: NonNullableGraph,
|
graph: NonNullableGraph,
|
||||||
baseNodeId: string
|
baseNodeId: string
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
// The txt2img tab has special handling - its control adapters are set up in the Control Layers graph helper.
|
// The generation tab has special handling - its control adapters are set up in the Control Layers graph helper.
|
||||||
const activeTabName = activeTabNameSelector(state);
|
const activeTabName = activeTabNameSelector(state);
|
||||||
assert(activeTabName !== 'txt2img', 'Tried to use addT2IAdaptersToLinearGraph on txt2img tab');
|
assert(activeTabName !== 'generation', 'Tried to use addT2IAdaptersToLinearGraph on generation tab');
|
||||||
|
|
||||||
const ipAdapters = selectValidIPAdapters(state.controlAdapters).filter(({ model, controlImage, isEnabled }) => {
|
const ipAdapters = selectValidIPAdapters(state.controlAdapters).filter(({ model, controlImage, isEnabled }) => {
|
||||||
const hasModel = Boolean(model);
|
const hasModel = Boolean(model);
|
||||||
|
@ -20,9 +20,9 @@ export const addT2IAdaptersToLinearGraph = async (
|
|||||||
graph: NonNullableGraph,
|
graph: NonNullableGraph,
|
||||||
baseNodeId: string
|
baseNodeId: string
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
// The txt2img tab has special handling - its control adapters are set up in the Control Layers graph helper.
|
// The generation tab has special handling - its control adapters are set up in the Control Layers graph helper.
|
||||||
const activeTabName = activeTabNameSelector(state);
|
const activeTabName = activeTabNameSelector(state);
|
||||||
assert(activeTabName !== 'txt2img', 'Tried to use addT2IAdaptersToLinearGraph on txt2img tab');
|
assert(activeTabName !== 'generation', 'Tried to use addT2IAdaptersToLinearGraph on generation tab');
|
||||||
|
|
||||||
const t2iAdapters = selectValidT2IAdapters(state.controlAdapters).filter(
|
const t2iAdapters = selectValidT2IAdapters(state.controlAdapters).filter(
|
||||||
({ model, processedControlImage, processorType, controlImage, isEnabled }) => {
|
({ model, processedControlImage, processorType, controlImage, isEnabled }) => {
|
||||||
|
@ -31,7 +31,7 @@ export const getSDXLStylePrompts = (state: RootState): { positiveStylePrompt: st
|
|||||||
*/
|
*/
|
||||||
export const getIsIntermediate = (state: RootState) => {
|
export const getIsIntermediate = (state: RootState) => {
|
||||||
const activeTabName = activeTabNameSelector(state);
|
const activeTabName = activeTabNameSelector(state);
|
||||||
if (activeTabName === 'unifiedCanvas') {
|
if (activeTabName === 'canvas') {
|
||||||
return !state.canvas.shouldAutoSave;
|
return !state.canvas.shouldAutoSave;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -10,10 +10,10 @@ export const NavigateToModelManagerButton = memo((props: Omit<IconButtonProps, '
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const disabledTabs = useAppSelector((s) => s.config.disabledTabs);
|
const disabledTabs = useAppSelector((s) => s.config.disabledTabs);
|
||||||
const shouldShowButton = useMemo(() => !disabledTabs.includes('modelManager'), [disabledTabs]);
|
const shouldShowButton = useMemo(() => !disabledTabs.includes('models'), [disabledTabs]);
|
||||||
|
|
||||||
const handleClick = useCallback(() => {
|
const handleClick = useCallback(() => {
|
||||||
dispatch(setActiveTab('modelManager'));
|
dispatch(setActiveTab('models'));
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
if (!shouldShowButton) {
|
if (!shouldShowButton) {
|
||||||
|
@ -25,7 +25,7 @@ export const usePreselectedImage = (selectedImage?: {
|
|||||||
const handleSendToCanvas = useCallback(() => {
|
const handleSendToCanvas = useCallback(() => {
|
||||||
if (selectedImageDto) {
|
if (selectedImageDto) {
|
||||||
dispatch(setInitialCanvasImage(selectedImageDto, optimalDimension));
|
dispatch(setInitialCanvasImage(selectedImageDto, optimalDimension));
|
||||||
dispatch(setActiveTab('unifiedCanvas'));
|
dispatch(setActiveTab('canvas'));
|
||||||
toaster({
|
toaster({
|
||||||
title: t('toast.sentToUnifiedCanvas'),
|
title: t('toast.sentToUnifiedCanvas'),
|
||||||
status: 'info',
|
status: 'info',
|
||||||
|
@ -31,7 +31,7 @@ const selector = createMemoizedSelector(
|
|||||||
const badges: string[] = [];
|
const badges: string[] = [];
|
||||||
const isSDXL = model?.base === 'sdxl';
|
const isSDXL = model?.base === 'sdxl';
|
||||||
|
|
||||||
if (activeTabName === 'unifiedCanvas') {
|
if (activeTabName === 'canvas') {
|
||||||
const {
|
const {
|
||||||
aspectRatio,
|
aspectRatio,
|
||||||
boundingBoxDimensions: { width, height },
|
boundingBoxDimensions: { width, height },
|
||||||
@ -85,7 +85,7 @@ export const ImageSettingsAccordion = memo(() => {
|
|||||||
onToggle={onToggleAccordion}
|
onToggle={onToggleAccordion}
|
||||||
>
|
>
|
||||||
<Flex px={4} pt={4} w="full" h="full" flexDir="column" data-testid="image-settings-accordion">
|
<Flex px={4} pt={4} w="full" h="full" flexDir="column" data-testid="image-settings-accordion">
|
||||||
{activeTabName === 'unifiedCanvas' ? <ImageSizeCanvas /> : <ImageSizeLinear />}
|
{activeTabName === 'canvas' ? <ImageSizeCanvas /> : <ImageSizeLinear />}
|
||||||
<Expander label={t('accordions.advanced.options')} isOpen={isOpenExpander} onToggle={onToggleExpander}>
|
<Expander label={t('accordions.advanced.options')} isOpen={isOpenExpander} onToggle={onToggleExpander}>
|
||||||
<Flex gap={4} pb={4} flexDir="column">
|
<Flex gap={4} pb={4} flexDir="column">
|
||||||
<Flex gap={4} alignItems="center">
|
<Flex gap={4} alignItems="center">
|
||||||
@ -93,9 +93,9 @@ export const ImageSettingsAccordion = memo(() => {
|
|||||||
<ParamSeedShuffle />
|
<ParamSeedShuffle />
|
||||||
<ParamSeedRandomize />
|
<ParamSeedRandomize />
|
||||||
</Flex>
|
</Flex>
|
||||||
{activeTabName === 'unifiedCanvas' && <ImageToImageStrength />}
|
{activeTabName === 'canvas' && <ImageToImageStrength />}
|
||||||
{activeTabName === 'txt2img' && !isSDXL && <HrfSettings />}
|
{activeTabName === 'generation' && !isSDXL && <HrfSettings />}
|
||||||
{activeTabName === 'unifiedCanvas' && (
|
{activeTabName === 'canvas' && (
|
||||||
<>
|
<>
|
||||||
<ParamScaleBeforeProcessing />
|
<ParamScaleBeforeProcessing />
|
||||||
<FormControlGroup formLabelProps={scalingLabelProps}>
|
<FormControlGroup formLabelProps={scalingLabelProps}>
|
||||||
|
@ -50,7 +50,7 @@ export const ImageSizeLinear = memo(() => {
|
|||||||
aspectRatioState={aspectRatioState}
|
aspectRatioState={aspectRatioState}
|
||||||
heightComponent={<ParamHeight />}
|
heightComponent={<ParamHeight />}
|
||||||
widthComponent={<ParamWidth />}
|
widthComponent={<ParamWidth />}
|
||||||
previewComponent={tab === 'txt2img' ? <AspectRatioCanvasPreview /> : <AspectRatioIconPreview />}
|
previewComponent={tab === 'generation' ? <AspectRatioCanvasPreview /> : <AspectRatioIconPreview />}
|
||||||
onChangeAspectRatioState={onChangeAspectRatioState}
|
onChangeAspectRatioState={onChangeAspectRatioState}
|
||||||
onChangeWidth={onChangeWidth}
|
onChangeWidth={onChangeWidth}
|
||||||
onChangeHeight={onChangeHeight}
|
onChangeHeight={onChangeHeight}
|
||||||
|
@ -44,26 +44,26 @@ type TabData = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const TAB_DATA: Record<InvokeTabName, TabData> = {
|
const TAB_DATA: Record<InvokeTabName, TabData> = {
|
||||||
txt2img: {
|
generation: {
|
||||||
id: 'txt2img',
|
id: 'generation',
|
||||||
translationKey: 'ui.tabs.generation',
|
translationKey: 'ui.tabs.generation',
|
||||||
icon: <RiInputMethodLine />,
|
icon: <RiInputMethodLine />,
|
||||||
content: <TextToImageTab />,
|
content: <TextToImageTab />,
|
||||||
},
|
},
|
||||||
unifiedCanvas: {
|
canvas: {
|
||||||
id: 'unifiedCanvas',
|
id: 'canvas',
|
||||||
translationKey: 'ui.tabs.canvas',
|
translationKey: 'ui.tabs.canvas',
|
||||||
icon: <RiBrushLine />,
|
icon: <RiBrushLine />,
|
||||||
content: <UnifiedCanvasTab />,
|
content: <UnifiedCanvasTab />,
|
||||||
},
|
},
|
||||||
nodes: {
|
workflows: {
|
||||||
id: 'nodes',
|
id: 'workflows',
|
||||||
translationKey: 'ui.tabs.workflows',
|
translationKey: 'ui.tabs.workflows',
|
||||||
icon: <PiFlowArrowBold />,
|
icon: <PiFlowArrowBold />,
|
||||||
content: <NodesTab />,
|
content: <NodesTab />,
|
||||||
},
|
},
|
||||||
modelManager: {
|
models: {
|
||||||
id: 'modelManager',
|
id: 'models',
|
||||||
translationKey: 'ui.tabs.models',
|
translationKey: 'ui.tabs.models',
|
||||||
icon: <RiBox2Line />,
|
icon: <RiBox2Line />,
|
||||||
content: <ModelManagerTab />,
|
content: <ModelManagerTab />,
|
||||||
@ -80,8 +80,8 @@ const enabledTabsSelector = createMemoizedSelector(selectConfigSlice, (config) =
|
|||||||
TAB_NUMBER_MAP.map((tabName) => TAB_DATA[tabName]).filter((tab) => !config.disabledTabs.includes(tab.id))
|
TAB_NUMBER_MAP.map((tabName) => TAB_DATA[tabName]).filter((tab) => !config.disabledTabs.includes(tab.id))
|
||||||
);
|
);
|
||||||
|
|
||||||
const NO_GALLERY_PANEL_TABS: InvokeTabName[] = ['modelManager', 'queue'];
|
const NO_GALLERY_PANEL_TABS: InvokeTabName[] = ['models', 'queue'];
|
||||||
const NO_OPTIONS_PANEL_TABS: InvokeTabName[] = ['modelManager', 'queue'];
|
const NO_OPTIONS_PANEL_TABS: InvokeTabName[] = ['models', 'queue'];
|
||||||
const panelStyles: CSSProperties = { height: '100%', width: '100%' };
|
const panelStyles: CSSProperties = { height: '100%', width: '100%' };
|
||||||
const GALLERY_MIN_SIZE_PX = 310;
|
const GALLERY_MIN_SIZE_PX = 310;
|
||||||
const GALLERY_MIN_SIZE_PCT = 20;
|
const GALLERY_MIN_SIZE_PCT = 20;
|
||||||
@ -291,10 +291,10 @@ export default memo(InvokeTabs);
|
|||||||
const ParametersPanelComponent = memo(() => {
|
const ParametersPanelComponent = memo(() => {
|
||||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
const activeTabName = useAppSelector(activeTabNameSelector);
|
||||||
|
|
||||||
if (activeTabName === 'nodes') {
|
if (activeTabName === 'workflows') {
|
||||||
return <NodeEditorPanelGroup />;
|
return <NodeEditorPanelGroup />;
|
||||||
}
|
}
|
||||||
if (activeTabName === 'txt2img') {
|
if (activeTabName === 'generation') {
|
||||||
return <ParametersPanelTextToImage />;
|
return <ParametersPanelTextToImage />;
|
||||||
}
|
}
|
||||||
return <ParametersPanel />;
|
return <ParametersPanel />;
|
||||||
|
@ -34,8 +34,8 @@ const ParametersPanel = () => {
|
|||||||
{isSDXL ? <SDXLPrompts /> : <Prompts />}
|
{isSDXL ? <SDXLPrompts /> : <Prompts />}
|
||||||
<ImageSettingsAccordion />
|
<ImageSettingsAccordion />
|
||||||
<GenerationSettingsAccordion />
|
<GenerationSettingsAccordion />
|
||||||
{activeTabName !== 'txt2img' && <ControlSettingsAccordion />}
|
{activeTabName !== 'generation' && <ControlSettingsAccordion />}
|
||||||
{activeTabName === 'unifiedCanvas' && <CompositingSettingsAccordion />}
|
{activeTabName === 'canvas' && <CompositingSettingsAccordion />}
|
||||||
{isSDXL && <RefinerSettingsAccordion />}
|
{isSDXL && <RefinerSettingsAccordion />}
|
||||||
<AdvancedSettingsAccordion />
|
<AdvancedSettingsAccordion />
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -48,8 +48,8 @@ const ParametersPanelTextToImage = () => {
|
|||||||
<Flex gap={2} flexDirection="column" h="full" w="full">
|
<Flex gap={2} flexDirection="column" h="full" w="full">
|
||||||
<ImageSettingsAccordion />
|
<ImageSettingsAccordion />
|
||||||
<GenerationSettingsAccordion />
|
<GenerationSettingsAccordion />
|
||||||
{activeTabName !== 'txt2img' && <ControlSettingsAccordion />}
|
{activeTabName !== 'generation' && <ControlSettingsAccordion />}
|
||||||
{activeTabName === 'unifiedCanvas' && <CompositingSettingsAccordion />}
|
{activeTabName === 'canvas' && <CompositingSettingsAccordion />}
|
||||||
{isSDXL && <RefinerSettingsAccordion />}
|
{isSDXL && <RefinerSettingsAccordion />}
|
||||||
<AdvancedSettingsAccordion />
|
<AdvancedSettingsAccordion />
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
export const TAB_NUMBER_MAP = ['txt2img', 'unifiedCanvas', 'nodes', 'modelManager', 'queue'] as const;
|
export const TAB_NUMBER_MAP = ['generation', 'canvas', 'workflows', 'models', 'queue'] as const;
|
||||||
|
|
||||||
export type InvokeTabName = (typeof TAB_NUMBER_MAP)[number];
|
export type InvokeTabName = (typeof TAB_NUMBER_MAP)[number];
|
||||||
|
@ -11,7 +11,7 @@ export const activeTabNameSelector = createSelector(
|
|||||||
* Previously `activeTab` was an integer, but now it's a string.
|
* Previously `activeTab` was an integer, but now it's a string.
|
||||||
* Default to first tab in case user has integer.
|
* Default to first tab in case user has integer.
|
||||||
*/
|
*/
|
||||||
(ui) => (isString(ui.activeTab) ? ui.activeTab : 'txt2img')
|
(ui) => (isString(ui.activeTab) ? ui.activeTab : 'generation')
|
||||||
);
|
);
|
||||||
|
|
||||||
export const activeTabIndexSelector = createSelector(selectUiSlice, selectConfigSlice, (ui, config) => {
|
export const activeTabIndexSelector = createSelector(selectUiSlice, selectConfigSlice, (ui, config) => {
|
||||||
|
@ -7,8 +7,8 @@ import type { InvokeTabName } from './tabMap';
|
|||||||
import type { UIState } from './uiTypes';
|
import type { UIState } from './uiTypes';
|
||||||
|
|
||||||
const initialUIState: UIState = {
|
const initialUIState: UIState = {
|
||||||
_version: 1,
|
_version: 2,
|
||||||
activeTab: 'txt2img',
|
activeTab: 'generation',
|
||||||
shouldShowImageDetails: false,
|
shouldShowImageDetails: false,
|
||||||
shouldShowProgressInViewer: true,
|
shouldShowProgressInViewer: true,
|
||||||
panels: {},
|
panels: {},
|
||||||
@ -43,7 +43,7 @@ export const uiSlice = createSlice({
|
|||||||
},
|
},
|
||||||
extraReducers(builder) {
|
extraReducers(builder) {
|
||||||
builder.addCase(workflowLoadRequested, (state) => {
|
builder.addCase(workflowLoadRequested, (state) => {
|
||||||
state.activeTab = 'nodes';
|
state.activeTab = 'workflows';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -64,6 +64,10 @@ const migrateUIState = (state: any): any => {
|
|||||||
if (!('_version' in state)) {
|
if (!('_version' in state)) {
|
||||||
state._version = 1;
|
state._version = 1;
|
||||||
}
|
}
|
||||||
|
if (state._version === 1) {
|
||||||
|
state.activeTab = 'generation';
|
||||||
|
state._version = 2;
|
||||||
|
}
|
||||||
return state;
|
return state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ export interface UIState {
|
|||||||
/**
|
/**
|
||||||
* Slice schema version.
|
* Slice schema version.
|
||||||
*/
|
*/
|
||||||
_version: 1;
|
_version: 2;
|
||||||
/**
|
/**
|
||||||
* The currently active tab.
|
* The currently active tab.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user