From 5eaea9dd64ff24dd817f1257e508da7a7aa27663 Mon Sep 17 00:00:00 2001
From: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date: Mon, 13 Nov 2023 08:43:27 +1100
Subject: [PATCH 1/4] chore(ui): delete unused files
---
.../IAIErrorLoadingImageFallback.tsx | 43 -----
.../web/src/common/components/IAIForm.tsx | 8 -
.../IAIForms/IAIFormErrorMessage.tsx | 15 --
.../components/IAIForms/IAIFormHelperText.tsx | 15 --
.../IAIForms/IAIFormItemWrapper.tsx | 25 ---
.../src/common/components/IAIFullCheckbox.tsx | 25 ---
.../components/SelectImagePlaceholder.tsx | 23 ---
.../web/src/common/hooks/useResolution.ts | 24 ---
.../web/src/common/util/getTimestamp.ts | 7 -
.../web/src/common/util/seedWeightPairs.ts | 71 --------
.../canvas/util/konvaNodeToDataURL.ts | 16 --
.../ControlAdapterPreprocessButton.tsx | 36 ----
.../dynamicPrompts/store/selectors.ts | 1 -
.../embedding/store/embeddingSlice.ts | 0
.../Boards/BoardsList/GenericBoard.tsx | 108 -----------
.../Boards/BoardsList/SystemBoardButton.tsx | 53 ------
.../CurrentImage/CurrentImageHidden.tsx | 22 ---
.../components/ImageFallbackSpinner.tsx | 27 ---
.../fields/inputs/ClipInputField.tsx | 14 --
.../fields/inputs/CollectionInputField.tsx | 17 --
.../inputs/CollectionItemInputField.tsx | 17 --
.../fields/inputs/ConditioningInputField.tsx | 17 --
.../fields/inputs/ControlInputField.tsx | 19 --
.../fields/inputs/DenoiseMaskInputField.tsx | 17 --
.../fields/inputs/IPAdapterInputField.tsx | 19 --
.../inputs/ImageCollectionInputField.tsx | 94 ----------
.../fields/inputs/LatentsInputField.tsx | 19 --
.../fields/inputs/T2IAdapterInputField.tsx | 19 --
.../fields/inputs/UnetInputField.tsx | 14 --
.../fields/inputs/VaeInputField.tsx | 14 --
.../flow/nodes/common/NodeResizer.tsx | 27 ---
.../inspector/InspectorDetailsTab.tsx | 78 --------
.../sidePanel/workflow/WorkflowNotesTab.tsx | 51 ------
.../nodes/store/util/makeTemplateSelector.ts | 11 --
.../BoundingBox/ParamBoundingBoxCollapse.tsx | 21 ---
.../Parameters/Noise/ParamNoiseThreshold.tsx | 39 ----
.../Parameters/Noise/ParamPerlinNoise.tsx | 39 ----
.../Variations/ParamVariationAmount.tsx | 35 ----
.../Variations/ParamVariationCollapse.tsx | 51 ------
.../Variations/ParamVariationToggle.tsx | 24 ---
.../Variations/ParamVariationWeights.tsx | 41 -----
.../store/postprocessingSelectors.ts | 4 -
.../queue/components/CurrentQueueItemCard.tsx | 18 --
.../queue/components/NextQueueItemCard.tsx | 18 --
.../QueueList/QueueItemSkeleton.tsx | 41 -----
.../queue/components/QueueStatusCard.tsx | 54 ------
.../queue/components/common/QueueItemCard.tsx | 52 ------
.../components/common/QueueStatusDot.tsx | 28 ---
.../features/queue/util/formatNumberShort.ts | 4 -
.../SettingsModal/ResetWebUIButton.tsx | 82 ---------
.../web/src/features/system/store/actions.ts | 3 -
.../src/features/system/store/sessionSlice.ts | 62 -------
.../components/common/OverlayScrollable.tsx | 22 ---
.../store/modelmanagerSelectors.tsx | 3 -
.../UnifiedCanvasBaseBrushSettings.tsx | 12 --
.../UnifiedCanvasBrushSettings.tsx | 12 --
.../UnifiedCanvasBrushSize.tsx | 54 ------
.../UnifiedCanvasClearMask.tsx | 25 ---
.../UnifiedCanvasColorPicker.tsx | 128 -------------
.../UnifiedCanvasDarkenOutsideSelection.tsx | 25 ---
.../UnifiedCanvasEnableMask.tsx | 25 ---
.../UnifiedCanvasLimitStrokesToBox.tsx | 25 ---
.../UnifiedCanvasMaskBrushSettings.tsx | 16 --
.../UnifiedCanvasMoveSettings.tsx | 14 --
.../UnifiedCanvasPreserveMask.tsx | 22 ---
.../UnifiedCanvasSettings.tsx | 113 ------------
.../UnifiedCanvasShowGrid.tsx | 22 ---
.../UnifiedCanvasSnapToGrid.tsx | 26 ---
.../UnifiedCanvasToolSettingsBeta.tsx | 41 -----
.../UnifiedCanvasCopyToClipboard.tsx | 50 -----
.../UnifiedCanvasDownloadImage.tsx | 43 -----
.../UnifiedCanvasFileUploader.tsx | 28 ---
.../UnifiedCanvasLayerSelect.tsx | 71 --------
.../UnifiedCanvasMergeVisible.tsx | 37 ----
.../UnifiedCanvasMoveTool.tsx | 39 ----
.../UnifiedCanvasResetCanvas.tsx | 26 ---
.../UnifiedCanvasResetView.tsx | 55 ------
.../UnifiedCanvasSaveToGallery.tsx | 39 ----
.../UnifiedCanvasToolSelect.tsx | 172 ------------------
.../UnifiedCanvasToolbarBeta.tsx | 53 ------
.../web/src/theme/components/table.ts | 0
81 files changed, 2780 deletions(-)
delete mode 100644 invokeai/frontend/web/src/common/components/IAIErrorLoadingImageFallback.tsx
delete mode 100644 invokeai/frontend/web/src/common/components/IAIForm.tsx
delete mode 100644 invokeai/frontend/web/src/common/components/IAIForms/IAIFormErrorMessage.tsx
delete mode 100644 invokeai/frontend/web/src/common/components/IAIForms/IAIFormHelperText.tsx
delete mode 100644 invokeai/frontend/web/src/common/components/IAIForms/IAIFormItemWrapper.tsx
delete mode 100644 invokeai/frontend/web/src/common/components/IAIFullCheckbox.tsx
delete mode 100644 invokeai/frontend/web/src/common/components/SelectImagePlaceholder.tsx
delete mode 100644 invokeai/frontend/web/src/common/hooks/useResolution.ts
delete mode 100644 invokeai/frontend/web/src/common/util/getTimestamp.ts
delete mode 100644 invokeai/frontend/web/src/common/util/seedWeightPairs.ts
delete mode 100644 invokeai/frontend/web/src/features/canvas/util/konvaNodeToDataURL.ts
delete mode 100644 invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterPreprocessButton.tsx
delete mode 100644 invokeai/frontend/web/src/features/dynamicPrompts/store/selectors.ts
delete mode 100644 invokeai/frontend/web/src/features/embedding/store/embeddingSlice.ts
delete mode 100644 invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GenericBoard.tsx
delete mode 100644 invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/SystemBoardButton.tsx
delete mode 100644 invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageHidden.tsx
delete mode 100644 invokeai/frontend/web/src/features/gallery/components/ImageFallbackSpinner.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ClipInputField.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/CollectionInputField.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/CollectionItemInputField.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ConditioningInputField.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ControlInputField.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/DenoiseMaskInputField.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/IPAdapterInputField.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ImageCollectionInputField.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/LatentsInputField.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/T2IAdapterInputField.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/UnetInputField.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/VaeInputField.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/flow/nodes/common/NodeResizer.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/sidePanel/inspector/InspectorDetailsTab.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowNotesTab.tsx
delete mode 100644 invokeai/frontend/web/src/features/nodes/store/util/makeTemplateSelector.ts
delete mode 100644 invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/BoundingBox/ParamBoundingBoxCollapse.tsx
delete mode 100644 invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseThreshold.tsx
delete mode 100644 invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamPerlinNoise.tsx
delete mode 100644 invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationAmount.tsx
delete mode 100644 invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationCollapse.tsx
delete mode 100644 invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationToggle.tsx
delete mode 100644 invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationWeights.tsx
delete mode 100644 invokeai/frontend/web/src/features/parameters/store/postprocessingSelectors.ts
delete mode 100644 invokeai/frontend/web/src/features/queue/components/CurrentQueueItemCard.tsx
delete mode 100644 invokeai/frontend/web/src/features/queue/components/NextQueueItemCard.tsx
delete mode 100644 invokeai/frontend/web/src/features/queue/components/QueueList/QueueItemSkeleton.tsx
delete mode 100644 invokeai/frontend/web/src/features/queue/components/QueueStatusCard.tsx
delete mode 100644 invokeai/frontend/web/src/features/queue/components/common/QueueItemCard.tsx
delete mode 100644 invokeai/frontend/web/src/features/queue/components/common/QueueStatusDot.tsx
delete mode 100644 invokeai/frontend/web/src/features/queue/util/formatNumberShort.ts
delete mode 100644 invokeai/frontend/web/src/features/system/components/SettingsModal/ResetWebUIButton.tsx
delete mode 100644 invokeai/frontend/web/src/features/system/store/actions.ts
delete mode 100644 invokeai/frontend/web/src/features/system/store/sessionSlice.ts
delete mode 100644 invokeai/frontend/web/src/features/ui/components/common/OverlayScrollable.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/store/modelmanagerSelectors.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasBaseBrushSettings.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasBrushSettings.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasBrushSize.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasClearMask.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasColorPicker.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasDarkenOutsideSelection.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasEnableMask.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasLimitStrokesToBox.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasMaskBrushSettings.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasMoveSettings.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasPreserveMask.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasSettings.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasShowGrid.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasSnapToGrid.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettingsBeta.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasCopyToClipboard.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasDownloadImage.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasFileUploader.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasLayerSelect.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasMergeVisible.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasMoveTool.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasResetCanvas.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasResetView.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasSaveToGallery.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasToolSelect.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbarBeta.tsx
delete mode 100644 invokeai/frontend/web/src/theme/components/table.ts
diff --git a/invokeai/frontend/web/src/common/components/IAIErrorLoadingImageFallback.tsx b/invokeai/frontend/web/src/common/components/IAIErrorLoadingImageFallback.tsx
deleted file mode 100644
index 0a5d4fb12f..0000000000
--- a/invokeai/frontend/web/src/common/components/IAIErrorLoadingImageFallback.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { Box, Flex, Icon } from '@chakra-ui/react';
-import { memo } from 'react';
-import { FaExclamation } from 'react-icons/fa';
-
-const IAIErrorLoadingImageFallback = () => {
- return (
-
-
-
-
-
- );
-};
-
-export default memo(IAIErrorLoadingImageFallback);
diff --git a/invokeai/frontend/web/src/common/components/IAIForm.tsx b/invokeai/frontend/web/src/common/components/IAIForm.tsx
deleted file mode 100644
index c94d177a21..0000000000
--- a/invokeai/frontend/web/src/common/components/IAIForm.tsx
+++ /dev/null
@@ -1,8 +0,0 @@
-import { chakra } from '@chakra-ui/react';
-
-/**
- * Chakra-enabled
- */
-const IAIForm = chakra.form;
-
-export default IAIForm;
diff --git a/invokeai/frontend/web/src/common/components/IAIForms/IAIFormErrorMessage.tsx b/invokeai/frontend/web/src/common/components/IAIForms/IAIFormErrorMessage.tsx
deleted file mode 100644
index 22aa10cb06..0000000000
--- a/invokeai/frontend/web/src/common/components/IAIForms/IAIFormErrorMessage.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { FormErrorMessage, FormErrorMessageProps } from '@chakra-ui/react';
-import { ReactNode } from 'react';
-
-type IAIFormErrorMessageProps = FormErrorMessageProps & {
- children: ReactNode | string;
-};
-
-export default function IAIFormErrorMessage(props: IAIFormErrorMessageProps) {
- const { children, ...rest } = props;
- return (
-
- {children}
-
- );
-}
diff --git a/invokeai/frontend/web/src/common/components/IAIForms/IAIFormHelperText.tsx b/invokeai/frontend/web/src/common/components/IAIForms/IAIFormHelperText.tsx
deleted file mode 100644
index 4d48ac991c..0000000000
--- a/invokeai/frontend/web/src/common/components/IAIForms/IAIFormHelperText.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { FormHelperText, FormHelperTextProps } from '@chakra-ui/react';
-import { ReactNode } from 'react';
-
-type IAIFormHelperTextProps = FormHelperTextProps & {
- children: ReactNode | string;
-};
-
-export default function IAIFormHelperText(props: IAIFormHelperTextProps) {
- const { children, ...rest } = props;
- return (
-
- {children}
-
- );
-}
diff --git a/invokeai/frontend/web/src/common/components/IAIForms/IAIFormItemWrapper.tsx b/invokeai/frontend/web/src/common/components/IAIForms/IAIFormItemWrapper.tsx
deleted file mode 100644
index 83e91366c2..0000000000
--- a/invokeai/frontend/web/src/common/components/IAIForms/IAIFormItemWrapper.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { Flex, useColorMode } from '@chakra-ui/react';
-import { ReactElement } from 'react';
-import { mode } from 'theme/util/mode';
-
-export function IAIFormItemWrapper({
- children,
-}: {
- children: ReactElement | ReactElement[];
-}) {
- const { colorMode } = useColorMode();
- return (
-
- {children}
-
- );
-}
diff --git a/invokeai/frontend/web/src/common/components/IAIFullCheckbox.tsx b/invokeai/frontend/web/src/common/components/IAIFullCheckbox.tsx
deleted file mode 100644
index 97ff24689c..0000000000
--- a/invokeai/frontend/web/src/common/components/IAIFullCheckbox.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import {
- Checkbox,
- CheckboxProps,
- FormControl,
- FormControlProps,
- FormLabel,
-} from '@chakra-ui/react';
-import { memo, ReactNode } from 'react';
-
-type IAIFullCheckboxProps = CheckboxProps & {
- label: string | ReactNode;
- formControlProps?: FormControlProps;
-};
-
-const IAIFullCheckbox = (props: IAIFullCheckboxProps) => {
- const { label, formControlProps, ...rest } = props;
- return (
-
- {label}
-
-
- );
-};
-
-export default memo(IAIFullCheckbox);
diff --git a/invokeai/frontend/web/src/common/components/SelectImagePlaceholder.tsx b/invokeai/frontend/web/src/common/components/SelectImagePlaceholder.tsx
deleted file mode 100644
index 2db202ddc0..0000000000
--- a/invokeai/frontend/web/src/common/components/SelectImagePlaceholder.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import { Flex, Icon } from '@chakra-ui/react';
-import { memo } from 'react';
-import { FaImage } from 'react-icons/fa';
-
-const SelectImagePlaceholder = () => {
- return (
-
-
-
- );
-};
-
-export default memo(SelectImagePlaceholder);
diff --git a/invokeai/frontend/web/src/common/hooks/useResolution.ts b/invokeai/frontend/web/src/common/hooks/useResolution.ts
deleted file mode 100644
index fb52555be8..0000000000
--- a/invokeai/frontend/web/src/common/hooks/useResolution.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { useBreakpoint } from '@chakra-ui/react';
-
-export default function useResolution():
- | 'mobile'
- | 'tablet'
- | 'desktop'
- | 'unknown' {
- const breakpointValue = useBreakpoint();
-
- const mobileResolutions = ['base', 'sm'];
- const tabletResolutions = ['md', 'lg'];
- const desktopResolutions = ['xl', '2xl'];
-
- if (mobileResolutions.includes(breakpointValue)) {
- return 'mobile';
- }
- if (tabletResolutions.includes(breakpointValue)) {
- return 'tablet';
- }
- if (desktopResolutions.includes(breakpointValue)) {
- return 'desktop';
- }
- return 'unknown';
-}
diff --git a/invokeai/frontend/web/src/common/util/getTimestamp.ts b/invokeai/frontend/web/src/common/util/getTimestamp.ts
deleted file mode 100644
index daa9f8dc33..0000000000
--- a/invokeai/frontend/web/src/common/util/getTimestamp.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import dateFormat from 'dateformat';
-
-/**
- * Get a `now` timestamp with 1s precision, formatted as ISO datetime.
- */
-export const getTimestamp = () =>
- dateFormat(new Date(), `yyyy-mm-dd'T'HH:MM:ss:lo`);
diff --git a/invokeai/frontend/web/src/common/util/seedWeightPairs.ts b/invokeai/frontend/web/src/common/util/seedWeightPairs.ts
deleted file mode 100644
index 564f66c1e3..0000000000
--- a/invokeai/frontend/web/src/common/util/seedWeightPairs.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-// TODO: Restore variations
-// Support code from v2.3 in here.
-
-// export const stringToSeedWeights = (
-// string: string
-// ): InvokeAI.SeedWeights | boolean => {
-// const stringPairs = string.split(',');
-// const arrPairs = stringPairs.map((p) => p.split(':'));
-// const pairs = arrPairs.map((p: Array): InvokeAI.SeedWeightPair => {
-// return { seed: Number(p[0]), weight: Number(p[1]) };
-// });
-
-// if (!validateSeedWeights(pairs)) {
-// return false;
-// }
-
-// return pairs;
-// };
-
-// export const validateSeedWeights = (
-// seedWeights: InvokeAI.SeedWeights | string
-// ): boolean => {
-// return typeof seedWeights === 'string'
-// ? Boolean(stringToSeedWeights(seedWeights))
-// : Boolean(
-// seedWeights.length &&
-// !seedWeights.some((pair: InvokeAI.SeedWeightPair) => {
-// const { seed, weight } = pair;
-// const isSeedValid = !isNaN(parseInt(seed.toString(), 10));
-// const isWeightValid =
-// !isNaN(parseInt(weight.toString(), 10)) &&
-// weight >= 0 &&
-// weight <= 1;
-// return !(isSeedValid && isWeightValid);
-// })
-// );
-// };
-
-// export const seedWeightsToString = (
-// seedWeights: InvokeAI.SeedWeights
-// ): string => {
-// return seedWeights.reduce((acc, pair, i, arr) => {
-// const { seed, weight } = pair;
-// acc += `${seed}:${weight}`;
-// if (i !== arr.length - 1) {
-// acc += ',';
-// }
-// return acc;
-// }, '');
-// };
-
-// export const seedWeightsToArray = (
-// seedWeights: InvokeAI.SeedWeights
-// ): Array> => {
-// return seedWeights.map((pair: InvokeAI.SeedWeightPair) => [
-// pair.seed,
-// pair.weight,
-// ]);
-// };
-
-// export const stringToSeedWeightsArray = (
-// string: string
-// ): Array> => {
-// const stringPairs = string.split(',');
-// const arrPairs = stringPairs.map((p) => p.split(':'));
-// return arrPairs.map(
-// (p: Array): Array => [parseInt(p[0], 10), parseFloat(p[1])]
-// );
-// };
-
-export default {};
diff --git a/invokeai/frontend/web/src/features/canvas/util/konvaNodeToDataURL.ts b/invokeai/frontend/web/src/features/canvas/util/konvaNodeToDataURL.ts
deleted file mode 100644
index 5d0aaf5443..0000000000
--- a/invokeai/frontend/web/src/features/canvas/util/konvaNodeToDataURL.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import Konva from 'konva';
-import { IRect } from 'konva/lib/types';
-
-/**
- * Converts a Konva node to a dataURL
- * @param node - The Konva node to convert to a dataURL
- * @param boundingBox - The bounding box to crop to
- * @returns A dataURL of the node cropped to the bounding box
- */
-export const konvaNodeToDataURL = (
- node: Konva.Node,
- boundingBox: IRect
-): string => {
- // get a dataURL of the bbox'd region
- return node.toDataURL(boundingBox);
-};
diff --git a/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterPreprocessButton.tsx b/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterPreprocessButton.tsx
deleted file mode 100644
index 44a34dcd46..0000000000
--- a/invokeai/frontend/web/src/features/controlAdapters/components/ControlAdapterPreprocessButton.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import { useAppDispatch } from 'app/store/storeHooks';
-import IAIButton from 'common/components/IAIButton';
-import { useIsReadyToEnqueue } from 'common/hooks/useIsReadyToEnqueue';
-import { memo, useCallback } from 'react';
-import { useControlAdapterControlImage } from '../hooks/useControlAdapterControlImage';
-import { controlAdapterImageProcessed } from '../store/actions';
-
-type Props = {
- id: string;
-};
-
-const ControlAdapterPreprocessButton = ({ id }: Props) => {
- const controlImage = useControlAdapterControlImage(id);
- const dispatch = useAppDispatch();
- const isReady = useIsReadyToEnqueue();
-
- const handleProcess = useCallback(() => {
- dispatch(
- controlAdapterImageProcessed({
- id,
- })
- );
- }, [id, dispatch]);
-
- return (
-
- Preprocess
-
- );
-};
-
-export default memo(ControlAdapterPreprocessButton);
diff --git a/invokeai/frontend/web/src/features/dynamicPrompts/store/selectors.ts b/invokeai/frontend/web/src/features/dynamicPrompts/store/selectors.ts
deleted file mode 100644
index 8337712ea5..0000000000
--- a/invokeai/frontend/web/src/features/dynamicPrompts/store/selectors.ts
+++ /dev/null
@@ -1 +0,0 @@
-//
diff --git a/invokeai/frontend/web/src/features/embedding/store/embeddingSlice.ts b/invokeai/frontend/web/src/features/embedding/store/embeddingSlice.ts
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GenericBoard.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GenericBoard.tsx
deleted file mode 100644
index 7a95e7fcd9..0000000000
--- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/GenericBoard.tsx
+++ /dev/null
@@ -1,108 +0,0 @@
-import { As, Badge, Flex } from '@chakra-ui/react';
-import IAIDroppable from 'common/components/IAIDroppable';
-import { IAINoContentFallback } from 'common/components/IAIImageFallback';
-import { TypesafeDroppableData } from 'features/dnd/types';
-import { BoardId } from 'features/gallery/store/types';
-import { ReactNode, memo } from 'react';
-import BoardContextMenu from '../BoardContextMenu';
-
-type GenericBoardProps = {
- board_id: BoardId;
- droppableData?: TypesafeDroppableData;
- onClick: () => void;
- isSelected: boolean;
- icon: As;
- label: string;
- dropLabel?: ReactNode;
- badgeCount?: number;
-};
-
-export const formatBadgeCount = (count: number) =>
- Intl.NumberFormat('en-US', {
- notation: 'compact',
- maximumFractionDigits: 1,
- }).format(count);
-
-const GenericBoard = (props: GenericBoardProps) => {
- const {
- board_id,
- droppableData,
- onClick,
- isSelected,
- icon,
- label,
- badgeCount,
- dropLabel,
- } = props;
-
- return (
-
- {(ref) => (
-
-
-
-
- {badgeCount !== undefined && (
- {formatBadgeCount(badgeCount)}
- )}
-
-
-
-
- {label}
-
-
- )}
-
- );
-};
-
-export default memo(GenericBoard);
diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/SystemBoardButton.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/SystemBoardButton.tsx
deleted file mode 100644
index 462aa4b5e6..0000000000
--- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardsList/SystemBoardButton.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import { createSelector } from '@reduxjs/toolkit';
-import { stateSelector } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
-import IAIButton from 'common/components/IAIButton';
-import { boardIdSelected } from 'features/gallery/store/gallerySlice';
-import { memo, useCallback, useMemo } from 'react';
-import { useBoardName } from 'services/api/hooks/useBoardName';
-
-type Props = {
- board_id: 'images' | 'assets' | 'no_board';
-};
-
-const SystemBoardButton = ({ board_id }: Props) => {
- const dispatch = useAppDispatch();
-
- const selector = useMemo(
- () =>
- createSelector(
- [stateSelector],
- ({ gallery }) => {
- const { selectedBoardId } = gallery;
- return { isSelected: selectedBoardId === board_id };
- },
- defaultSelectorOptions
- ),
- [board_id]
- );
-
- const { isSelected } = useAppSelector(selector);
-
- const boardName = useBoardName(board_id);
-
- const handleClick = useCallback(() => {
- dispatch(boardIdSelected({ boardId: board_id }));
- }, [board_id, dispatch]);
-
- return (
-
- {boardName}
-
- );
-};
-
-export default memo(SystemBoardButton);
diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageHidden.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageHidden.tsx
deleted file mode 100644
index af2a7c5f98..0000000000
--- a/invokeai/frontend/web/src/features/gallery/components/CurrentImage/CurrentImageHidden.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { Flex } from '@chakra-ui/react';
-import { memo } from 'react';
-import { FaEyeSlash } from 'react-icons/fa';
-
-const CurrentImageHidden = () => {
- return (
-
-
-
- );
-};
-
-export default memo(CurrentImageHidden);
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageFallbackSpinner.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageFallbackSpinner.tsx
deleted file mode 100644
index 95577efc13..0000000000
--- a/invokeai/frontend/web/src/features/gallery/components/ImageFallbackSpinner.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Flex, Spinner, SpinnerProps } from '@chakra-ui/react';
-import { memo } from 'react';
-
-type ImageFallbackSpinnerProps = SpinnerProps;
-
-const ImageFallbackSpinner = (props: ImageFallbackSpinnerProps) => {
- const { size = 'xl', ...rest } = props;
-
- return (
-
-
-
- );
-};
-
-export default memo(ImageFallbackSpinner);
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ClipInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ClipInputField.tsx
deleted file mode 100644
index cf5d7fae95..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ClipInputField.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import {
- ClipInputFieldTemplate,
- ClipInputFieldValue,
- FieldComponentProps,
-} from 'features/nodes/types/types';
-import { memo } from 'react';
-
-const ClipInputFieldComponent = (
- _props: FieldComponentProps
-) => {
- return null;
-};
-
-export default memo(ClipInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/CollectionInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/CollectionInputField.tsx
deleted file mode 100644
index 7cbc46f28c..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/CollectionInputField.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import {
- CollectionInputFieldTemplate,
- CollectionInputFieldValue,
- FieldComponentProps,
-} from 'features/nodes/types/types';
-import { memo } from 'react';
-
-const CollectionInputFieldComponent = (
- _props: FieldComponentProps<
- CollectionInputFieldValue,
- CollectionInputFieldTemplate
- >
-) => {
- return null;
-};
-
-export default memo(CollectionInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/CollectionItemInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/CollectionItemInputField.tsx
deleted file mode 100644
index e67a20bdfb..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/CollectionItemInputField.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import {
- CollectionItemInputFieldTemplate,
- CollectionItemInputFieldValue,
- FieldComponentProps,
-} from 'features/nodes/types/types';
-import { memo } from 'react';
-
-const CollectionItemInputFieldComponent = (
- _props: FieldComponentProps<
- CollectionItemInputFieldValue,
- CollectionItemInputFieldTemplate
- >
-) => {
- return null;
-};
-
-export default memo(CollectionItemInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ConditioningInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ConditioningInputField.tsx
deleted file mode 100644
index 9d174f40c5..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ConditioningInputField.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import {
- ConditioningInputFieldTemplate,
- ConditioningInputFieldValue,
- FieldComponentProps,
-} from 'features/nodes/types/types';
-import { memo } from 'react';
-
-const ConditioningInputFieldComponent = (
- _props: FieldComponentProps<
- ConditioningInputFieldValue,
- ConditioningInputFieldTemplate
- >
-) => {
- return null;
-};
-
-export default memo(ConditioningInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ControlInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ControlInputField.tsx
deleted file mode 100644
index 2aaac52615..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ControlInputField.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import {
- ControlInputFieldTemplate,
- ControlInputFieldValue,
- ControlPolymorphicInputFieldTemplate,
- ControlPolymorphicInputFieldValue,
- FieldComponentProps,
-} from 'features/nodes/types/types';
-import { memo } from 'react';
-
-const ControlInputFieldComponent = (
- _props: FieldComponentProps<
- ControlInputFieldValue | ControlPolymorphicInputFieldValue,
- ControlInputFieldTemplate | ControlPolymorphicInputFieldTemplate
- >
-) => {
- return null;
-};
-
-export default memo(ControlInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/DenoiseMaskInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/DenoiseMaskInputField.tsx
deleted file mode 100644
index 79b2668887..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/DenoiseMaskInputField.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import {
- DenoiseMaskInputFieldTemplate,
- DenoiseMaskInputFieldValue,
- FieldComponentProps,
-} from 'features/nodes/types/types';
-import { memo } from 'react';
-
-const DenoiseMaskInputFieldComponent = (
- _props: FieldComponentProps<
- DenoiseMaskInputFieldValue,
- DenoiseMaskInputFieldTemplate
- >
-) => {
- return null;
-};
-
-export default memo(DenoiseMaskInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/IPAdapterInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/IPAdapterInputField.tsx
deleted file mode 100644
index efeffe5723..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/IPAdapterInputField.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import {
- IPAdapterInputFieldTemplate,
- IPAdapterInputFieldValue,
- FieldComponentProps,
- IPAdapterPolymorphicInputFieldValue,
- IPAdapterPolymorphicInputFieldTemplate,
-} from 'features/nodes/types/types';
-import { memo } from 'react';
-
-const IPAdapterInputFieldComponent = (
- _props: FieldComponentProps<
- IPAdapterInputFieldValue | IPAdapterPolymorphicInputFieldValue,
- IPAdapterInputFieldTemplate | IPAdapterPolymorphicInputFieldTemplate
- >
-) => {
- return null;
-};
-
-export default memo(IPAdapterInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ImageCollectionInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ImageCollectionInputField.tsx
deleted file mode 100644
index 4a19f08614..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/ImageCollectionInputField.tsx
+++ /dev/null
@@ -1,94 +0,0 @@
-import {
- ImageCollectionInputFieldTemplate,
- ImageCollectionInputFieldValue,
- FieldComponentProps,
-} from 'features/nodes/types/types';
-import { memo } from 'react';
-
-import { Flex } from '@chakra-ui/react';
-import IAIDndImage from 'common/components/IAIDndImage';
-import IAIDropOverlay from 'common/components/IAIDropOverlay';
-import { useDroppableTypesafe } from 'features/dnd/hooks/typesafeHooks';
-import { NodesMultiImageDropData } from 'features/dnd/types';
-import { isValidDrop } from 'features/dnd/util/isValidDrop';
-import { useGetImageDTOQuery } from 'services/api/endpoints/images';
-
-const ImageCollectionInputFieldComponent = (
- props: FieldComponentProps<
- ImageCollectionInputFieldValue,
- ImageCollectionInputFieldTemplate
- >
-) => {
- const { nodeId, field } = props;
-
- // const dispatch = useAppDispatch();
-
- // const handleDrop = useCallback(
- // ({ image_name }: ImageDTO) => {
- // dispatch(
- // fieldValueChanged({
- // nodeId,
- // fieldName: field.name,
- // value: uniqBy([...(field.value ?? []), { image_name }], 'image_name'),
- // })
- // );
- // },
- // [dispatch, field.name, field.value, nodeId]
- // );
-
- const droppableData: NodesMultiImageDropData = {
- id: `node-${nodeId}-${field.name}`,
- actionType: 'SET_MULTI_NODES_IMAGE',
- context: { nodeId: nodeId, fieldName: field.name },
- };
-
- const {
- isOver,
- setNodeRef: setDroppableRef,
- active,
- } = useDroppableTypesafe({
- id: `node_${nodeId}`,
- data: droppableData,
- });
-
- // const handleReset = useCallback(() => {
- // dispatch(
- // fieldValueChanged({
- // nodeId,
- // fieldName: field.name,
- // value: undefined,
- // })
- // );
- // }, [dispatch, field.name, nodeId]);
-
- return (
-
- {field.value?.map(({ image_name }) => (
-
- ))}
- {isValidDrop(droppableData, active) && }
-
- );
-};
-
-export default memo(ImageCollectionInputFieldComponent);
-
-type ImageSubFieldProps = { imageName: string };
-
-const ImageSubField = (props: ImageSubFieldProps) => {
- const { currentData: image } = useGetImageDTOQuery(props.imageName);
-
- return (
-
- );
-};
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/LatentsInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/LatentsInputField.tsx
deleted file mode 100644
index a5065be0ee..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/LatentsInputField.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import {
- LatentsInputFieldTemplate,
- LatentsInputFieldValue,
- FieldComponentProps,
- LatentsPolymorphicInputFieldValue,
- LatentsPolymorphicInputFieldTemplate,
-} from 'features/nodes/types/types';
-import { memo } from 'react';
-
-const LatentsInputFieldComponent = (
- _props: FieldComponentProps<
- LatentsInputFieldValue | LatentsPolymorphicInputFieldValue,
- LatentsInputFieldTemplate | LatentsPolymorphicInputFieldTemplate
- >
-) => {
- return null;
-};
-
-export default memo(LatentsInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/T2IAdapterInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/T2IAdapterInputField.tsx
deleted file mode 100644
index 210adb6eff..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/T2IAdapterInputField.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import {
- T2IAdapterInputFieldTemplate,
- T2IAdapterInputFieldValue,
- T2IAdapterPolymorphicInputFieldTemplate,
- T2IAdapterPolymorphicInputFieldValue,
- FieldComponentProps,
-} from 'features/nodes/types/types';
-import { memo } from 'react';
-
-const T2IAdapterInputFieldComponent = (
- _props: FieldComponentProps<
- T2IAdapterInputFieldValue | T2IAdapterPolymorphicInputFieldValue,
- T2IAdapterInputFieldTemplate | T2IAdapterPolymorphicInputFieldTemplate
- >
-) => {
- return null;
-};
-
-export default memo(T2IAdapterInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/UnetInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/UnetInputField.tsx
deleted file mode 100644
index 2beefc7034..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/UnetInputField.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import {
- UNetInputFieldTemplate,
- UNetInputFieldValue,
- FieldComponentProps,
-} from 'features/nodes/types/types';
-import { memo } from 'react';
-
-const UNetInputFieldComponent = (
- _props: FieldComponentProps
-) => {
- return null;
-};
-
-export default memo(UNetInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/VaeInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/VaeInputField.tsx
deleted file mode 100644
index 738267faab..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/VaeInputField.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import {
- VaeInputFieldTemplate,
- VaeInputFieldValue,
- FieldComponentProps,
-} from 'features/nodes/types/types';
-import { memo } from 'react';
-
-const VaeInputFieldComponent = (
- _props: FieldComponentProps
-) => {
- return null;
-};
-
-export default memo(VaeInputFieldComponent);
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/common/NodeResizer.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/common/NodeResizer.tsx
deleted file mode 100644
index 6391e86471..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/common/NodeResizer.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { NODE_MIN_WIDTH } from 'features/nodes/types/constants';
-import { memo } from 'react';
-import { NodeResizeControl, NodeResizerProps } from 'reactflow';
-
-// this causes https://github.com/invoke-ai/InvokeAI/issues/4140
-// not using it for now
-
-const NodeResizer = (props: NodeResizerProps) => {
- const { ...rest } = props;
- return (
-
- );
-};
-
-export default memo(NodeResizer);
diff --git a/invokeai/frontend/web/src/features/nodes/components/sidePanel/inspector/InspectorDetailsTab.tsx b/invokeai/frontend/web/src/features/nodes/components/sidePanel/inspector/InspectorDetailsTab.tsx
deleted file mode 100644
index ffc260b95a..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/sidePanel/inspector/InspectorDetailsTab.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import { Box, Flex } from '@chakra-ui/react';
-import { createSelector } from '@reduxjs/toolkit';
-import { stateSelector } from 'app/store/store';
-import { useAppSelector } from 'app/store/storeHooks';
-import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
-import { IAINoContentFallback } from 'common/components/IAIImageFallback';
-import { InvocationTemplate, NodeData } from 'features/nodes/types/types';
-import { memo } from 'react';
-import NotesTextarea from '../../flow/nodes/Invocation/NotesTextarea';
-import NodeTitle from '../../flow/nodes/common/NodeTitle';
-import ScrollableContent from '../ScrollableContent';
-import { useTranslation } from 'react-i18next';
-
-const selector = createSelector(
- stateSelector,
- ({ nodes }) => {
- const lastSelectedNodeId =
- nodes.selectedNodes[nodes.selectedNodes.length - 1];
-
- const lastSelectedNode = nodes.nodes.find(
- (node) => node.id === lastSelectedNodeId
- );
-
- const lastSelectedNodeTemplate = lastSelectedNode
- ? nodes.nodeTemplates[lastSelectedNode.data.type]
- : undefined;
-
- return {
- data: lastSelectedNode?.data,
- template: lastSelectedNodeTemplate,
- };
- },
- defaultSelectorOptions
-);
-
-const InspectorDetailsTab = () => {
- const { data, template } = useAppSelector(selector);
- const { t } = useTranslation();
-
- if (!template || !data) {
- return (
-
- );
- }
-
- return ;
-};
-
-export default memo(InspectorDetailsTab);
-
-const Content = (props: { data: NodeData; template: InvocationTemplate }) => {
- const { data } = props;
-
- return (
-
-
-
-
-
-
-
-
- );
-};
diff --git a/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowNotesTab.tsx b/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowNotesTab.tsx
deleted file mode 100644
index d1ea0bcea1..0000000000
--- a/invokeai/frontend/web/src/features/nodes/components/sidePanel/workflow/WorkflowNotesTab.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import { Box, Text } from '@chakra-ui/react';
-import { createSelector } from '@reduxjs/toolkit';
-import { stateSelector } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAITextarea from 'common/components/IAITextarea';
-import { workflowNotesChanged } from 'features/nodes/store/nodesSlice';
-import { ChangeEvent, memo, useCallback } from 'react';
-
-const selector = createSelector(stateSelector, ({ nodes }) => {
- const { notes } = nodes.workflow;
-
- return {
- notes,
- };
-});
-
-const WorkflowNotesTab = () => {
- const { notes } = useAppSelector(selector);
- const dispatch = useAppDispatch();
-
- const handleChangeNotes = useCallback(
- (e: ChangeEvent) => {
- dispatch(workflowNotesChanged(e.target.value));
- },
- [dispatch]
- );
-
- return (
-
-
-
-
- {notes.length}
-
-
-
- );
-};
-
-export default memo(WorkflowNotesTab);
diff --git a/invokeai/frontend/web/src/features/nodes/store/util/makeTemplateSelector.ts b/invokeai/frontend/web/src/features/nodes/store/util/makeTemplateSelector.ts
deleted file mode 100644
index 2c4ec37f0b..0000000000
--- a/invokeai/frontend/web/src/features/nodes/store/util/makeTemplateSelector.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { createSelector } from '@reduxjs/toolkit';
-import { stateSelector } from 'app/store/store';
-import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
-import { AnyInvocationType } from 'services/events/types';
-
-export const makeTemplateSelector = (type: AnyInvocationType) =>
- createSelector(
- stateSelector,
- ({ nodes }) => nodes.nodeTemplates[type],
- defaultSelectorOptions
- );
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/BoundingBox/ParamBoundingBoxCollapse.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/BoundingBox/ParamBoundingBoxCollapse.tsx
deleted file mode 100644
index b9cc8511aa..0000000000
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/BoundingBox/ParamBoundingBoxCollapse.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { Flex } from '@chakra-ui/react';
-import IAICollapse from 'common/components/IAICollapse';
-import { memo } from 'react';
-import { useTranslation } from 'react-i18next';
-import ParamBoundingBoxHeight from './ParamBoundingBoxHeight';
-import ParamBoundingBoxWidth from './ParamBoundingBoxWidth';
-
-const ParamBoundingBoxCollapse = () => {
- const { t } = useTranslation();
-
- return (
-
-
-
-
-
-
- );
-};
-
-export default memo(ParamBoundingBoxCollapse);
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseThreshold.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseThreshold.tsx
deleted file mode 100644
index 7244800c41..0000000000
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamNoiseThreshold.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { createSelector } from '@reduxjs/toolkit';
-import { stateSelector } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
-import IAISlider from 'common/components/IAISlider';
-import { setThreshold } from 'features/parameters/store/generationSlice';
-import { useTranslation } from 'react-i18next';
-
-const selector = createSelector(
- stateSelector,
- (state) => {
- const { threshold } = state.generation;
- return {
- threshold,
- };
- },
- defaultSelectorOptions
-);
-
-export default function ParamNoiseThreshold() {
- const dispatch = useAppDispatch();
- const { threshold } = useAppSelector(selector);
- const { t } = useTranslation();
-
- return (
- dispatch(setThreshold(v))}
- handleReset={() => dispatch(setThreshold(0))}
- value={threshold}
- withInput
- withReset
- withSliderMarks
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamPerlinNoise.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamPerlinNoise.tsx
deleted file mode 100644
index b5429dc292..0000000000
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Noise/ParamPerlinNoise.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { createSelector } from '@reduxjs/toolkit';
-import { stateSelector } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
-import IAISlider from 'common/components/IAISlider';
-import { setPerlin } from 'features/parameters/store/generationSlice';
-import { useTranslation } from 'react-i18next';
-
-const selector = createSelector(
- stateSelector,
- (state) => {
- const { perlin } = state.generation;
- return {
- perlin,
- };
- },
- defaultSelectorOptions
-);
-
-export default function ParamPerlinNoise() {
- const dispatch = useAppDispatch();
- const { perlin } = useAppSelector(selector);
- const { t } = useTranslation();
-
- return (
- dispatch(setPerlin(v))}
- handleReset={() => dispatch(setPerlin(0))}
- value={perlin}
- withInput
- withReset
- withSliderMarks
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationAmount.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationAmount.tsx
deleted file mode 100644
index 9bc84a0bf4..0000000000
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationAmount.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import { RootState } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAISlider from 'common/components/IAISlider';
-import { setVariationAmount } from 'features/parameters/store/generationSlice';
-import { useTranslation } from 'react-i18next';
-
-export default function ParamVariationAmount() {
- const variationAmount = useAppSelector(
- (state: RootState) => state.generation.variationAmount
- );
-
- const shouldGenerateVariations = useAppSelector(
- (state: RootState) => state.generation.shouldGenerateVariations
- );
-
- const { t } = useTranslation();
-
- const dispatch = useAppDispatch();
-
- return (
- dispatch(setVariationAmount(v))}
- handleReset={() => dispatch(setVariationAmount(0.1))}
- withInput
- withReset
- withSliderMarks
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationCollapse.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationCollapse.tsx
deleted file mode 100644
index 7ea248498d..0000000000
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationCollapse.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-// TODO: variations
-
-// import { Flex } from '@chakra-ui/react';
-// import { createSelector } from '@reduxjs/toolkit';
-// import { stateSelector } from 'app/store/store';
-// import { useAppSelector } from 'app/store/storeHooks';
-// import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
-// import IAICollapse from 'common/components/IAICollapse';
-// import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
-// import { memo } from 'react';
-// import { useTranslation } from 'react-i18next';
-// import ParamVariationAmount from './ParamVariationAmount';
-// import { ParamVariationToggle } from './ParamVariationToggle';
-// import ParamVariationWeights from './ParamVariationWeights';
-
-// const selector = createSelector(
-// stateSelector,
-// (state) => {
-// const activeLabel = state.generation.shouldGenerateVariations
-// ? 'Enabled'
-// : undefined;
-
-// return { activeLabel };
-// },
-// defaultSelectorOptions
-// );
-
-// const ParamVariationCollapse = () => {
-// const { t } = useTranslation();
-// const { activeLabel } = useAppSelector(selector);
-
-// const isVariationEnabled = useFeatureStatus('variation').isFeatureEnabled;
-
-// if (!isVariationEnabled) {
-// return null;
-// }
-
-// return (
-//
-//
-//
-//
-//
-//
-//
-// );
-// };
-
-// export default memo(ParamVariationCollapse);
-
-export default {};
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationToggle.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationToggle.tsx
deleted file mode 100644
index 96929ea00a..0000000000
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationToggle.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import type { RootState } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAISwitch from 'common/components/IAISwitch';
-import { setShouldGenerateVariations } from 'features/parameters/store/generationSlice';
-import { ChangeEvent } from 'react';
-
-export const ParamVariationToggle = () => {
- const dispatch = useAppDispatch();
-
- const shouldGenerateVariations = useAppSelector(
- (state: RootState) => state.generation.shouldGenerateVariations
- );
-
- const handleChange = (e: ChangeEvent) =>
- dispatch(setShouldGenerateVariations(e.target.checked));
-
- return (
-
- );
-};
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationWeights.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationWeights.tsx
deleted file mode 100644
index 45029e8536..0000000000
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Variations/ParamVariationWeights.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-// TODO: variations
-
-// import { RootState } from 'app/store/store';
-// import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-// import IAIInput from 'common/components/IAIInput';
-// import { validateSeedWeights } from 'common/util/seedWeightPairs';
-// import { setSeedWeights } from 'features/parameters/store/generationSlice';
-// import { ChangeEvent } from 'react';
-// import { useTranslation } from 'react-i18next';
-
-// export default function ParamVariationWeights() {
-// const seedWeights = useAppSelector(
-// (state: RootState) => state.generation.seedWeights
-// );
-
-// const shouldGenerateVariations = useAppSelector(
-// (state: RootState) => state.generation.shouldGenerateVariations
-// );
-
-// const { t } = useTranslation();
-
-// const dispatch = useAppDispatch();
-
-// const handleChangeSeedWeights = (e: ChangeEvent) =>
-// dispatch(setSeedWeights(e.target.value));
-
-// return (
-//
-// );
-// }
-
-export default {};
diff --git a/invokeai/frontend/web/src/features/parameters/store/postprocessingSelectors.ts b/invokeai/frontend/web/src/features/parameters/store/postprocessingSelectors.ts
deleted file mode 100644
index 2908d16c54..0000000000
--- a/invokeai/frontend/web/src/features/parameters/store/postprocessingSelectors.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import { RootState } from 'app/store/store';
-
-export const postprocessingSelector = (state: RootState) =>
- state.postprocessing;
diff --git a/invokeai/frontend/web/src/features/queue/components/CurrentQueueItemCard.tsx b/invokeai/frontend/web/src/features/queue/components/CurrentQueueItemCard.tsx
deleted file mode 100644
index 2f7fc6fd8b..0000000000
--- a/invokeai/frontend/web/src/features/queue/components/CurrentQueueItemCard.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { memo } from 'react';
-import QueueItemCard from './common/QueueItemCard';
-import { useGetCurrentQueueItemQuery } from 'services/api/endpoints/queue';
-import { useTranslation } from 'react-i18next';
-
-const CurrentQueueItemCard = () => {
- const { t } = useTranslation();
- const { data: currentQueueItemData } = useGetCurrentQueueItemQuery();
-
- return (
-
- );
-};
-
-export default memo(CurrentQueueItemCard);
diff --git a/invokeai/frontend/web/src/features/queue/components/NextQueueItemCard.tsx b/invokeai/frontend/web/src/features/queue/components/NextQueueItemCard.tsx
deleted file mode 100644
index f9b9e874ab..0000000000
--- a/invokeai/frontend/web/src/features/queue/components/NextQueueItemCard.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { memo } from 'react';
-import { useTranslation } from 'react-i18next';
-import { useGetNextQueueItemQuery } from 'services/api/endpoints/queue';
-import QueueItemCard from './common/QueueItemCard';
-
-const NextQueueItemCard = () => {
- const { t } = useTranslation();
- const { data: nextQueueItemData } = useGetNextQueueItemQuery();
-
- return (
-
- );
-};
-
-export default memo(NextQueueItemCard);
diff --git a/invokeai/frontend/web/src/features/queue/components/QueueList/QueueItemSkeleton.tsx b/invokeai/frontend/web/src/features/queue/components/QueueList/QueueItemSkeleton.tsx
deleted file mode 100644
index 529c46af74..0000000000
--- a/invokeai/frontend/web/src/features/queue/components/QueueList/QueueItemSkeleton.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { Flex, Skeleton } from '@chakra-ui/react';
-import { memo } from 'react';
-import { COLUMN_WIDTHS } from './constants';
-
-const QueueItemSkeleton = () => {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-};
-
-export default memo(QueueItemSkeleton);
diff --git a/invokeai/frontend/web/src/features/queue/components/QueueStatusCard.tsx b/invokeai/frontend/web/src/features/queue/components/QueueStatusCard.tsx
deleted file mode 100644
index fb57500461..0000000000
--- a/invokeai/frontend/web/src/features/queue/components/QueueStatusCard.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import { Flex, Heading, Text } from '@chakra-ui/react';
-import { memo } from 'react';
-import { useTranslation } from 'react-i18next';
-import { useGetQueueStatusQuery } from 'services/api/endpoints/queue';
-
-const QueueStatusCard = () => {
- const { t } = useTranslation();
- const { data: queueStatus } = useGetQueueStatusQuery();
-
- return (
-
- {t('queue.status')}
-
-
- {t('queue.pending')}:{' '}
-
- {queueStatus?.queue.pending}
-
-
-
- {t('queue.in_progress')}:{' '}
-
- {queueStatus?.queue.in_progress}
-
-
-
- {t('queue.completed')}:{' '}
-
- {queueStatus?.queue.completed}
-
-
-
- {t('queue.failed')}:{' '}
-
- {queueStatus?.queue.failed}
-
-
-
- {t('queue.canceled')}:{' '}
-
- {queueStatus?.queue.canceled}
-
-
- );
-};
-
-export default memo(QueueStatusCard);
diff --git a/invokeai/frontend/web/src/features/queue/components/common/QueueItemCard.tsx b/invokeai/frontend/web/src/features/queue/components/common/QueueItemCard.tsx
deleted file mode 100644
index d441be4ecb..0000000000
--- a/invokeai/frontend/web/src/features/queue/components/common/QueueItemCard.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import { Flex, Heading, Text, Tooltip } from '@chakra-ui/react';
-import ScrollableContent from 'features/nodes/components/sidePanel/ScrollableContent';
-import { memo } from 'react';
-import { components } from 'services/api/schema';
-
-const QueueItemCard = ({
- session_queue_item,
- label,
-}: {
- session_queue_item?: components['schemas']['SessionQueueItem'] | null;
- label: string;
-}) => {
- return (
-
-
- {label}
- {session_queue_item && (
-
- {session_queue_item.batch_id}
-
- )}
-
- {session_queue_item && (
-
- Batch Values:
- {session_queue_item.field_values &&
- session_queue_item.field_values
- .filter((v) => v.node_path !== 'metadata_accumulator')
- .map(({ node_path, field_name, value }) => (
-
-
- {node_path}.{field_name}
-
- : {value}
-
- ))}
-
- )}
-
- );
-};
-
-export default memo(QueueItemCard);
diff --git a/invokeai/frontend/web/src/features/queue/components/common/QueueStatusDot.tsx b/invokeai/frontend/web/src/features/queue/components/common/QueueStatusDot.tsx
deleted file mode 100644
index 6a500cada2..0000000000
--- a/invokeai/frontend/web/src/features/queue/components/common/QueueStatusDot.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import { Box } from '@chakra-ui/react';
-import { memo, useMemo } from 'react';
-import { SessionQueueItemStatus } from 'services/api/endpoints/queue';
-
-const STATUSES = {
- pending: { colorScheme: 'cyan', translationKey: 'queue.pending' },
- in_progress: { colorScheme: 'yellow', translationKey: 'queue.in_progress' },
- completed: { colorScheme: 'green', translationKey: 'queue.completed' },
- failed: { colorScheme: 'red', translationKey: 'queue.failed' },
- canceled: { colorScheme: 'orange', translationKey: 'queue.canceled' },
-};
-
-const QueueStatusDot = ({ status }: { status: SessionQueueItemStatus }) => {
- const sx = useMemo(
- () => ({
- w: 2,
- h: 2,
- bg: `${STATUSES[status].colorScheme}.${500}`,
- _dark: {
- bg: `${STATUSES[status].colorScheme}.${400}`,
- },
- borderRadius: '100%',
- }),
- [status]
- );
- return ;
-};
-export default memo(QueueStatusDot);
diff --git a/invokeai/frontend/web/src/features/queue/util/formatNumberShort.ts b/invokeai/frontend/web/src/features/queue/util/formatNumberShort.ts
deleted file mode 100644
index 9cc300c960..0000000000
--- a/invokeai/frontend/web/src/features/queue/util/formatNumberShort.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export const formatNumberShort = (num: number) =>
- Intl.NumberFormat('en-US', {
- notation: 'standard',
- }).format(num);
diff --git a/invokeai/frontend/web/src/features/system/components/SettingsModal/ResetWebUIButton.tsx b/invokeai/frontend/web/src/features/system/components/SettingsModal/ResetWebUIButton.tsx
deleted file mode 100644
index 9617d0cd34..0000000000
--- a/invokeai/frontend/web/src/features/system/components/SettingsModal/ResetWebUIButton.tsx
+++ /dev/null
@@ -1,82 +0,0 @@
-import {
- Flex,
- Modal,
- ModalBody,
- ModalContent,
- ModalFooter,
- ModalHeader,
- ModalOverlay,
- Text,
- useDisclosure,
-} from '@chakra-ui/react';
-import { LOCALSTORAGE_KEYS, LOCALSTORAGE_PREFIX } from 'app/store/constants';
-import IAIButton from 'common/components/IAIButton';
-import { memo, useCallback, useEffect, useState } from 'react';
-import { useTranslation } from 'react-i18next';
-
-type Props = {
- onSettingsModalClose: () => void;
-};
-
-const ResetWebUIButton = ({ onSettingsModalClose }: Props) => {
- const { t } = useTranslation();
- const [countdown, setCountdown] = useState(5);
-
- const {
- isOpen: isRefreshModalOpen,
- onOpen: onRefreshModalOpen,
- onClose: onRefreshModalClose,
- } = useDisclosure();
-
- const handleClickResetWebUI = useCallback(() => {
- // Only remove our keys
- Object.keys(window.localStorage).forEach((key) => {
- if (
- LOCALSTORAGE_KEYS.includes(key) ||
- key.startsWith(LOCALSTORAGE_PREFIX)
- ) {
- localStorage.removeItem(key);
- }
- });
- onSettingsModalClose();
- onRefreshModalOpen();
- setInterval(() => setCountdown((prev) => prev - 1), 1000);
- }, [onSettingsModalClose, onRefreshModalOpen]);
-
- useEffect(() => {
- if (countdown <= 0) {
- window.location.reload();
- }
- }, [countdown]);
-
- return (
- <>
-
- {t('settings.resetWebUI')}
-
-
-
-
-
-
-
-
- {t('settings.resetComplete')}
- Reloading in {countdown}...
-
-
-
-
-
-
- >
- );
-};
-
-export default memo(ResetWebUIButton);
diff --git a/invokeai/frontend/web/src/features/system/store/actions.ts b/invokeai/frontend/web/src/features/system/store/actions.ts
deleted file mode 100644
index 66181bc803..0000000000
--- a/invokeai/frontend/web/src/features/system/store/actions.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-import { createAction } from '@reduxjs/toolkit';
-
-export const sessionReadyToInvoke = createAction('system/sessionReadyToInvoke');
diff --git a/invokeai/frontend/web/src/features/system/store/sessionSlice.ts b/invokeai/frontend/web/src/features/system/store/sessionSlice.ts
deleted file mode 100644
index 40d59c7baa..0000000000
--- a/invokeai/frontend/web/src/features/system/store/sessionSlice.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-// TODO: split system slice inot this
-
-// import type { PayloadAction } from '@reduxjs/toolkit';
-// import { createSlice } from '@reduxjs/toolkit';
-// import { socketSubscribed, socketUnsubscribed } from 'services/events/actions';
-
-// export type SessionState = {
-// /**
-// * The current socket session id
-// */
-// sessionId: string;
-// /**
-// * Whether the current session is a canvas session. Needed to manage the staging area.
-// */
-// isCanvasSession: boolean;
-// /**
-// * When a session is canceled, its ID is stored here until a new session is created.
-// */
-// canceledSessionId: string;
-// };
-
-// export const initialSessionState: SessionState = {
-// sessionId: '',
-// isCanvasSession: false,
-// canceledSessionId: '',
-// };
-
-// export const sessionSlice = createSlice({
-// name: 'session',
-// initialState: initialSessionState,
-// reducers: {
-// sessionIdChanged: (state, action: PayloadAction) => {
-// state.sessionId = action.payload;
-// },
-// isCanvasSessionChanged: (state, action: PayloadAction) => {
-// state.isCanvasSession = action.payload;
-// },
-// },
-// extraReducers: (builder) => {
-// /**
-// * Socket Subscribed
-// */
-// builder.addCase(socketSubscribed, (state, action) => {
-// state.sessionId = action.payload.sessionId;
-// state.canceledSessionId = '';
-// });
-
-// /**
-// * Socket Unsubscribed
-// */
-// builder.addCase(socketUnsubscribed, (state) => {
-// state.sessionId = '';
-// });
-// },
-// });
-
-// export const { sessionIdChanged, isCanvasSessionChanged } =
-// sessionSlice.actions;
-
-// export default sessionSlice.reducer;
-
-export default {};
diff --git a/invokeai/frontend/web/src/features/ui/components/common/OverlayScrollable.tsx b/invokeai/frontend/web/src/features/ui/components/common/OverlayScrollable.tsx
deleted file mode 100644
index 722ee46fd5..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/common/OverlayScrollable.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
-import { PropsWithChildren, memo } from 'react';
-const OverlayScrollable = (props: PropsWithChildren) => {
- return (
-
- {props.children}
-
- );
-};
-export default memo(OverlayScrollable);
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/store/modelmanagerSelectors.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/store/modelmanagerSelectors.tsx
deleted file mode 100644
index 593282760a..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/store/modelmanagerSelectors.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-import { RootState } from 'app/store/store';
-
-export const modelmanagerSelector = (state: RootState) => state.modelmanager;
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasBaseBrushSettings.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasBaseBrushSettings.tsx
deleted file mode 100644
index 9b9310b197..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasBaseBrushSettings.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Flex } from '@chakra-ui/react';
-import UnifiedCanvasBrushSettings from './UnifiedCanvasBrushSettings';
-import UnifiedCanvasLimitStrokesToBox from './UnifiedCanvasLimitStrokesToBox';
-
-export default function UnifiedCanvasBaseBrushSettings() {
- return (
-
-
-
-
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasBrushSettings.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasBrushSettings.tsx
deleted file mode 100644
index 1a5e42461b..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasBrushSettings.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Flex } from '@chakra-ui/react';
-import UnifiedCanvasBrushSize from './UnifiedCanvasBrushSize';
-import UnifiedCanvasColorPicker from './UnifiedCanvasColorPicker';
-
-export default function UnifiedCanvasBrushSettings() {
- return (
-
-
-
-
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasBrushSize.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasBrushSize.tsx
deleted file mode 100644
index 0792b787cd..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasBrushSize.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import { RootState } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAISlider from 'common/components/IAISlider';
-import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
-import { setBrushSize } from 'features/canvas/store/canvasSlice';
-import { useHotkeys } from 'react-hotkeys-hook';
-import { useTranslation } from 'react-i18next';
-
-export default function UnifiedCanvasBrushSize() {
- const dispatch = useAppDispatch();
-
- const brushSize = useAppSelector(
- (state: RootState) => state.canvas.brushSize
- );
-
- const { t } = useTranslation();
-
- const isStaging = useAppSelector(isStagingSelector);
-
- useHotkeys(
- ['BracketLeft'],
- () => {
- dispatch(setBrushSize(Math.max(brushSize - 5, 5)));
- },
- {
- enabled: () => !isStaging,
- preventDefault: true,
- },
- [brushSize]
- );
-
- useHotkeys(
- ['BracketRight'],
- () => {
- dispatch(setBrushSize(Math.min(brushSize + 5, 500)));
- },
- {
- enabled: () => !isStaging,
- preventDefault: true,
- },
- [brushSize]
- );
-
- return (
- dispatch(setBrushSize(newSize))}
- sliderNumberInputProps={{ max: 500 }}
- isCompact
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasClearMask.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasClearMask.tsx
deleted file mode 100644
index 325afa7327..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasClearMask.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { useAppDispatch } from 'app/store/storeHooks';
-import IAIButton from 'common/components/IAIButton';
-
-import { clearMask } from 'features/canvas/store/canvasSlice';
-import { useTranslation } from 'react-i18next';
-
-import { FaTrash } from 'react-icons/fa';
-
-export default function UnifiedCanvasClearMask() {
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
-
- const handleClearMask = () => dispatch(clearMask());
-
- return (
- }
- onClick={handleClearMask}
- tooltip={`${t('unifiedCanvas.clearMask')} (Shift+C)`}
- >
- {t('unifiedCanvas.betaClear')}
-
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasColorPicker.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasColorPicker.tsx
deleted file mode 100644
index e57d87915f..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasColorPicker.tsx
+++ /dev/null
@@ -1,128 +0,0 @@
-import { Box, Flex } from '@chakra-ui/react';
-import { createSelector } from '@reduxjs/toolkit';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAIColorPicker from 'common/components/IAIColorPicker';
-import IAIPopover from 'common/components/IAIPopover';
-import {
- canvasSelector,
- isStagingSelector,
-} from 'features/canvas/store/canvasSelectors';
-import { setBrushColor, setMaskColor } from 'features/canvas/store/canvasSlice';
-import { clamp, isEqual } from 'lodash-es';
-
-import { useHotkeys } from 'react-hotkeys-hook';
-
-const selector = createSelector(
- [canvasSelector, isStagingSelector],
- (canvas, isStaging) => {
- const { brushColor, maskColor, layer } = canvas;
- return {
- brushColor,
- maskColor,
- layer,
- isStaging,
- };
- },
- {
- memoizeOptions: {
- resultEqualityCheck: isEqual,
- },
- }
-);
-
-export default function UnifiedCanvasColorPicker() {
- const dispatch = useAppDispatch();
- const { brushColor, maskColor, layer, isStaging } = useAppSelector(selector);
-
- const currentColorDisplay = () => {
- if (layer === 'base') {
- return `rgba(${brushColor.r},${brushColor.g},${brushColor.b},${brushColor.a})`;
- }
- if (layer === 'mask') {
- return `rgba(${maskColor.r},${maskColor.g},${maskColor.b},${maskColor.a})`;
- }
- };
-
- useHotkeys(
- ['shift+BracketLeft'],
- () => {
- dispatch(
- setBrushColor({
- ...brushColor,
- a: clamp(brushColor.a - 0.05, 0.05, 1),
- })
- );
- },
- {
- enabled: () => !isStaging,
- preventDefault: true,
- },
- [brushColor]
- );
-
- useHotkeys(
- ['shift+BracketRight'],
- () => {
- dispatch(
- setBrushColor({
- ...brushColor,
- a: clamp(brushColor.a + 0.05, 0.05, 1),
- })
- );
- },
- {
- enabled: () => !isStaging,
- preventDefault: true,
- },
- [brushColor]
- );
-
- return (
-
- }
- >
-
- {layer === 'base' && (
-
- dispatch(setBrushColor(newColor))}
- />
-
- )}
- {layer === 'mask' && (
-
- dispatch(setMaskColor(newColor))}
- />
-
- )}
-
-
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasDarkenOutsideSelection.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasDarkenOutsideSelection.tsx
deleted file mode 100644
index 53e36f62b6..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasDarkenOutsideSelection.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { RootState } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAISimpleCheckbox from 'common/components/IAISimpleCheckbox';
-import { setShouldDarkenOutsideBoundingBox } from 'features/canvas/store/canvasSlice';
-import { useTranslation } from 'react-i18next';
-
-export default function UnifiedCanvasDarkenOutsideSelection() {
- const shouldDarkenOutsideBoundingBox = useAppSelector(
- (state: RootState) => state.canvas.shouldDarkenOutsideBoundingBox
- );
-
- const dispatch = useAppDispatch();
-
- const { t } = useTranslation();
-
- return (
-
- dispatch(setShouldDarkenOutsideBoundingBox(e.target.checked))
- }
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasEnableMask.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasEnableMask.tsx
deleted file mode 100644
index ceb58cb5ca..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasEnableMask.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { RootState } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAISimpleCheckbox from 'common/components/IAISimpleCheckbox';
-import { setIsMaskEnabled } from 'features/canvas/store/canvasSlice';
-import { useTranslation } from 'react-i18next';
-
-export default function UnifiedCanvasEnableMask() {
- const isMaskEnabled = useAppSelector(
- (state: RootState) => state.canvas.isMaskEnabled
- );
-
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
-
- const handleToggleEnableMask = () =>
- dispatch(setIsMaskEnabled(!isMaskEnabled));
-
- return (
-
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasLimitStrokesToBox.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasLimitStrokesToBox.tsx
deleted file mode 100644
index 65f77c582f..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasLimitStrokesToBox.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import { RootState } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAISimpleCheckbox from 'common/components/IAISimpleCheckbox';
-import { setShouldRestrictStrokesToBox } from 'features/canvas/store/canvasSlice';
-import { useTranslation } from 'react-i18next';
-
-export default function UnifiedCanvasLimitStrokesToBox() {
- const dispatch = useAppDispatch();
-
- const shouldRestrictStrokesToBox = useAppSelector(
- (state: RootState) => state.canvas.shouldRestrictStrokesToBox
- );
-
- const { t } = useTranslation();
-
- return (
-
- dispatch(setShouldRestrictStrokesToBox(e.target.checked))
- }
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasMaskBrushSettings.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasMaskBrushSettings.tsx
deleted file mode 100644
index 71f41496ed..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasMaskBrushSettings.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import { Flex } from '@chakra-ui/react';
-import UnifiedCanvasBrushSettings from './UnifiedCanvasBrushSettings';
-import UnifiedCanvasClearMask from './UnifiedCanvasClearMask';
-import UnifiedCanvasEnableMask from './UnifiedCanvasEnableMask';
-import UnifiedCanvasPreserveMask from './UnifiedCanvasPreserveMask';
-
-export default function UnifiedCanvasMaskBrushSettings() {
- return (
-
-
-
-
-
-
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasMoveSettings.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasMoveSettings.tsx
deleted file mode 100644
index 8881c93bb1..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasMoveSettings.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import { Flex } from '@chakra-ui/layout';
-import UnifiedCanvasDarkenOutsideSelection from './UnifiedCanvasDarkenOutsideSelection';
-import UnifiedCanvasShowGrid from './UnifiedCanvasShowGrid';
-import UnifiedCanvasSnapToGrid from './UnifiedCanvasSnapToGrid';
-
-export default function UnifiedCanvasMoveSettings() {
- return (
-
-
-
-
-
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasPreserveMask.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasPreserveMask.tsx
deleted file mode 100644
index fd3396533c..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasPreserveMask.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { RootState } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAISimpleCheckbox from 'common/components/IAISimpleCheckbox';
-import { setShouldPreserveMaskedArea } from 'features/canvas/store/canvasSlice';
-import { useTranslation } from 'react-i18next';
-
-export default function UnifiedCanvasPreserveMask() {
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
-
- const shouldPreserveMaskedArea = useAppSelector(
- (state: RootState) => state.canvas.shouldPreserveMaskedArea
- );
-
- return (
- dispatch(setShouldPreserveMaskedArea(e.target.checked))}
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasSettings.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasSettings.tsx
deleted file mode 100644
index 22737ce0bb..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasSettings.tsx
+++ /dev/null
@@ -1,113 +0,0 @@
-import { Flex } from '@chakra-ui/react';
-import { createSelector } from '@reduxjs/toolkit';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAISimpleCheckbox from 'common/components/IAISimpleCheckbox';
-import IAIIconButton from 'common/components/IAIIconButton';
-import IAIPopover from 'common/components/IAIPopover';
-import { canvasSelector } from 'features/canvas/store/canvasSelectors';
-import {
- setShouldAntialias,
- setShouldAutoSave,
- setShouldCropToBoundingBoxOnSave,
- setShouldShowCanvasDebugInfo,
- setShouldShowIntermediates,
-} from 'features/canvas/store/canvasSlice';
-
-import { FaWrench } from 'react-icons/fa';
-
-import ClearCanvasHistoryButtonModal from 'features/canvas/components/ClearCanvasHistoryButtonModal';
-import { isEqual } from 'lodash-es';
-import { useTranslation } from 'react-i18next';
-import { memo } from 'react';
-
-export const canvasControlsSelector = createSelector(
- [canvasSelector],
- (canvas) => {
- const {
- shouldAutoSave,
- shouldCropToBoundingBoxOnSave,
- shouldShowCanvasDebugInfo,
- shouldShowIntermediates,
- shouldAntialias,
- } = canvas;
-
- return {
- shouldAutoSave,
- shouldCropToBoundingBoxOnSave,
- shouldShowCanvasDebugInfo,
- shouldShowIntermediates,
- shouldAntialias,
- };
- },
- {
- memoizeOptions: {
- resultEqualityCheck: isEqual,
- },
- }
-);
-
-const UnifiedCanvasSettings = () => {
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
-
- const {
- shouldAutoSave,
- shouldCropToBoundingBoxOnSave,
- shouldShowCanvasDebugInfo,
- shouldShowIntermediates,
- shouldAntialias,
- } = useAppSelector(canvasControlsSelector);
-
- return (
- }
- />
- }
- >
-
-
- dispatch(setShouldShowIntermediates(e.target.checked))
- }
- />
- dispatch(setShouldAutoSave(e.target.checked))}
- />
-
- dispatch(setShouldCropToBoundingBoxOnSave(e.target.checked))
- }
- />
-
- dispatch(setShouldShowCanvasDebugInfo(e.target.checked))
- }
- />
- dispatch(setShouldAntialias(e.target.checked))}
- />
-
-
-
- );
-};
-
-export default memo(UnifiedCanvasSettings);
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasShowGrid.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasShowGrid.tsx
deleted file mode 100644
index e17f74ce41..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasShowGrid.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { RootState } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAISimpleCheckbox from 'common/components/IAISimpleCheckbox';
-import { setShouldShowGrid } from 'features/canvas/store/canvasSlice';
-import { useTranslation } from 'react-i18next';
-
-export default function UnifiedCanvasShowGrid() {
- const shouldShowGrid = useAppSelector(
- (state: RootState) => state.canvas.shouldShowGrid
- );
-
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
-
- return (
- dispatch(setShouldShowGrid(e.target.checked))}
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasSnapToGrid.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasSnapToGrid.tsx
deleted file mode 100644
index 69e9a4e78b..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettings/UnifiedCanvasSnapToGrid.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { RootState } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAISimpleCheckbox from 'common/components/IAISimpleCheckbox';
-import { setShouldSnapToGrid } from 'features/canvas/store/canvasSlice';
-import { ChangeEvent } from 'react';
-import { useTranslation } from 'react-i18next';
-
-export default function UnifiedCanvasSnapToGrid() {
- const shouldSnapToGrid = useAppSelector(
- (state: RootState) => state.canvas.shouldSnapToGrid
- );
-
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
-
- const handleChangeShouldSnapToGrid = (e: ChangeEvent) =>
- dispatch(setShouldSnapToGrid(e.target.checked));
-
- return (
-
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettingsBeta.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettingsBeta.tsx
deleted file mode 100644
index e5503ac203..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolSettingsBeta.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { createSelector } from '@reduxjs/toolkit';
-import { useAppSelector } from 'app/store/storeHooks';
-import { canvasSelector } from 'features/canvas/store/canvasSelectors';
-
-import { Flex } from '@chakra-ui/react';
-import { isEqual } from 'lodash-es';
-import UnifiedCanvasBaseBrushSettings from './UnifiedCanvasToolSettings/UnifiedCanvasBaseBrushSettings';
-import UnifiedCanvasMaskBrushSettings from './UnifiedCanvasToolSettings/UnifiedCanvasMaskBrushSettings';
-import UnifiedCanvasMoveSettings from './UnifiedCanvasToolSettings/UnifiedCanvasMoveSettings';
-
-const selector = createSelector(
- [canvasSelector],
- (canvas) => {
- const { tool, layer } = canvas;
- return {
- tool,
- layer,
- };
- },
- {
- memoizeOptions: {
- resultEqualityCheck: isEqual,
- },
- }
-);
-
-export default function UnifiedCanvasToolSettingsBeta() {
- const { tool, layer } = useAppSelector(selector);
-
- return (
-
- {layer == 'base' && ['brush', 'eraser', 'colorPicker'].includes(tool) && (
-
- )}
- {layer == 'mask' && ['brush', 'eraser', 'colorPicker'].includes(tool) && (
-
- )}
- {tool == 'move' && }
-
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasCopyToClipboard.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasCopyToClipboard.tsx
deleted file mode 100644
index a865bcd0de..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasCopyToClipboard.tsx
+++ /dev/null
@@ -1,50 +0,0 @@
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAIIconButton from 'common/components/IAIIconButton';
-import { canvasCopiedToClipboard } from 'features/canvas/store/actions';
-import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
-import { useCopyImageToClipboard } from 'features/ui/hooks/useCopyImageToClipboard';
-import { useCallback } from 'react';
-import { useHotkeys } from 'react-hotkeys-hook';
-import { useTranslation } from 'react-i18next';
-import { FaCopy } from 'react-icons/fa';
-
-export default function UnifiedCanvasCopyToClipboard() {
- const isStaging = useAppSelector(isStagingSelector);
- const { isClipboardAPIAvailable } = useCopyImageToClipboard();
-
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
-
- useHotkeys(
- ['meta+c', 'ctrl+c'],
- () => {
- handleCopyImageToClipboard();
- },
- {
- enabled: () => !isStaging && isClipboardAPIAvailable,
- preventDefault: true,
- },
- [isClipboardAPIAvailable]
- );
-
- const handleCopyImageToClipboard = useCallback(() => {
- if (!isClipboardAPIAvailable) {
- return;
- }
- dispatch(canvasCopiedToClipboard());
- }, [dispatch, isClipboardAPIAvailable]);
-
- if (!isClipboardAPIAvailable) {
- return null;
- }
-
- return (
- }
- onClick={handleCopyImageToClipboard}
- isDisabled={isStaging}
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasDownloadImage.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasDownloadImage.tsx
deleted file mode 100644
index 1039c5f364..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasDownloadImage.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAIIconButton from 'common/components/IAIIconButton';
-import { canvasDownloadedAsImage } from 'features/canvas/store/actions';
-import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
-import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
-import { useHotkeys } from 'react-hotkeys-hook';
-import { useTranslation } from 'react-i18next';
-import { FaDownload } from 'react-icons/fa';
-
-export default function UnifiedCanvasDownloadImage() {
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
-
- const canvasBaseLayer = getCanvasBaseLayer();
-
- const isStaging = useAppSelector(isStagingSelector);
-
- useHotkeys(
- ['shift+d'],
- () => {
- handleDownloadAsImage();
- },
- {
- enabled: () => !isStaging,
- preventDefault: true,
- },
- [canvasBaseLayer]
- );
-
- const handleDownloadAsImage = () => {
- dispatch(canvasDownloadedAsImage());
- };
-
- return (
- }
- onClick={handleDownloadAsImage}
- isDisabled={isStaging}
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasFileUploader.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasFileUploader.tsx
deleted file mode 100644
index ac83e7f20b..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasFileUploader.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import { useAppSelector } from 'app/store/storeHooks';
-import IAIIconButton from 'common/components/IAIIconButton';
-import { useImageUploadButton } from 'common/hooks/useImageUploadButton';
-import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
-import { useTranslation } from 'react-i18next';
-import { FaUpload } from 'react-icons/fa';
-
-export default function UnifiedCanvasFileUploader() {
- const isStaging = useAppSelector(isStagingSelector);
-
- const { getUploadButtonProps, getUploadInputProps } = useImageUploadButton({
- postUploadAction: { type: 'SET_CANVAS_INITIAL_IMAGE' },
- });
- const { t } = useTranslation();
-
- return (
- <>
- }
- isDisabled={isStaging}
- {...getUploadButtonProps()}
- />
-
- >
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasLayerSelect.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasLayerSelect.tsx
deleted file mode 100644
index d7fb9d8201..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasLayerSelect.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import { createSelector } from '@reduxjs/toolkit';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAIMantineSelect from 'common/components/IAIMantineSelect';
-import {
- canvasSelector,
- isStagingSelector,
-} from 'features/canvas/store/canvasSelectors';
-import { setIsMaskEnabled, setLayer } from 'features/canvas/store/canvasSlice';
-import {
- CanvasLayer,
- LAYER_NAMES_DICT,
-} from 'features/canvas/store/canvasTypes';
-import { isEqual } from 'lodash-es';
-
-import { useHotkeys } from 'react-hotkeys-hook';
-import { useTranslation } from 'react-i18next';
-
-const selector = createSelector(
- [canvasSelector, isStagingSelector],
- (canvas, isStaging) => {
- const { layer, isMaskEnabled } = canvas;
- return { layer, isMaskEnabled, isStaging };
- },
- {
- memoizeOptions: {
- resultEqualityCheck: isEqual,
- },
- }
-);
-
-export default function UnifiedCanvasLayerSelect() {
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
-
- const { layer, isMaskEnabled, isStaging } = useAppSelector(selector);
-
- const handleToggleMaskLayer = () => {
- dispatch(setLayer(layer === 'mask' ? 'base' : 'mask'));
- };
-
- useHotkeys(
- ['q'],
- () => {
- handleToggleMaskLayer();
- },
- {
- enabled: () => !isStaging,
- preventDefault: true,
- },
- [layer]
- );
-
- const handleChangeLayer = (v: string) => {
- const newLayer = v as CanvasLayer;
- dispatch(setLayer(newLayer));
- if (newLayer === 'mask' && !isMaskEnabled) {
- dispatch(setIsMaskEnabled(true));
- }
- };
- return (
-
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasMergeVisible.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasMergeVisible.tsx
deleted file mode 100644
index 66c378e068..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasMergeVisible.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAIIconButton from 'common/components/IAIIconButton';
-import { canvasMerged } from 'features/canvas/store/actions';
-import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
-import { useHotkeys } from 'react-hotkeys-hook';
-import { useTranslation } from 'react-i18next';
-import { FaLayerGroup } from 'react-icons/fa';
-export default function UnifiedCanvasMergeVisible() {
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
- const isStaging = useAppSelector(isStagingSelector);
-
- useHotkeys(
- ['shift+m'],
- () => {
- handleMergeVisible();
- },
- {
- enabled: () => !isStaging,
- preventDefault: true,
- },
- []
- );
-
- const handleMergeVisible = () => {
- dispatch(canvasMerged());
- };
- return (
- }
- onClick={handleMergeVisible}
- isDisabled={isStaging}
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasMoveTool.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasMoveTool.tsx
deleted file mode 100644
index 5362657def..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasMoveTool.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { RootState } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAIIconButton from 'common/components/IAIIconButton';
-import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
-import { setTool } from 'features/canvas/store/canvasSlice';
-import { useHotkeys } from 'react-hotkeys-hook';
-import { useTranslation } from 'react-i18next';
-import { FaArrowsAlt } from 'react-icons/fa';
-
-export default function UnifiedCanvasMoveTool() {
- const tool = useAppSelector((state: RootState) => state.canvas.tool);
- const isStaging = useAppSelector(isStagingSelector);
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
-
- useHotkeys(
- ['v'],
- () => {
- handleSelectMoveTool();
- },
- {
- enabled: () => !isStaging,
- preventDefault: true,
- },
- []
- );
-
- const handleSelectMoveTool = () => dispatch(setTool('move'));
-
- return (
- }
- isChecked={tool === 'move' || isStaging}
- onClick={handleSelectMoveTool}
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasResetCanvas.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasResetCanvas.tsx
deleted file mode 100644
index 85396c87be..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasResetCanvas.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAIIconButton from 'common/components/IAIIconButton';
-import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
-import { resetCanvas } from 'features/canvas/store/canvasSlice';
-import { useTranslation } from 'react-i18next';
-import { FaTrash } from 'react-icons/fa';
-
-export default function UnifiedCanvasResetCanvas() {
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
- const isStaging = useAppSelector(isStagingSelector);
-
- const handleResetCanvas = () => {
- dispatch(resetCanvas());
- };
- return (
- }
- onClick={handleResetCanvas}
- isDisabled={isStaging}
- colorScheme="error"
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasResetView.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasResetView.tsx
deleted file mode 100644
index 7d0478476e..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasResetView.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import { useAppDispatch } from 'app/store/storeHooks';
-import IAIIconButton from 'common/components/IAIIconButton';
-import { useSingleAndDoubleClick } from 'common/hooks/useSingleAndDoubleClick';
-import { resetCanvasView } from 'features/canvas/store/canvasSlice';
-import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
-import { useHotkeys } from 'react-hotkeys-hook';
-import { useTranslation } from 'react-i18next';
-import { FaCrosshairs } from 'react-icons/fa';
-
-export default function UnifiedCanvasResetView() {
- const canvasBaseLayer = getCanvasBaseLayer();
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
-
- useHotkeys(
- ['r'],
- () => {
- handleResetCanvasView();
- },
- {
- enabled: () => true,
- preventDefault: true,
- },
- [canvasBaseLayer]
- );
-
- const handleClickResetCanvasView = useSingleAndDoubleClick(
- () => handleResetCanvasView(false),
- () => handleResetCanvasView(true)
- );
-
- const handleResetCanvasView = (shouldScaleTo1 = false) => {
- const canvasBaseLayer = getCanvasBaseLayer();
- if (!canvasBaseLayer) {
- return;
- }
- const clientRect = canvasBaseLayer.getClientRect({
- skipTransform: true,
- });
- dispatch(
- resetCanvasView({
- contentRect: clientRect,
- shouldScaleTo1,
- })
- );
- };
- return (
- }
- onClick={handleClickResetCanvasView}
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasSaveToGallery.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasSaveToGallery.tsx
deleted file mode 100644
index 31617a4dbe..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasSaveToGallery.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAIIconButton from 'common/components/IAIIconButton';
-import { canvasSavedToGallery } from 'features/canvas/store/actions';
-import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
-import { useHotkeys } from 'react-hotkeys-hook';
-import { useTranslation } from 'react-i18next';
-import { FaSave } from 'react-icons/fa';
-
-export default function UnifiedCanvasSaveToGallery() {
- const isStaging = useAppSelector(isStagingSelector);
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
-
- useHotkeys(
- ['shift+s'],
- () => {
- handleSaveToGallery();
- },
- {
- enabled: () => !isStaging,
- preventDefault: true,
- },
- []
- );
-
- const handleSaveToGallery = () => {
- dispatch(canvasSavedToGallery());
- };
-
- return (
- }
- onClick={handleSaveToGallery}
- isDisabled={isStaging}
- />
- );
-}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasToolSelect.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasToolSelect.tsx
deleted file mode 100644
index 59a0890960..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbar/UnifiedCanvasToolSelect.tsx
+++ /dev/null
@@ -1,172 +0,0 @@
-import { ButtonGroup, Flex } from '@chakra-ui/react';
-import { createSelector } from '@reduxjs/toolkit';
-import { stateSelector } from 'app/store/store';
-import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
-import IAIIconButton from 'common/components/IAIIconButton';
-import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
-import {
- addEraseRect,
- addFillRect,
- setTool,
-} from 'features/canvas/store/canvasSlice';
-import { isEqual } from 'lodash-es';
-import { memo, useCallback } from 'react';
-
-import { useHotkeys } from 'react-hotkeys-hook';
-import { useTranslation } from 'react-i18next';
-import {
- FaEraser,
- FaEyeDropper,
- FaFillDrip,
- FaPaintBrush,
- FaPlus,
-} from 'react-icons/fa';
-
-export const selector = createSelector(
- [stateSelector, isStagingSelector],
- ({ canvas }, isStaging) => {
- const { tool } = canvas;
-
- return {
- tool,
- isStaging,
- };
- },
- {
- memoizeOptions: {
- resultEqualityCheck: isEqual,
- },
- }
-);
-
-const UnifiedCanvasToolSelect = () => {
- const dispatch = useAppDispatch();
- const { t } = useTranslation();
- const { tool, isStaging } = useAppSelector(selector);
-
- useHotkeys(
- ['b'],
- () => {
- handleSelectBrushTool();
- },
- {
- enabled: () => !isStaging,
- preventDefault: true,
- },
- []
- );
-
- useHotkeys(
- ['e'],
- () => {
- handleSelectEraserTool();
- },
- {
- enabled: () => !isStaging,
- preventDefault: true,
- },
- [tool]
- );
-
- useHotkeys(
- ['c'],
- () => {
- handleSelectColorPickerTool();
- },
- {
- enabled: () => !isStaging,
- preventDefault: true,
- },
- [tool]
- );
-
- useHotkeys(
- ['shift+f'],
- () => {
- handleFillRect();
- },
- {
- enabled: () => !isStaging,
- preventDefault: true,
- }
- );
-
- useHotkeys(
- ['delete', 'backspace'],
- () => {
- handleEraseBoundingBox();
- },
- {
- enabled: () => !isStaging,
- preventDefault: true,
- }
- );
-
- const handleSelectBrushTool = useCallback(
- () => dispatch(setTool('brush')),
- [dispatch]
- );
- const handleSelectEraserTool = useCallback(
- () => dispatch(setTool('eraser')),
- [dispatch]
- );
- const handleSelectColorPickerTool = useCallback(
- () => dispatch(setTool('colorPicker')),
- [dispatch]
- );
- const handleFillRect = useCallback(() => dispatch(addFillRect()), [dispatch]);
- const handleEraseBoundingBox = useCallback(
- () => dispatch(addEraseRect()),
- [dispatch]
- );
-
- return (
-
-
- }
- isChecked={tool === 'brush' && !isStaging}
- onClick={handleSelectBrushTool}
- isDisabled={isStaging}
- />
- }
- isChecked={tool === 'eraser' && !isStaging}
- isDisabled={isStaging}
- onClick={handleSelectEraserTool}
- />
-
-
- }
- isDisabled={isStaging}
- onClick={handleFillRect}
- />
- }
- isDisabled={isStaging}
- onClick={handleEraseBoundingBox}
- />
-
- }
- isChecked={tool === 'colorPicker' && !isStaging}
- isDisabled={isStaging}
- onClick={handleSelectColorPickerTool}
- width="max-content"
- />
-
- );
-};
-
-export default memo(UnifiedCanvasToolSelect);
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbarBeta.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbarBeta.tsx
deleted file mode 100644
index 7ef5af6949..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasBeta/UnifiedCanvasToolbarBeta.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import { Flex } from '@chakra-ui/react';
-
-import IAICanvasRedoButton from 'features/canvas/components/IAICanvasToolbar/IAICanvasRedoButton';
-import IAICanvasUndoButton from 'features/canvas/components/IAICanvasToolbar/IAICanvasUndoButton';
-import { memo } from 'react';
-import UnifiedCanvasSettings from './UnifiedCanvasToolSettings/UnifiedCanvasSettings';
-import UnifiedCanvasCopyToClipboard from './UnifiedCanvasToolbar/UnifiedCanvasCopyToClipboard';
-import UnifiedCanvasDownloadImage from './UnifiedCanvasToolbar/UnifiedCanvasDownloadImage';
-import UnifiedCanvasFileUploader from './UnifiedCanvasToolbar/UnifiedCanvasFileUploader';
-import UnifiedCanvasLayerSelect from './UnifiedCanvasToolbar/UnifiedCanvasLayerSelect';
-import UnifiedCanvasMergeVisible from './UnifiedCanvasToolbar/UnifiedCanvasMergeVisible';
-import UnifiedCanvasMoveTool from './UnifiedCanvasToolbar/UnifiedCanvasMoveTool';
-import UnifiedCanvasResetCanvas from './UnifiedCanvasToolbar/UnifiedCanvasResetCanvas';
-import UnifiedCanvasResetView from './UnifiedCanvasToolbar/UnifiedCanvasResetView';
-import UnifiedCanvasSaveToGallery from './UnifiedCanvasToolbar/UnifiedCanvasSaveToGallery';
-import UnifiedCanvasToolSelect from './UnifiedCanvasToolbar/UnifiedCanvasToolSelect';
-
-const UnifiedCanvasToolbarBeta = () => {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-};
-
-export default memo(UnifiedCanvasToolbarBeta);
diff --git a/invokeai/frontend/web/src/theme/components/table.ts b/invokeai/frontend/web/src/theme/components/table.ts
deleted file mode 100644
index e69de29bb2..0000000000
From 3a0ec635c9d52e10c757a103e2a271b70b872f71 Mon Sep 17 00:00:00 2001
From: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date: Mon, 13 Nov 2023 10:01:14 +1100
Subject: [PATCH 2/4] feat(ui): add eslint rule `react/jsx-no-bind`
This rule enforces no arrow functions in component props. In practice, it means all functions passed as component props must be wrapped in `useCallback()`.
This is a performance optimization to prevent unnecessary rerenders.
The rule is added and all violations have been fixed, whew!
---
invokeai/frontend/web/.eslintrc.js | 1 +
.../src/common/components/IAIAlertDialog.tsx | 17 ++-
.../src/common/components/IAIMantineInput.tsx | 52 +++++----
.../src/common/components/IAINumberInput.tsx | 40 ++++---
.../web/src/common/components/IAISelect.tsx | 15 +--
.../web/src/common/components/IAISlider.tsx | 19 ++--
.../src/common/components/ImageUploader.tsx | 17 ++-
.../ClearCanvasHistoryButtonModal.tsx | 9 +-
.../IAICanvasToolbar/IAICanvasMaskOptions.tsx | 41 ++++---
.../IAICanvasToolbar/IAICanvasRedoButton.tsx | 5 +-
.../IAICanvasSettingsButtonPopover.tsx | 76 +++++++++----
.../IAICanvasToolChooserOptions.tsx | 39 +++++--
.../IAICanvasToolbar/IAICanvasToolbar.tsx | 43 ++++----
.../IAICanvasToolbar/IAICanvasUndoButton.tsx | 5 +-
.../components/ChangeBoardModal.tsx | 7 +-
.../components/ParamEmbeddingPopover.tsx | 16 +--
.../components/Boards/BoardAutoAddSelect.tsx | 12 ++-
.../components/Boards/BoardContextMenu.tsx | 77 ++++++++------
.../components/GallerySettingsPopover.tsx | 10 +-
.../ImageContextMenu/ImageContextMenu.tsx | 56 +++++-----
.../components/ImageGrid/GalleryImageGrid.tsx | 12 ++-
.../ImageMetadataActions.tsx | 8 +-
.../ImageMetadataViewer/ImageMetadataItem.tsx | 9 +-
.../lora/components/ParamLoraSelect.tsx | 12 ++-
.../nodes/CurrentImage/CurrentImageNode.tsx | 10 +-
.../Invocation/fields/FieldContextMenu.tsx | 34 +++---
.../fields/inputs/LoRAModelInputField.tsx | 12 ++-
.../fields/inputs/NumberInputField.tsx | 33 +++---
.../BoundingBox/ParamBoundingBoxHeight.tsx | 33 +++---
.../BoundingBox/ParamBoundingBoxWidth.tsx | 33 +++---
.../ParamCanvasCoherenceMode.tsx | 17 +--
.../ParamCanvasCoherenceSteps.tsx | 21 ++--
.../ParamCanvasCoherenceStrength.tsx | 20 ++--
.../MaskAdjustment/ParamMaskBlur.tsx | 19 ++--
.../MaskAdjustment/ParamMaskBlurMethod.tsx | 16 +--
.../ParamScaleBeforeProcessing.tsx | 11 +-
.../InfillAndScaling/ParamScaledHeight.tsx | 35 +++---
.../InfillAndScaling/ParamScaledWidth.tsx | 35 +++---
.../Parameters/Core/ParamAspectRatio.tsx | 14 ++-
.../ImageToImage/ImageToImageFit.tsx | 10 +-
.../components/Parameters/Seed/ParamSeed.tsx | 6 +-
.../Parameters/Seed/ParamSeedRandomize.tsx | 9 +-
.../Parameters/Seed/ParamSeedShuffle.tsx | 7 +-
.../Symmetry/ParamSymmetryHorizontal.tsx | 15 ++-
.../Symmetry/ParamSymmetryToggle.tsx | 9 +-
.../Symmetry/ParamSymmetryVertical.tsx | 15 ++-
.../Upscale/ParamRealESRGANModel.tsx | 7 +-
.../sdxl/components/ParamSDXLConcatButton.tsx | 5 +-
.../SDXLRefiner/ParamUseSDXLRefiner.tsx | 11 +-
.../SettingsModal/SettingsModal.tsx | 95 +++++++++++------
.../ui/components/FloatingGalleryButton.tsx | 6 +-
.../FloatingParametersPanelButtons.tsx | 6 +-
.../subpanels/AddModelsPanel/AddModels.tsx | 11 +-
.../AddModelsPanel/AdvancedAddCheckpoint.tsx | 37 ++++---
.../AddModelsPanel/AdvancedAddDiffusers.tsx | 29 +++--
.../AddModelsPanel/AdvancedAddModels.tsx | 15 +--
.../AddModelsPanel/FoundModelsList.tsx | 7 +-
.../AddModelsPanel/ScanAdvancedAddModels.tsx | 33 +++---
.../AddModelsPanel/SearchFolderForm.tsx | 14 +--
.../subpanels/ImportModelsPanel.tsx | 9 +-
.../subpanels/MergeModelsPanel.tsx | 100 +++++++++++++-----
.../ModelManagerPanel/CheckpointModelEdit.tsx | 7 +-
.../ModelManagerPanel/ModelConvert.tsx | 37 ++++---
.../subpanels/ModelManagerPanel/ModelList.tsx | 12 +--
.../SyncModelsButton.tsx | 5 +-
65 files changed, 932 insertions(+), 526 deletions(-)
diff --git a/invokeai/frontend/web/.eslintrc.js b/invokeai/frontend/web/.eslintrc.js
index c2b1433a9a..976aea9739 100644
--- a/invokeai/frontend/web/.eslintrc.js
+++ b/invokeai/frontend/web/.eslintrc.js
@@ -24,6 +24,7 @@ module.exports = {
root: true,
rules: {
curly: 'error',
+ 'react/jsx-no-bind': ['error', { allowBind: true }],
'react/jsx-curly-brace-presence': [
'error',
{ props: 'never', children: 'never' },
diff --git a/invokeai/frontend/web/src/common/components/IAIAlertDialog.tsx b/invokeai/frontend/web/src/common/components/IAIAlertDialog.tsx
index bd919c162a..a82095daa3 100644
--- a/invokeai/frontend/web/src/common/components/IAIAlertDialog.tsx
+++ b/invokeai/frontend/web/src/common/components/IAIAlertDialog.tsx
@@ -8,7 +8,14 @@ import {
forwardRef,
useDisclosure,
} from '@chakra-ui/react';
-import { cloneElement, memo, ReactElement, ReactNode, useRef } from 'react';
+import {
+ cloneElement,
+ memo,
+ ReactElement,
+ ReactNode,
+ useCallback,
+ useRef,
+} from 'react';
import { useTranslation } from 'react-i18next';
import IAIButton from './IAIButton';
@@ -38,15 +45,15 @@ const IAIAlertDialog = forwardRef((props: Props, ref) => {
const { isOpen, onOpen, onClose } = useDisclosure();
const cancelRef = useRef(null);
- const handleAccept = () => {
+ const handleAccept = useCallback(() => {
acceptCallback();
onClose();
- };
+ }, [acceptCallback, onClose]);
- const handleCancel = () => {
+ const handleCancel = useCallback(() => {
cancelCallback && cancelCallback();
onClose();
- };
+ }, [cancelCallback, onClose]);
return (
<>
diff --git a/invokeai/frontend/web/src/common/components/IAIMantineInput.tsx b/invokeai/frontend/web/src/common/components/IAIMantineInput.tsx
index afe8b9442b..a324f80770 100644
--- a/invokeai/frontend/web/src/common/components/IAIMantineInput.tsx
+++ b/invokeai/frontend/web/src/common/components/IAIMantineInput.tsx
@@ -1,6 +1,7 @@
import { useColorMode } from '@chakra-ui/react';
import { TextInput, TextInputProps } from '@mantine/core';
import { useChakraThemeTokens } from 'common/hooks/useChakraThemeTokens';
+import { useCallback } from 'react';
import { mode } from 'theme/util/mode';
type IAIMantineTextInputProps = TextInputProps;
@@ -20,26 +21,37 @@ export default function IAIMantineTextInput(props: IAIMantineTextInputProps) {
} = useChakraThemeTokens();
const { colorMode } = useColorMode();
- return (
- ({
- input: {
- color: mode(base900, base100)(colorMode),
- backgroundColor: mode(base50, base900)(colorMode),
- borderColor: mode(base200, base800)(colorMode),
- borderWidth: 2,
- outline: 'none',
- ':focus': {
- borderColor: mode(accent300, accent500)(colorMode),
- },
+ const stylesFunc = useCallback(
+ () => ({
+ input: {
+ color: mode(base900, base100)(colorMode),
+ backgroundColor: mode(base50, base900)(colorMode),
+ borderColor: mode(base200, base800)(colorMode),
+ borderWidth: 2,
+ outline: 'none',
+ ':focus': {
+ borderColor: mode(accent300, accent500)(colorMode),
},
- label: {
- color: mode(base700, base300)(colorMode),
- fontWeight: 'normal',
- marginBottom: 4,
- },
- })}
- {...rest}
- />
+ },
+ label: {
+ color: mode(base700, base300)(colorMode),
+ fontWeight: 'normal' as const,
+ marginBottom: 4,
+ },
+ }),
+ [
+ accent300,
+ accent500,
+ base100,
+ base200,
+ base300,
+ base50,
+ base700,
+ base800,
+ base900,
+ colorMode,
+ ]
);
+
+ return ;
}
diff --git a/invokeai/frontend/web/src/common/components/IAINumberInput.tsx b/invokeai/frontend/web/src/common/components/IAINumberInput.tsx
index 243dac9d63..36098ec097 100644
--- a/invokeai/frontend/web/src/common/components/IAINumberInput.tsx
+++ b/invokeai/frontend/web/src/common/components/IAINumberInput.tsx
@@ -98,28 +98,34 @@ const IAINumberInput = forwardRef((props: Props, ref) => {
}
}, [value, valueAsString]);
- const handleOnChange = (v: string) => {
- setValueAsString(v);
- // This allows negatives and decimals e.g. '-123', `.5`, `-0.2`, etc.
- if (!v.match(numberStringRegex)) {
- // Cast the value to number. Floor it if it should be an integer.
- onChange(isInteger ? Math.floor(Number(v)) : Number(v));
- }
- };
+ const handleOnChange = useCallback(
+ (v: string) => {
+ setValueAsString(v);
+ // This allows negatives and decimals e.g. '-123', `.5`, `-0.2`, etc.
+ if (!v.match(numberStringRegex)) {
+ // Cast the value to number. Floor it if it should be an integer.
+ onChange(isInteger ? Math.floor(Number(v)) : Number(v));
+ }
+ },
+ [isInteger, onChange]
+ );
/**
* Clicking the steppers allows the value to go outside bounds; we need to
* clamp it on blur and floor it if needed.
*/
- const handleBlur = (e: FocusEvent) => {
- const clamped = clamp(
- isInteger ? Math.floor(Number(e.target.value)) : Number(e.target.value),
- min,
- max
- );
- setValueAsString(String(clamped));
- onChange(clamped);
- };
+ const handleBlur = useCallback(
+ (e: FocusEvent) => {
+ const clamped = clamp(
+ isInteger ? Math.floor(Number(e.target.value)) : Number(e.target.value),
+ min,
+ max
+ );
+ setValueAsString(String(clamped));
+ onChange(clamped);
+ },
+ [isInteger, max, min, onChange]
+ );
const handleKeyDown = useCallback(
(e: KeyboardEvent) => {
diff --git a/invokeai/frontend/web/src/common/components/IAISelect.tsx b/invokeai/frontend/web/src/common/components/IAISelect.tsx
index 7bc8952d94..faa5732017 100644
--- a/invokeai/frontend/web/src/common/components/IAISelect.tsx
+++ b/invokeai/frontend/web/src/common/components/IAISelect.tsx
@@ -6,7 +6,7 @@ import {
Tooltip,
TooltipProps,
} from '@chakra-ui/react';
-import { memo, MouseEvent } from 'react';
+import { memo, MouseEvent, useCallback } from 'react';
import IAIOption from './IAIOption';
type IAISelectProps = SelectProps & {
@@ -33,15 +33,16 @@ const IAISelect = (props: IAISelectProps) => {
spaceEvenly,
...rest
} = props;
+ const handleClick = useCallback((e: MouseEvent) => {
+ e.stopPropagation();
+ e.nativeEvent.stopImmediatePropagation();
+ e.nativeEvent.stopPropagation();
+ e.nativeEvent.cancelBubble = true;
+ }, []);
return (
) => {
- e.stopPropagation();
- e.nativeEvent.stopImmediatePropagation();
- e.nativeEvent.stopPropagation();
- e.nativeEvent.cancelBubble = true;
- }}
+ onClick={handleClick}
sx={
horizontal
? {
diff --git a/invokeai/frontend/web/src/common/components/IAISlider.tsx b/invokeai/frontend/web/src/common/components/IAISlider.tsx
index e879c00977..3ed3ee1920 100644
--- a/invokeai/frontend/web/src/common/components/IAISlider.tsx
+++ b/invokeai/frontend/web/src/common/components/IAISlider.tsx
@@ -186,6 +186,13 @@ const IAISlider = forwardRef((props: IAIFullSliderProps, ref) => {
[dispatch]
);
+ const handleMouseEnter = useCallback(() => setShowTooltip(true), []);
+ const handleMouseLeave = useCallback(() => setShowTooltip(false), []);
+ const handleStepperClick = useCallback(
+ () => onChange(Number(localInputValue)),
+ [localInputValue, onChange]
+ );
+
return (
{
max={max}
step={step}
onChange={handleSliderChange}
- onMouseEnter={() => setShowTooltip(true)}
- onMouseLeave={() => setShowTooltip(false)}
+ onMouseEnter={handleMouseEnter}
+ onMouseLeave={handleMouseLeave}
focusThumbOnChange={false}
isDisabled={isDisabled}
{...rest}
@@ -332,12 +339,8 @@ const IAISlider = forwardRef((props: IAIFullSliderProps, ref) => {
{...sliderNumberInputFieldProps}
/>
- onChange(Number(localInputValue))}
- />
- onChange(Number(localInputValue))}
- />
+
+
)}
diff --git a/invokeai/frontend/web/src/common/components/ImageUploader.tsx b/invokeai/frontend/web/src/common/components/ImageUploader.tsx
index 59349e615d..913d3b4414 100644
--- a/invokeai/frontend/web/src/common/components/ImageUploader.tsx
+++ b/invokeai/frontend/web/src/common/components/ImageUploader.tsx
@@ -146,16 +146,15 @@ const ImageUploader = (props: ImageUploaderProps) => {
};
}, [inputRef]);
+ const handleKeyDown = useCallback((e: KeyboardEvent) => {
+ // Bail out if user hits spacebar - do not open the uploader
+ if (e.key === ' ') {
+ return;
+ }
+ }, []);
+
return (
- {
- // Bail out if user hits spacebar - do not open the uploader
- if (e.key === ' ') {
- return;
- }
- }}
- >
+
{children}
diff --git a/invokeai/frontend/web/src/features/canvas/components/ClearCanvasHistoryButtonModal.tsx b/invokeai/frontend/web/src/features/canvas/components/ClearCanvasHistoryButtonModal.tsx
index a86497aade..3f5264fe92 100644
--- a/invokeai/frontend/web/src/features/canvas/components/ClearCanvasHistoryButtonModal.tsx
+++ b/invokeai/frontend/web/src/features/canvas/components/ClearCanvasHistoryButtonModal.tsx
@@ -5,17 +5,22 @@ import { clearCanvasHistory } from 'features/canvas/store/canvasSlice';
import { useTranslation } from 'react-i18next';
import { FaTrash } from 'react-icons/fa';
import { isStagingSelector } from '../store/canvasSelectors';
-import { memo } from 'react';
+import { memo, useCallback } from 'react';
const ClearCanvasHistoryButtonModal = () => {
const isStaging = useAppSelector(isStagingSelector);
const dispatch = useAppDispatch();
const { t } = useTranslation();
+ const acceptCallback = useCallback(
+ () => dispatch(clearCanvasHistory()),
+ [dispatch]
+ );
+
return (
dispatch(clearCanvasHistory())}
+ acceptCallback={acceptCallback}
acceptButtonText={t('unifiedCanvas.clearHistory')}
triggerComponent={
} isDisabled={isStaging}>
diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasMaskOptions.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasMaskOptions.tsx
index 43e8febd66..e1b2105bbc 100644
--- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasMaskOptions.tsx
+++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasMaskOptions.tsx
@@ -20,7 +20,8 @@ import {
} from 'features/canvas/store/canvasSlice';
import { rgbaColorToString } from 'features/canvas/util/colorToString';
import { isEqual } from 'lodash-es';
-import { memo } from 'react';
+import { ChangeEvent, memo, useCallback } from 'react';
+import { RgbaColor } from 'react-colorful';
import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next';
@@ -95,18 +96,35 @@ const IAICanvasMaskOptions = () => {
[isMaskEnabled]
);
- const handleToggleMaskLayer = () => {
+ const handleToggleMaskLayer = useCallback(() => {
dispatch(setLayer(layer === 'mask' ? 'base' : 'mask'));
- };
+ }, [dispatch, layer]);
- const handleClearMask = () => dispatch(clearMask());
+ const handleClearMask = useCallback(() => {
+ dispatch(clearMask());
+ }, [dispatch]);
- const handleToggleEnableMask = () =>
+ const handleToggleEnableMask = useCallback(() => {
dispatch(setIsMaskEnabled(!isMaskEnabled));
+ }, [dispatch, isMaskEnabled]);
- const handleSaveMask = async () => {
+ const handleSaveMask = useCallback(async () => {
dispatch(canvasMaskSavedToGallery());
- };
+ }, [dispatch]);
+
+ const handleChangePreserveMaskedArea = useCallback(
+ (e: ChangeEvent) => {
+ dispatch(setShouldPreserveMaskedArea(e.target.checked));
+ },
+ [dispatch]
+ );
+
+ const handleChangeMaskColor = useCallback(
+ (newColor: RgbaColor) => {
+ dispatch(setMaskColor(newColor));
+ },
+ [dispatch]
+ );
return (
{
- dispatch(setShouldPreserveMaskedArea(e.target.checked))
- }
+ onChange={handleChangePreserveMaskedArea}
/>
- dispatch(setMaskColor(newColor))}
- />
+
} onClick={handleSaveMask}>
Save Mask
diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasRedoButton.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasRedoButton.tsx
index 18ded1c9c7..e20980f318 100644
--- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasRedoButton.tsx
+++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasRedoButton.tsx
@@ -10,6 +10,7 @@ import { redo } from 'features/canvas/store/canvasSlice';
import { stateSelector } from 'app/store/store';
import { isEqual } from 'lodash-es';
import { useTranslation } from 'react-i18next';
+import { useCallback } from 'react';
const canvasRedoSelector = createSelector(
[stateSelector, activeTabNameSelector],
@@ -34,9 +35,9 @@ export default function IAICanvasRedoButton() {
const { t } = useTranslation();
- const handleRedo = () => {
+ const handleRedo = useCallback(() => {
dispatch(redo());
- };
+ }, [dispatch]);
useHotkeys(
['meta+shift+z', 'ctrl+shift+z', 'control+y', 'meta+y'],
diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasSettingsButtonPopover.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasSettingsButtonPopover.tsx
index aae2da5632..c653c4ccd2 100644
--- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasSettingsButtonPopover.tsx
+++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasSettingsButtonPopover.tsx
@@ -18,7 +18,7 @@ import {
} from 'features/canvas/store/canvasSlice';
import { isEqual } from 'lodash-es';
-import { ChangeEvent, memo } from 'react';
+import { ChangeEvent, memo, useCallback } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next';
import { FaWrench } from 'react-icons/fa';
@@ -86,8 +86,52 @@ const IAICanvasSettingsButtonPopover = () => {
[shouldSnapToGrid]
);
- const handleChangeShouldSnapToGrid = (e: ChangeEvent) =>
- dispatch(setShouldSnapToGrid(e.target.checked));
+ const handleChangeShouldSnapToGrid = useCallback(
+ (e: ChangeEvent) =>
+ dispatch(setShouldSnapToGrid(e.target.checked)),
+ [dispatch]
+ );
+
+ const handleChangeShouldShowIntermediates = useCallback(
+ (e: ChangeEvent) =>
+ dispatch(setShouldShowIntermediates(e.target.checked)),
+ [dispatch]
+ );
+ const handleChangeShouldShowGrid = useCallback(
+ (e: ChangeEvent) =>
+ dispatch(setShouldShowGrid(e.target.checked)),
+ [dispatch]
+ );
+ const handleChangeShouldDarkenOutsideBoundingBox = useCallback(
+ (e: ChangeEvent) =>
+ dispatch(setShouldDarkenOutsideBoundingBox(e.target.checked)),
+ [dispatch]
+ );
+ const handleChangeShouldAutoSave = useCallback(
+ (e: ChangeEvent) =>
+ dispatch(setShouldAutoSave(e.target.checked)),
+ [dispatch]
+ );
+ const handleChangeShouldCropToBoundingBoxOnSave = useCallback(
+ (e: ChangeEvent) =>
+ dispatch(setShouldCropToBoundingBoxOnSave(e.target.checked)),
+ [dispatch]
+ );
+ const handleChangeShouldRestrictStrokesToBox = useCallback(
+ (e: ChangeEvent) =>
+ dispatch(setShouldRestrictStrokesToBox(e.target.checked)),
+ [dispatch]
+ );
+ const handleChangeShouldShowCanvasDebugInfo = useCallback(
+ (e: ChangeEvent) =>
+ dispatch(setShouldShowCanvasDebugInfo(e.target.checked)),
+ [dispatch]
+ );
+ const handleChangeShouldAntialias = useCallback(
+ (e: ChangeEvent) =>
+ dispatch(setShouldAntialias(e.target.checked)),
+ [dispatch]
+ );
return (
{
- dispatch(setShouldShowIntermediates(e.target.checked))
- }
+ onChange={handleChangeShouldShowIntermediates}
/>
dispatch(setShouldShowGrid(e.target.checked))}
+ onChange={handleChangeShouldShowGrid}
/>
{
- dispatch(setShouldDarkenOutsideBoundingBox(e.target.checked))
- }
+ onChange={handleChangeShouldDarkenOutsideBoundingBox}
/>
dispatch(setShouldAutoSave(e.target.checked))}
+ onChange={handleChangeShouldAutoSave}
/>
- dispatch(setShouldCropToBoundingBoxOnSave(e.target.checked))
- }
+ onChange={handleChangeShouldCropToBoundingBoxOnSave}
/>
- dispatch(setShouldRestrictStrokesToBox(e.target.checked))
- }
+ onChange={handleChangeShouldRestrictStrokesToBox}
/>
- dispatch(setShouldShowCanvasDebugInfo(e.target.checked))
- }
+ onChange={handleChangeShouldShowCanvasDebugInfo}
/>
dispatch(setShouldAntialias(e.target.checked))}
+ onChange={handleChangeShouldAntialias}
/>
diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolChooserOptions.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolChooserOptions.tsx
index 0030f1f06e..40b3186fb1 100644
--- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolChooserOptions.tsx
+++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolChooserOptions.tsx
@@ -15,7 +15,8 @@ import {
setTool,
} from 'features/canvas/store/canvasSlice';
import { clamp, isEqual } from 'lodash-es';
-import { memo } from 'react';
+import { memo, useCallback } from 'react';
+import { RgbaColor } from 'react-colorful';
import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next';
@@ -172,11 +173,33 @@ const IAICanvasToolChooserOptions = () => {
[brushColor]
);
- const handleSelectBrushTool = () => dispatch(setTool('brush'));
- const handleSelectEraserTool = () => dispatch(setTool('eraser'));
- const handleSelectColorPickerTool = () => dispatch(setTool('colorPicker'));
- const handleFillRect = () => dispatch(addFillRect());
- const handleEraseBoundingBox = () => dispatch(addEraseRect());
+ const handleSelectBrushTool = useCallback(() => {
+ dispatch(setTool('brush'));
+ }, [dispatch]);
+ const handleSelectEraserTool = useCallback(() => {
+ dispatch(setTool('eraser'));
+ }, [dispatch]);
+ const handleSelectColorPickerTool = useCallback(() => {
+ dispatch(setTool('colorPicker'));
+ }, [dispatch]);
+ const handleFillRect = useCallback(() => {
+ dispatch(addFillRect());
+ }, [dispatch]);
+ const handleEraseBoundingBox = useCallback(() => {
+ dispatch(addEraseRect());
+ }, [dispatch]);
+ const handleChangeBrushSize = useCallback(
+ (newSize: number) => {
+ dispatch(setBrushSize(newSize));
+ },
+ [dispatch]
+ );
+ const handleChangeBrushColor = useCallback(
+ (newColor: RgbaColor) => {
+ dispatch(setBrushColor(newColor));
+ },
+ [dispatch]
+ );
return (
@@ -233,7 +256,7 @@ const IAICanvasToolChooserOptions = () => {
label={t('unifiedCanvas.brushSize')}
value={brushSize}
withInput
- onChange={(newSize) => dispatch(setBrushSize(newSize))}
+ onChange={handleChangeBrushSize}
sliderNumberInputProps={{ max: 500 }}
/>
@@ -247,7 +270,7 @@ const IAICanvasToolChooserOptions = () => {
dispatch(setBrushColor(newColor))}
+ onChange={handleChangeBrushColor}
/>
diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx
index 617fedf0f0..7c04208349 100644
--- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx
+++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx
@@ -27,7 +27,7 @@ import {
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
import { useCopyImageToClipboard } from 'features/ui/hooks/useCopyImageToClipboard';
import { isEqual } from 'lodash-es';
-import { memo } from 'react';
+import { memo, useCallback } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next';
import {
@@ -151,7 +151,9 @@ const IAICanvasToolbar = () => {
[canvasBaseLayer]
);
- const handleSelectMoveTool = () => dispatch(setTool('move'));
+ const handleSelectMoveTool = useCallback(() => {
+ dispatch(setTool('move'));
+ }, [dispatch]);
const handleClickResetCanvasView = useSingleAndDoubleClick(
() => handleResetCanvasView(false),
@@ -174,36 +176,39 @@ const IAICanvasToolbar = () => {
);
};
- const handleResetCanvas = () => {
+ const handleResetCanvas = useCallback(() => {
dispatch(resetCanvas());
- };
+ }, [dispatch]);
- const handleMergeVisible = () => {
+ const handleMergeVisible = useCallback(() => {
dispatch(canvasMerged());
- };
+ }, [dispatch]);
- const handleSaveToGallery = () => {
+ const handleSaveToGallery = useCallback(() => {
dispatch(canvasSavedToGallery());
- };
+ }, [dispatch]);
- const handleCopyImageToClipboard = () => {
+ const handleCopyImageToClipboard = useCallback(() => {
if (!isClipboardAPIAvailable) {
return;
}
dispatch(canvasCopiedToClipboard());
- };
+ }, [dispatch, isClipboardAPIAvailable]);
- const handleDownloadAsImage = () => {
+ const handleDownloadAsImage = useCallback(() => {
dispatch(canvasDownloadedAsImage());
- };
+ }, [dispatch]);
- const handleChangeLayer = (v: string) => {
- const newLayer = v as CanvasLayer;
- dispatch(setLayer(newLayer));
- if (newLayer === 'mask' && !isMaskEnabled) {
- dispatch(setIsMaskEnabled(true));
- }
- };
+ const handleChangeLayer = useCallback(
+ (v: string) => {
+ const newLayer = v as CanvasLayer;
+ dispatch(setLayer(newLayer));
+ if (newLayer === 'mask' && !isMaskEnabled) {
+ dispatch(setIsMaskEnabled(true));
+ }
+ },
+ [dispatch, isMaskEnabled]
+ );
return (
{
+ const handleUndo = useCallback(() => {
dispatch(undo());
- };
+ }, [dispatch]);
useHotkeys(
['meta+z', 'ctrl+z'],
diff --git a/invokeai/frontend/web/src/features/changeBoardModal/components/ChangeBoardModal.tsx b/invokeai/frontend/web/src/features/changeBoardModal/components/ChangeBoardModal.tsx
index 6bdf434d52..122b2b7d38 100644
--- a/invokeai/frontend/web/src/features/changeBoardModal/components/ChangeBoardModal.tsx
+++ b/invokeai/frontend/web/src/features/changeBoardModal/components/ChangeBoardModal.tsx
@@ -87,6 +87,11 @@ const ChangeBoardModal = () => {
selectedBoard,
]);
+ const handleSetSelectedBoard = useCallback(
+ (v: string | null) => setSelectedBoard(v),
+ []
+ );
+
const cancelRef = useRef(null);
return (
@@ -113,7 +118,7 @@ const ChangeBoardModal = () => {
isFetching ? t('boards.loading') : t('boards.selectBoard')
}
disabled={isFetching}
- onChange={(v) => setSelectedBoard(v)}
+ onChange={handleSetSelectedBoard}
value={selectedBoard}
data={data}
/>
diff --git a/invokeai/frontend/web/src/features/embedding/components/ParamEmbeddingPopover.tsx b/invokeai/frontend/web/src/features/embedding/components/ParamEmbeddingPopover.tsx
index 164fd01a1f..32334a9f88 100644
--- a/invokeai/frontend/web/src/features/embedding/components/ParamEmbeddingPopover.tsx
+++ b/invokeai/frontend/web/src/features/embedding/components/ParamEmbeddingPopover.tsx
@@ -14,9 +14,9 @@ import IAIMantineSelectItemWithTooltip from 'common/components/IAIMantineSelectI
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
import { forEach } from 'lodash-es';
import { PropsWithChildren, memo, useCallback, useMemo, useRef } from 'react';
+import { useTranslation } from 'react-i18next';
import { useGetTextualInversionModelsQuery } from 'services/api/endpoints/models';
import { PARAMETERS_PANEL_WIDTH } from 'theme/util/constants';
-import { useTranslation } from 'react-i18next';
type Props = PropsWithChildren & {
onSelect: (v: string) => void;
@@ -78,6 +78,13 @@ const ParamEmbeddingPopover = (props: Props) => {
[onSelect]
);
+ const filterFunc = useCallback(
+ (value: string, item: SelectItem) =>
+ item.label?.toLowerCase().includes(value.toLowerCase().trim()) ||
+ item.value.toLowerCase().includes(value.toLowerCase().trim()),
+ []
+ );
+
return (
{
itemComponent={IAIMantineSelectItemWithTooltip}
disabled={data.length === 0}
onDropdownClose={onClose}
- filter={(value, item: SelectItem) =>
- item.label
- ?.toLowerCase()
- .includes(value.toLowerCase().trim()) ||
- item.value.toLowerCase().includes(value.toLowerCase().trim())
- }
+ filter={filterFunc}
onChange={handleChange}
/>
)}
diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardAutoAddSelect.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardAutoAddSelect.tsx
index 29211a7558..9c77500ef3 100644
--- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardAutoAddSelect.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardAutoAddSelect.tsx
@@ -60,6 +60,13 @@ const BoardAutoAddSelect = () => {
[dispatch]
);
+ const filterFunc = useCallback(
+ (value: string, item: SelectItem) =>
+ item.label?.toLowerCase().includes(value.toLowerCase().trim()) ||
+ item.value.toLowerCase().includes(value.toLowerCase().trim()),
+ []
+ );
+
return (
{
nothingFound={t('boards.noMatching')}
itemComponent={IAIMantineSelectItemWithTooltip}
disabled={!hasBoards || autoAssignBoardOnClick}
- filter={(value, item: SelectItem) =>
- item.label?.toLowerCase().includes(value.toLowerCase().trim()) ||
- item.value.toLowerCase().includes(value.toLowerCase().trim())
- }
+ filter={filterFunc}
onChange={handleChange}
/>
);
diff --git a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx
index 5dd6b94753..97e49b493c 100644
--- a/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/Boards/BoardContextMenu.tsx
@@ -90,6 +90,50 @@ const BoardContextMenu = ({
e.preventDefault();
}, []);
+ const renderMenuFunc = useCallback(
+ () => (
+
+
+ }
+ isDisabled={isAutoAdd || autoAssignBoardOnClick}
+ onClick={handleSetAutoAdd}
+ >
+ {t('boards.menuItemAutoAdd')}
+
+ {isBulkDownloadEnabled && (
+ } onClickCapture={handleBulkDownload}>
+ {t('boards.downloadBoard')}
+
+ )}
+ {!board && }
+ {board && (
+
+ )}
+
+
+ ),
+ [
+ autoAssignBoardOnClick,
+ board,
+ boardName,
+ handleBulkDownload,
+ handleSetAutoAdd,
+ isAutoAdd,
+ isBulkDownloadEnabled,
+ setBoardToDelete,
+ skipEvent,
+ t,
+ ]
+ );
+
return (
menuProps={{ size: 'sm', isLazy: true }}
@@ -97,38 +141,7 @@ const BoardContextMenu = ({
bg: 'transparent',
_hover: { bg: 'transparent' },
}}
- renderMenu={() => (
-
-
- }
- isDisabled={isAutoAdd || autoAssignBoardOnClick}
- onClick={handleSetAutoAdd}
- >
- {t('boards.menuItemAutoAdd')}
-
- {isBulkDownloadEnabled && (
- }
- onClickCapture={handleBulkDownload}
- >
- {t('boards.downloadBoard')}
-
- )}
- {!board && }
- {board && (
-
- )}
-
-
- )}
+ renderMenu={renderMenuFunc}
>
{children}
diff --git a/invokeai/frontend/web/src/features/gallery/components/GallerySettingsPopover.tsx b/invokeai/frontend/web/src/features/gallery/components/GallerySettingsPopover.tsx
index 2eab78d118..015a206fa2 100644
--- a/invokeai/frontend/web/src/features/gallery/components/GallerySettingsPopover.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/GallerySettingsPopover.tsx
@@ -61,6 +61,12 @@ const GallerySettingsPopover = () => {
[dispatch]
);
+ const handleChangeAutoAssignBoardOnClick = useCallback(
+ (e: ChangeEvent) =>
+ dispatch(autoAssignBoardOnClickChanged(e.target.checked)),
+ [dispatch]
+ );
+
return (
{
) =>
- dispatch(autoAssignBoardOnClickChanged(e.target.checked))
- }
+ onChange={handleChangeAutoAssignBoardOnClick}
/>
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageContextMenu.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageContextMenu.tsx
index 0c13b37f0c..6fc5765785 100644
--- a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageContextMenu.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/ImageContextMenu.tsx
@@ -35,6 +35,34 @@ const ImageContextMenu = ({ imageDTO, children }: Props) => {
e.preventDefault();
}, []);
+ const renderMenuFunc = useCallback(() => {
+ if (!imageDTO) {
+ return null;
+ }
+
+ if (selectionCount > 1) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+
+
+
+ );
+ }, [imageDTO, selectionCount, skipEvent]);
+
return (
menuProps={{ size: 'sm', isLazy: true }}
@@ -42,33 +70,7 @@ const ImageContextMenu = ({ imageDTO, children }: Props) => {
bg: 'transparent',
_hover: { bg: 'transparent' },
}}
- renderMenu={() => {
- if (!imageDTO) {
- return null;
- }
-
- if (selectionCount > 1) {
- return (
-
-
-
- );
- }
-
- return (
-
-
-
- );
- }}
+ renderMenu={renderMenuFunc}
>
{children}
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageGrid/GalleryImageGrid.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageGrid/GalleryImageGrid.tsx
index dc41a2ef2a..4b7997f2ef 100644
--- a/invokeai/frontend/web/src/features/gallery/components/ImageGrid/GalleryImageGrid.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/ImageGrid/GalleryImageGrid.tsx
@@ -20,6 +20,7 @@ import { useBoardTotal } from 'services/api/hooks/useBoardTotal';
import GalleryImage from './GalleryImage';
import ImageGridItemContainer from './ImageGridItemContainer';
import ImageGridListContainer from './ImageGridListContainer';
+import { EntityId } from '@reduxjs/toolkit';
const overlayScrollbarsConfig: UseOverlayScrollbarsParams = {
defer: true,
@@ -71,6 +72,13 @@ const GalleryImageGrid = () => {
});
}, [areMoreAvailable, listImages, queryArgs, currentData?.ids.length]);
+ const itemContentFunc = useCallback(
+ (index: number, imageName: EntityId) => (
+
+ ),
+ []
+ );
+
useEffect(() => {
// Initialize the gallery's custom scrollbar
const { current: root } = rootRef;
@@ -131,9 +139,7 @@ const GalleryImageGrid = () => {
List: ImageGridListContainer,
}}
scrollerRef={setScroller}
- itemContent={(index, imageName) => (
-
- )}
+ itemContent={itemContentFunc}
/>
{
key={index}
label="LoRA"
value={`${lora.lora.model_name} - ${lora.weight}`}
- onClick={() => handleRecallLoRA(lora)}
+ onClick={handleRecallLoRA.bind(null, lora)}
/>
);
}
@@ -289,7 +289,7 @@ const ImageMetadataActions = (props: Props) => {
key={index}
label="ControlNet"
value={`${controlnet.control_model?.model_name} - ${controlnet.control_weight}`}
- onClick={() => handleRecallControlNet(controlnet)}
+ onClick={handleRecallControlNet.bind(null, controlnet)}
/>
))}
{validIPAdapters.map((ipAdapter, index) => (
@@ -297,7 +297,7 @@ const ImageMetadataActions = (props: Props) => {
key={index}
label="IP Adapter"
value={`${ipAdapter.ip_adapter_model?.model_name} - ${ipAdapter.weight}`}
- onClick={() => handleRecallIPAdapter(ipAdapter)}
+ onClick={handleRecallIPAdapter.bind(null, ipAdapter)}
/>
))}
{validT2IAdapters.map((t2iAdapter, index) => (
@@ -305,7 +305,7 @@ const ImageMetadataActions = (props: Props) => {
key={index}
label="T2I Adapter"
value={`${t2iAdapter.t2i_adapter_model?.model_name} - ${t2iAdapter.weight}`}
- onClick={() => handleRecallT2IAdapter(t2iAdapter)}
+ onClick={handleRecallT2IAdapter.bind(null, t2iAdapter)}
/>
))}
>
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataItem.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataItem.tsx
index c03fd26ba1..135159562b 100644
--- a/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataItem.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/ImageMetadataViewer/ImageMetadataItem.tsx
@@ -1,6 +1,6 @@
import { ExternalLinkIcon } from '@chakra-ui/icons';
import { Flex, IconButton, Link, Text, Tooltip } from '@chakra-ui/react';
-import { memo } from 'react';
+import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { FaCopy } from 'react-icons/fa';
import { IoArrowUndoCircleOutline } from 'react-icons/io5';
@@ -27,6 +27,11 @@ const ImageMetadataItem = ({
}: MetadataItemProps) => {
const { t } = useTranslation();
+ const handleCopy = useCallback(
+ () => navigator.clipboard.writeText(value.toString()),
+ [value]
+ );
+
if (!value) {
return null;
}
@@ -53,7 +58,7 @@ const ImageMetadataItem = ({
size="xs"
variant="ghost"
fontSize={14}
- onClick={() => navigator.clipboard.writeText(value.toString())}
+ onClick={handleCopy}
/>
)}
diff --git a/invokeai/frontend/web/src/features/lora/components/ParamLoraSelect.tsx b/invokeai/frontend/web/src/features/lora/components/ParamLoraSelect.tsx
index 6048e4a159..e2fc841f15 100644
--- a/invokeai/frontend/web/src/features/lora/components/ParamLoraSelect.tsx
+++ b/invokeai/frontend/web/src/features/lora/components/ParamLoraSelect.tsx
@@ -76,6 +76,13 @@ const ParamLoRASelect = () => {
[dispatch, loraModels?.entities]
);
+ const filterFunc = useCallback(
+ (value: string, item: SelectItem) =>
+ item.label?.toLowerCase().includes(value.toLowerCase().trim()) ||
+ item.value.toLowerCase().includes(value.toLowerCase().trim()),
+ []
+ );
+
if (loraModels?.ids.length === 0) {
return (
@@ -94,10 +101,7 @@ const ParamLoRASelect = () => {
nothingFound="No matching LoRAs"
itemComponent={IAIMantineSelectItemWithTooltip}
disabled={data.length === 0}
- filter={(value, item: SelectItem) =>
- item.label?.toLowerCase().includes(value.toLowerCase().trim()) ||
- item.value.toLowerCase().includes(value.toLowerCase().trim())
- }
+ filter={filterFunc}
onChange={handleChange}
data-testid="add-lora"
/>
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/CurrentImage/CurrentImageNode.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/CurrentImage/CurrentImageNode.tsx
index 96ef7c56a3..57cdc6a8db 100644
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/CurrentImage/CurrentImageNode.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/CurrentImage/CurrentImageNode.tsx
@@ -1,4 +1,4 @@
-import { useState, PropsWithChildren, memo } from 'react';
+import { useState, PropsWithChildren, memo, useCallback } from 'react';
import { useSelector } from 'react-redux';
import { createSelector } from '@reduxjs/toolkit';
import { Flex, Image, Text } from '@chakra-ui/react';
@@ -59,13 +59,13 @@ export default memo(CurrentImageNode);
const Wrapper = (props: PropsWithChildren<{ nodeProps: NodeProps }>) => {
const [isHovering, setIsHovering] = useState(false);
- const handleMouseEnter = () => {
+ const handleMouseEnter = useCallback(() => {
setIsHovering(true);
- };
+ }, []);
- const handleMouseLeave = () => {
+ const handleMouseLeave = useCallback(() => {
setIsHovering(false);
- };
+ }, []);
return (
{
nodeId,
]);
+ const renderMenuFunc = useCallback(
+ () =>
+ !menuItems.length ? null : (
+
+
+ {menuItems}
+
+
+ ),
+ [fieldTemplateTitle, label, menuItems, skipEvent, t]
+ );
+
return (
menuProps={{
@@ -114,21 +132,7 @@ const FieldContextMenu = ({ nodeId, fieldName, kind, children }: Props) => {
bg: 'transparent',
_hover: { bg: 'transparent' },
}}
- renderMenu={() =>
- !menuItems.length ? null : (
-
-
- {menuItems}
-
-
- )
- }
+ renderMenu={renderMenuFunc}
>
{children}
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/LoRAModelInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/LoRAModelInputField.tsx
index 3ca87b3e85..712b1ff5a0 100644
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/LoRAModelInputField.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/LoRAModelInputField.tsx
@@ -80,6 +80,13 @@ const LoRAModelInputFieldComponent = (
[dispatch, field.name, nodeId]
);
+ const filterFunc = useCallback(
+ (value: string, item: SelectItem) =>
+ item.label?.toLowerCase().includes(value.toLowerCase().trim()) ||
+ item.value.toLowerCase().includes(value.toLowerCase().trim()),
+ []
+ );
+
if (loraModels?.ids.length === 0) {
return (
@@ -101,10 +108,7 @@ const LoRAModelInputFieldComponent = (
nothingFound={t('models.noMatchingLoRAs')}
itemComponent={IAIMantineSelectItemWithTooltip}
disabled={data.length === 0}
- filter={(value, item: SelectItem) =>
- item.label?.toLowerCase().includes(value.toLowerCase().trim()) ||
- item.value.toLowerCase().includes(value.toLowerCase().trim())
- }
+ filter={filterFunc}
error={!selectedLoRAModel}
onChange={handleChange}
sx={{
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/NumberInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/NumberInputField.tsx
index 2afbec1df8..2b2763ca3e 100644
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/NumberInputField.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/NumberInputField.tsx
@@ -19,7 +19,7 @@ import {
IntegerPolymorphicInputFieldTemplate,
IntegerPolymorphicInputFieldValue,
} from 'features/nodes/types/types';
-import { memo, useEffect, useMemo, useState } from 'react';
+import { memo, useCallback, useEffect, useMemo, useState } from 'react';
const NumberInputFieldComponent = (
props: FieldComponentProps<
@@ -43,20 +43,23 @@ const NumberInputFieldComponent = (
[fieldTemplate.type]
);
- const handleValueChanged = (v: string) => {
- setValueAsString(v);
- // This allows negatives and decimals e.g. '-123', `.5`, `-0.2`, etc.
- if (!v.match(numberStringRegex)) {
- // Cast the value to number. Floor it if it should be an integer.
- dispatch(
- fieldNumberValueChanged({
- nodeId,
- fieldName: field.name,
- value: isIntegerField ? Math.floor(Number(v)) : Number(v),
- })
- );
- }
- };
+ const handleValueChanged = useCallback(
+ (v: string) => {
+ setValueAsString(v);
+ // This allows negatives and decimals e.g. '-123', `.5`, `-0.2`, etc.
+ if (!v.match(numberStringRegex)) {
+ // Cast the value to number. Floor it if it should be an integer.
+ dispatch(
+ fieldNumberValueChanged({
+ nodeId,
+ fieldName: field.name,
+ value: isIntegerField ? Math.floor(Number(v)) : Number(v),
+ })
+ );
+ }
+ },
+ [dispatch, field.name, isIntegerField, nodeId]
+ );
useEffect(() => {
if (
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/BoundingBox/ParamBoundingBoxHeight.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/BoundingBox/ParamBoundingBoxHeight.tsx
index 1711c9344a..18a5b52e99 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/BoundingBox/ParamBoundingBoxHeight.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/BoundingBox/ParamBoundingBoxHeight.tsx
@@ -6,7 +6,7 @@ import IAISlider from 'common/components/IAISlider';
import { roundToMultiple } from 'common/util/roundDownToMultiple';
import { isStagingSelector } from 'features/canvas/store/canvasSelectors';
import { setBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
-import { memo } from 'react';
+import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
@@ -36,25 +36,28 @@ const ParamBoundingBoxWidth = () => {
? 1024
: 512;
- const handleChangeHeight = (v: number) => {
- dispatch(
- setBoundingBoxDimensions({
- ...boundingBoxDimensions,
- height: Math.floor(v),
- })
- );
- if (aspectRatio) {
- const newWidth = roundToMultiple(v * aspectRatio, 64);
+ const handleChangeHeight = useCallback(
+ (v: number) => {
dispatch(
setBoundingBoxDimensions({
- width: newWidth,
+ ...boundingBoxDimensions,
height: Math.floor(v),
})
);
- }
- };
+ if (aspectRatio) {
+ const newWidth = roundToMultiple(v * aspectRatio, 64);
+ dispatch(
+ setBoundingBoxDimensions({
+ width: newWidth,
+ height: Math.floor(v),
+ })
+ );
+ }
+ },
+ [aspectRatio, boundingBoxDimensions, dispatch]
+ );
- const handleResetHeight = () => {
+ const handleResetHeight = useCallback(() => {
dispatch(
setBoundingBoxDimensions({
...boundingBoxDimensions,
@@ -70,7 +73,7 @@ const ParamBoundingBoxWidth = () => {
})
);
}
- };
+ }, [aspectRatio, boundingBoxDimensions, dispatch, initial]);
return (
{
const { t } = useTranslation();
- const handleChangeWidth = (v: number) => {
- dispatch(
- setBoundingBoxDimensions({
- ...boundingBoxDimensions,
- width: Math.floor(v),
- })
- );
- if (aspectRatio) {
- const newHeight = roundToMultiple(v / aspectRatio, 64);
+ const handleChangeWidth = useCallback(
+ (v: number) => {
dispatch(
setBoundingBoxDimensions({
+ ...boundingBoxDimensions,
width: Math.floor(v),
- height: newHeight,
})
);
- }
- };
+ if (aspectRatio) {
+ const newHeight = roundToMultiple(v / aspectRatio, 64);
+ dispatch(
+ setBoundingBoxDimensions({
+ width: Math.floor(v),
+ height: newHeight,
+ })
+ );
+ }
+ },
+ [aspectRatio, boundingBoxDimensions, dispatch]
+ );
- const handleResetWidth = () => {
+ const handleResetWidth = useCallback(() => {
dispatch(
setBoundingBoxDimensions({
...boundingBoxDimensions,
@@ -70,7 +73,7 @@ const ParamBoundingBoxWidth = () => {
})
);
}
- };
+ }, [aspectRatio, boundingBoxDimensions, dispatch, initial]);
return (
{
);
const { t } = useTranslation();
- const handleCoherenceModeChange = (v: string | null) => {
- if (!v) {
- return;
- }
+ const handleCoherenceModeChange = useCallback(
+ (v: string | null) => {
+ if (!v) {
+ return;
+ }
- dispatch(setCanvasCoherenceMode(v as CanvasCoherenceModeParam));
- };
+ dispatch(setCanvasCoherenceMode(v as CanvasCoherenceModeParam));
+ },
+ [dispatch]
+ );
return (
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceSteps.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceSteps.tsx
index 463d596a5c..3c3bc59c20 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceSteps.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceSteps.tsx
@@ -3,7 +3,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIInformationalPopover from 'common/components/IAIInformationalPopover/IAIInformationalPopover';
import IAISlider from 'common/components/IAISlider';
import { setCanvasCoherenceSteps } from 'features/parameters/store/generationSlice';
-import { memo } from 'react';
+import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const ParamCanvasCoherenceSteps = () => {
@@ -13,6 +13,17 @@ const ParamCanvasCoherenceSteps = () => {
);
const { t } = useTranslation();
+ const handleChange = useCallback(
+ (v: number) => {
+ dispatch(setCanvasCoherenceSteps(v));
+ },
+ [dispatch]
+ );
+
+ const handleReset = useCallback(() => {
+ dispatch(setCanvasCoherenceSteps(20));
+ }, [dispatch]);
+
return (
{
step={1}
sliderNumberInputProps={{ max: 999 }}
value={canvasCoherenceSteps}
- onChange={(v) => {
- dispatch(setCanvasCoherenceSteps(v));
- }}
+ onChange={handleChange}
withInput
withSliderMarks
withReset
- handleReset={() => {
- dispatch(setCanvasCoherenceSteps(20));
- }}
+ handleReset={handleReset}
/>
);
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceStrength.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceStrength.tsx
index e5311db3a6..7fc3096062 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceStrength.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/CoherencePass/ParamCanvasCoherenceStrength.tsx
@@ -3,7 +3,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIInformationalPopover from 'common/components/IAIInformationalPopover/IAIInformationalPopover';
import IAISlider from 'common/components/IAISlider';
import { setCanvasCoherenceStrength } from 'features/parameters/store/generationSlice';
-import { memo } from 'react';
+import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const ParamCanvasCoherenceStrength = () => {
@@ -13,6 +13,16 @@ const ParamCanvasCoherenceStrength = () => {
);
const { t } = useTranslation();
+ const handleChange = useCallback(
+ (v: number) => {
+ dispatch(setCanvasCoherenceStrength(v));
+ },
+ [dispatch]
+ );
+ const handleReset = useCallback(() => {
+ dispatch(setCanvasCoherenceStrength(0.3));
+ }, [dispatch]);
+
return (
{
step={0.01}
sliderNumberInputProps={{ max: 999 }}
value={canvasCoherenceStrength}
- onChange={(v) => {
- dispatch(setCanvasCoherenceStrength(v));
- }}
+ onChange={handleChange}
withInput
withSliderMarks
withReset
- handleReset={() => {
- dispatch(setCanvasCoherenceStrength(0.3));
- }}
+ handleReset={handleReset}
/>
);
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/MaskAdjustment/ParamMaskBlur.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/MaskAdjustment/ParamMaskBlur.tsx
index bbadbbabf0..013d4ad4a3 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/MaskAdjustment/ParamMaskBlur.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/MaskAdjustment/ParamMaskBlur.tsx
@@ -3,6 +3,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIInformationalPopover from 'common/components/IAIInformationalPopover/IAIInformationalPopover';
import IAISlider from 'common/components/IAISlider';
import { setMaskBlur } from 'features/parameters/store/generationSlice';
+import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
export default function ParamMaskBlur() {
@@ -12,6 +13,16 @@ export default function ParamMaskBlur() {
);
const { t } = useTranslation();
+ const handleChange = useCallback(
+ (v: number) => {
+ dispatch(setMaskBlur(v));
+ },
+ [dispatch]
+ );
+ const handleReset = useCallback(() => {
+ dispatch(setMaskBlur(16));
+ }, [dispatch]);
+
return (
{
- dispatch(setMaskBlur(v));
- }}
+ onChange={handleChange}
withInput
withSliderMarks
withReset
- handleReset={() => {
- dispatch(setMaskBlur(16));
- }}
+ handleReset={handleReset}
/>
);
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/MaskAdjustment/ParamMaskBlurMethod.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/MaskAdjustment/ParamMaskBlurMethod.tsx
index df0b2ebc90..b7490461b5 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/MaskAdjustment/ParamMaskBlurMethod.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/Compositing/MaskAdjustment/ParamMaskBlurMethod.tsx
@@ -5,6 +5,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAIInformationalPopover from 'common/components/IAIInformationalPopover/IAIInformationalPopover';
import IAIMantineSelect from 'common/components/IAIMantineSelect';
import { setMaskBlurMethod } from 'features/parameters/store/generationSlice';
+import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
type MaskBlurMethods = 'box' | 'gaussian';
@@ -21,12 +22,15 @@ export default function ParamMaskBlurMethod() {
const dispatch = useAppDispatch();
const { t } = useTranslation();
- const handleMaskBlurMethodChange = (v: string | null) => {
- if (!v) {
- return;
- }
- dispatch(setMaskBlurMethod(v as MaskBlurMethods));
- };
+ const handleMaskBlurMethodChange = useCallback(
+ (v: string | null) => {
+ if (!v) {
+ return;
+ }
+ dispatch(setMaskBlurMethod(v as MaskBlurMethods));
+ },
+ [dispatch]
+ );
return (
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamScaleBeforeProcessing.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamScaleBeforeProcessing.tsx
index 1a0e497739..06594b7b1b 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamScaleBeforeProcessing.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamScaleBeforeProcessing.tsx
@@ -10,7 +10,7 @@ import {
BoundingBoxScale,
} from 'features/canvas/store/canvasTypes';
-import { memo } from 'react';
+import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const selector = createSelector(
@@ -31,9 +31,12 @@ const ParamScaleBeforeProcessing = () => {
const { t } = useTranslation();
- const handleChangeBoundingBoxScaleMethod = (v: string) => {
- dispatch(setBoundingBoxScaleMethod(v as BoundingBoxScale));
- };
+ const handleChangeBoundingBoxScaleMethod = useCallback(
+ (v: string) => {
+ dispatch(setBoundingBoxScaleMethod(v as BoundingBoxScale));
+ },
+ [dispatch]
+ );
return (
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamScaledHeight.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamScaledHeight.tsx
index 6d0ac52b2f..62b7c899f2 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamScaledHeight.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Canvas/InfillAndScaling/ParamScaledHeight.tsx
@@ -6,7 +6,7 @@ import { roundToMultiple } from 'common/util/roundDownToMultiple';
import { canvasSelector } from 'features/canvas/store/canvasSelectors';
import { setScaledBoundingBoxDimensions } from 'features/canvas/store/canvasSlice';
import { generationSelector } from 'features/parameters/store/generationSelectors';
-import { memo } from 'react';
+import { memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
const selector = createSelector(
@@ -36,23 +36,26 @@ const ParamScaledHeight = () => {
const { t } = useTranslation();
- const handleChangeScaledHeight = (v: number) => {
- let newWidth = scaledBoundingBoxDimensions.width;
- const newHeight = Math.floor(v);
+ const handleChangeScaledHeight = useCallback(
+ (v: number) => {
+ let newWidth = scaledBoundingBoxDimensions.width;
+ const newHeight = Math.floor(v);
- if (aspectRatio) {
- newWidth = roundToMultiple(newHeight * aspectRatio, 64);
- }
+ if (aspectRatio) {
+ newWidth = roundToMultiple(newHeight * aspectRatio, 64);
+ }
- dispatch(
- setScaledBoundingBoxDimensions({
- width: newWidth,
- height: newHeight,
- })
- );
- };
+ dispatch(
+ setScaledBoundingBoxDimensions({
+ width: newWidth,
+ height: newHeight,
+ })
+ );
+ },
+ [aspectRatio, dispatch, scaledBoundingBoxDimensions.width]
+ );
- const handleResetScaledHeight = () => {
+ const handleResetScaledHeight = useCallback(() => {
let resetWidth = scaledBoundingBoxDimensions.width;
const resetHeight = Math.floor(initial);
@@ -66,7 +69,7 @@ const ParamScaledHeight = () => {
height: resetHeight,
})
);
- };
+ }, [aspectRatio, dispatch, initial, scaledBoundingBoxDimensions.width]);
return (
{
const { t } = useTranslation();
- const handleChangeScaledWidth = (v: number) => {
- const newWidth = Math.floor(v);
- let newHeight = scaledBoundingBoxDimensions.height;
+ const handleChangeScaledWidth = useCallback(
+ (v: number) => {
+ const newWidth = Math.floor(v);
+ let newHeight = scaledBoundingBoxDimensions.height;
- if (aspectRatio) {
- newHeight = roundToMultiple(newWidth / aspectRatio, 64);
- }
+ if (aspectRatio) {
+ newHeight = roundToMultiple(newWidth / aspectRatio, 64);
+ }
- dispatch(
- setScaledBoundingBoxDimensions({
- width: newWidth,
- height: newHeight,
- })
- );
- };
+ dispatch(
+ setScaledBoundingBoxDimensions({
+ width: newWidth,
+ height: newHeight,
+ })
+ );
+ },
+ [aspectRatio, dispatch, scaledBoundingBoxDimensions.height]
+ );
- const handleResetScaledWidth = () => {
+ const handleResetScaledWidth = useCallback(() => {
const resetWidth = Math.floor(initial);
let resetHeight = scaledBoundingBoxDimensions.height;
@@ -66,7 +69,7 @@ const ParamScaledWidth = () => {
height: resetHeight,
})
);
- };
+ }, [aspectRatio, dispatch, initial, scaledBoundingBoxDimensions.height]);
return (
{
+ dispatch(setAspectRatio(ratio.value));
+ dispatch(setShouldLockAspectRatio(false));
+ },
+ [dispatch]
+ );
+
return (
{aspectRatios.map((ratio) => (
@@ -39,10 +48,7 @@ export default function ParamAspectRatio() {
isDisabled={
activeTabName === 'img2img' ? !shouldFitToWidthHeight : false
}
- onClick={() => {
- dispatch(setAspectRatio(ratio.value));
- dispatch(setShouldLockAspectRatio(false));
- }}
+ onClick={handleClick.bind(null, ratio)}
>
{ratio.name}
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/ImageToImageFit.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/ImageToImageFit.tsx
index 03f502846c..0305424ef0 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/ImageToImageFit.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/ImageToImage/ImageToImageFit.tsx
@@ -2,7 +2,7 @@ import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISwitch from 'common/components/IAISwitch';
import { setShouldFitToWidthHeight } from 'features/parameters/store/generationSlice';
-import { ChangeEvent } from 'react';
+import { ChangeEvent, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
export default function ImageToImageFit() {
@@ -12,8 +12,12 @@ export default function ImageToImageFit() {
(state: RootState) => state.generation.shouldFitToWidthHeight
);
- const handleChangeFit = (e: ChangeEvent) =>
- dispatch(setShouldFitToWidthHeight(e.target.checked));
+ const handleChangeFit = useCallback(
+ (e: ChangeEvent) => {
+ dispatch(setShouldFitToWidthHeight(e.target.checked));
+ },
+ [dispatch]
+ );
const { t } = useTranslation();
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeed.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeed.tsx
index 481fe27964..4dc86fb8ee 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeed.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Seed/ParamSeed.tsx
@@ -3,6 +3,7 @@ import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAINumberInput from 'common/components/IAINumberInput';
import { setSeed } from 'features/parameters/store/generationSlice';
+import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
export default function ParamSeed() {
@@ -18,7 +19,10 @@ export default function ParamSeed() {
const dispatch = useAppDispatch();
- const handleChangeSeed = (v: number) => dispatch(setSeed(v));
+ const handleChangeSeed = useCallback(
+ (v: number) => dispatch(setSeed(v)),
+ [dispatch]
+ );
return (
{
(state: RootState) => state.generation.shouldRandomizeSeed
);
- const handleChangeShouldRandomizeSeed = (e: ChangeEvent) =>
- dispatch(setShouldRandomizeSeed(e.target.checked));
+ const handleChangeShouldRandomizeSeed = useCallback(
+ (e: ChangeEvent) =>
+ dispatch(setShouldRandomizeSeed(e.target.checked)),
+ [dispatch]
+ );
return (
- dispatch(setSeed(randomInt(NUMPY_RAND_MIN, NUMPY_RAND_MAX)));
+ const handleClickRandomizeSeed = useCallback(
+ () => dispatch(setSeed(randomInt(NUMPY_RAND_MIN, NUMPY_RAND_MAX))),
+ [dispatch]
+ );
return (
{
+ dispatch(setHorizontalSymmetrySteps(v));
+ },
+ [dispatch]
+ );
+ const handleReset = useCallback(() => {
+ dispatch(setHorizontalSymmetrySteps(0));
+ }, [dispatch]);
+
return (
dispatch(setHorizontalSymmetrySteps(v))}
+ onChange={handleChange}
min={0}
max={steps}
step={1}
withInput
withSliderMarks
withReset
- handleReset={() => dispatch(setHorizontalSymmetrySteps(0))}
+ handleReset={handleReset}
/>
);
}
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryToggle.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryToggle.tsx
index 59386ff526..5de62fd9b2 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryToggle.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryToggle.tsx
@@ -2,6 +2,7 @@ import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISwitch from 'common/components/IAISwitch';
import { setShouldUseSymmetry } from 'features/parameters/store/generationSlice';
+import { ChangeEvent, useCallback } from 'react';
export default function ParamSymmetryToggle() {
const shouldUseSymmetry = useAppSelector(
@@ -9,12 +10,18 @@ export default function ParamSymmetryToggle() {
);
const dispatch = useAppDispatch();
+ const handleChange = useCallback(
+ (e: ChangeEvent) => {
+ dispatch(setShouldUseSymmetry(e.target.checked));
+ },
+ [dispatch]
+ );
return (
dispatch(setShouldUseSymmetry(e.target.checked))}
+ onChange={handleChange}
/>
);
}
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryVertical.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryVertical.tsx
index c8ddb46a3a..90656272ec 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryVertical.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Symmetry/ParamSymmetryVertical.tsx
@@ -2,6 +2,7 @@ import { RootState } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import IAISlider from 'common/components/IAISlider';
import { setVerticalSymmetrySteps } from 'features/parameters/store/generationSlice';
+import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
export default function ParamSymmetryVertical() {
@@ -15,18 +16,28 @@ export default function ParamSymmetryVertical() {
const { t } = useTranslation();
+ const handleChange = useCallback(
+ (v: number) => {
+ dispatch(setVerticalSymmetrySteps(v));
+ },
+ [dispatch]
+ );
+ const handleReset = useCallback(() => {
+ dispatch(setVerticalSymmetrySteps(0));
+ }, [dispatch]);
+
return (
dispatch(setVerticalSymmetrySteps(v))}
+ onChange={handleChange}
min={0}
max={steps}
step={1}
withInput
withSliderMarks
withReset
- handleReset={() => dispatch(setVerticalSymmetrySteps(0))}
+ handleReset={handleReset}
/>
);
}
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Upscale/ParamRealESRGANModel.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Upscale/ParamRealESRGANModel.tsx
index 5c1bc09717..8a5ac94fac 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Upscale/ParamRealESRGANModel.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Upscale/ParamRealESRGANModel.tsx
@@ -7,6 +7,7 @@ import {
ESRGANModelName,
esrganModelNameChanged,
} from 'features/parameters/store/postprocessingSlice';
+import { useCallback } from 'react';
export const ESRGAN_MODEL_NAMES: SelectItem[] = [
{
@@ -42,8 +43,10 @@ export default function ParamESRGANModel() {
const dispatch = useAppDispatch();
- const handleChange = (v: string) =>
- dispatch(esrganModelNameChanged(v as ESRGANModelName));
+ const handleChange = useCallback(
+ (v: string) => dispatch(esrganModelNameChanged(v as ESRGANModelName)),
+ [dispatch]
+ );
return (
{
+ const handleShouldConcatPromptChange = useCallback(() => {
dispatch(setShouldConcatSDXLStylePrompt(!shouldConcatSDXLStylePrompt));
- };
+ }, [dispatch, shouldConcatSDXLStylePrompt]);
return (
) => {
- dispatch(setShouldUseSDXLRefiner(e.target.checked));
- };
+ const handleUseSDXLRefinerChange = useCallback(
+ (e: ChangeEvent) => {
+ dispatch(setShouldUseSDXLRefiner(e.target.checked));
+ },
+ [dispatch]
+ );
return (
{
useFeatureStatus('localization').isFeatureEnabled;
const language = useAppSelector(languageSelector);
+ const handleChangeShouldConfirmOnDelete = useCallback(
+ (e: ChangeEvent) => {
+ dispatch(setShouldConfirmOnDelete(e.target.checked));
+ },
+ [dispatch]
+ );
+ const handleChangeShouldUseNSFWChecker = useCallback(
+ (e: ChangeEvent) => {
+ dispatch(shouldUseNSFWCheckerChanged(e.target.checked));
+ },
+ [dispatch]
+ );
+ const handleChangeShouldUseWatermarker = useCallback(
+ (e: ChangeEvent) => {
+ dispatch(shouldUseWatermarkerChanged(e.target.checked));
+ },
+ [dispatch]
+ );
+ const handleChangeShouldUseSliders = useCallback(
+ (e: ChangeEvent) => {
+ dispatch(setShouldUseSliders(e.target.checked));
+ },
+ [dispatch]
+ );
+ const handleChangeShouldShowProgressInViewer = useCallback(
+ (e: ChangeEvent) => {
+ dispatch(setShouldShowProgressInViewer(e.target.checked));
+ },
+ [dispatch]
+ );
+ const handleChangeShouldAntialiasProgressImage = useCallback(
+ (e: ChangeEvent) => {
+ dispatch(shouldAntialiasProgressImageChanged(e.target.checked));
+ },
+ [dispatch]
+ );
+ const handleChangeShouldAutoChangeDimensions = useCallback(
+ (e: ChangeEvent) => {
+ dispatch(setShouldAutoChangeDimensions(e.target.checked));
+ },
+ [dispatch]
+ );
+ const handleChangeShouldEnableInformationalPopovers = useCallback(
+ (e: ChangeEvent) => {
+ dispatch(setShouldEnableInformationalPopovers(e.target.checked));
+ },
+ [dispatch]
+ );
+ const handleChangeEnableImageDebugging = useCallback(
+ (e: ChangeEvent) => {
+ dispatch(setEnableImageDebugging(e.target.checked));
+ },
+ [dispatch]
+ );
+
return (
<>
{cloneElement(children, {
@@ -235,9 +290,7 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
) =>
- dispatch(setShouldConfirmOnDelete(e.target.checked))
- }
+ onChange={handleChangeShouldConfirmOnDelete}
/>
@@ -248,17 +301,13 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
label="Enable NSFW Checker"
isDisabled={!isNSFWCheckerAvailable}
isChecked={shouldUseNSFWChecker}
- onChange={(e: ChangeEvent) =>
- dispatch(shouldUseNSFWCheckerChanged(e.target.checked))
- }
+ onChange={handleChangeShouldUseNSFWChecker}
/>
) =>
- dispatch(shouldUseWatermarkerChanged(e.target.checked))
- }
+ onChange={handleChangeShouldUseWatermarker}
/>
@@ -272,32 +321,22 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
) =>
- dispatch(setShouldUseSliders(e.target.checked))
- }
+ onChange={handleChangeShouldUseSliders}
/>
) =>
- dispatch(setShouldShowProgressInViewer(e.target.checked))
- }
+ onChange={handleChangeShouldShowProgressInViewer}
/>
) =>
- dispatch(
- shouldAntialiasProgressImageChanged(e.target.checked)
- )
- }
+ onChange={handleChangeShouldAntialiasProgressImage}
/>
) =>
- dispatch(setShouldAutoChangeDimensions(e.target.checked))
- }
+ onChange={handleChangeShouldAutoChangeDimensions}
/>
{shouldShowLocalizationToggle && (
{
) =>
- dispatch(
- setShouldEnableInformationalPopovers(e.target.checked)
- )
- }
+ onChange={handleChangeShouldEnableInformationalPopovers}
/>
@@ -340,9 +375,7 @@ const SettingsModal = ({ children, config }: SettingsModalProps) => {
) =>
- dispatch(setEnableImageDebugging(e.target.checked))
- }
+ onChange={handleChangeEnableImageDebugging}
/>
)}
diff --git a/invokeai/frontend/web/src/features/ui/components/FloatingGalleryButton.tsx b/invokeai/frontend/web/src/features/ui/components/FloatingGalleryButton.tsx
index b18a069cfa..c999214841 100644
--- a/invokeai/frontend/web/src/features/ui/components/FloatingGalleryButton.tsx
+++ b/invokeai/frontend/web/src/features/ui/components/FloatingGalleryButton.tsx
@@ -1,7 +1,7 @@
import { Flex } from '@chakra-ui/layout';
import { Portal } from '@chakra-ui/portal';
import IAIIconButton from 'common/components/IAIIconButton';
-import { RefObject, memo } from 'react';
+import { RefObject, memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { MdPhotoLibrary } from 'react-icons/md';
import { ImperativePanelHandle } from 'react-resizable-panels';
@@ -17,9 +17,9 @@ const FloatingGalleryButton = ({
}: Props) => {
const { t } = useTranslation();
- const handleShowGallery = () => {
+ const handleShowGallery = useCallback(() => {
galleryPanelRef.current?.expand();
- };
+ }, [galleryPanelRef]);
if (!isGalleryCollapsed) {
return null;
diff --git a/invokeai/frontend/web/src/features/ui/components/FloatingParametersPanelButtons.tsx b/invokeai/frontend/web/src/features/ui/components/FloatingParametersPanelButtons.tsx
index da4d409943..49a6e120ab 100644
--- a/invokeai/frontend/web/src/features/ui/components/FloatingParametersPanelButtons.tsx
+++ b/invokeai/frontend/web/src/features/ui/components/FloatingParametersPanelButtons.tsx
@@ -3,7 +3,7 @@ import IAIIconButton from 'common/components/IAIIconButton';
import CancelCurrentQueueItemButton from 'features/queue/components/CancelCurrentQueueItemButton';
import ClearQueueButton from 'features/queue/components/ClearQueueButton';
import QueueBackButton from 'features/queue/components/QueueBackButton';
-import { RefObject, memo } from 'react';
+import { RefObject, memo, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { FaSlidersH } from 'react-icons/fa';
@@ -25,9 +25,9 @@ const FloatingSidePanelButtons = ({
}: Props) => {
const { t } = useTranslation();
- const handleShowSidePanel = () => {
+ const handleShowSidePanel = useCallback(() => {
sidePanelRef.current?.expand();
- };
+ }, [sidePanelRef]);
if (!isSidePanelCollapsed) {
return null;
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModels.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModels.tsx
index 0fa46ec57f..98ab96dea9 100644
--- a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModels.tsx
+++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModels.tsx
@@ -1,6 +1,6 @@
import { ButtonGroup, Flex } from '@chakra-ui/react';
import IAIButton from 'common/components/IAIButton';
-import { useState } from 'react';
+import { useCallback, useState } from 'react';
import AdvancedAddModels from './AdvancedAddModels';
import SimpleAddModels from './SimpleAddModels';
@@ -8,6 +8,11 @@ export default function AddModels() {
const [addModelMode, setAddModelMode] = useState<'simple' | 'advanced'>(
'simple'
);
+ const handleAddModelSimple = useCallback(() => setAddModelMode('simple'), []);
+ const handleAddModelAdvanced = useCallback(
+ () => setAddModelMode('advanced'),
+ []
+ );
return (
setAddModelMode('simple')}
+ onClick={handleAddModelSimple}
>
Simple
setAddModelMode('advanced')}
+ onClick={handleAddModelAdvanced}
>
Advanced
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AdvancedAddCheckpoint.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AdvancedAddCheckpoint.tsx
index 94a65a9122..f2d5efb565 100644
--- a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AdvancedAddCheckpoint.tsx
+++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AdvancedAddCheckpoint.tsx
@@ -6,7 +6,7 @@ import IAIMantineTextInput from 'common/components/IAIMantineInput';
import IAISimpleCheckbox from 'common/components/IAISimpleCheckbox';
import { addToast } from 'features/system/store/systemSlice';
import { makeToast } from 'features/system/util/makeToast';
-import { useState } from 'react';
+import { FocusEventHandler, useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useAddMainModelsMutation } from 'services/api/endpoints/models';
import { CheckpointModelConfig } from 'services/api/types';
@@ -83,6 +83,27 @@ export default function AdvancedAddCheckpoint(
});
};
+ const handleBlurModelLocation: FocusEventHandler =
+ useCallback(
+ (e) => {
+ if (advancedAddCheckpointForm.values['model_name'] === '') {
+ const modelName = getModelName(e.currentTarget.value);
+ if (modelName) {
+ advancedAddCheckpointForm.setFieldValue(
+ 'model_name',
+ modelName as string
+ );
+ }
+ }
+ },
+ [advancedAddCheckpointForm]
+ );
+
+ const handleChangeUseCustomConfig = useCallback(
+ () => setUseCustomConfig((prev) => !prev),
+ []
+ );
+
return (
@@ -76,17 +93,7 @@ export default function ScanAdvancedAddModels() {
label={t('modelManager.modelType')}
value={advancedAddMode}
data={advancedAddModeData}
- onChange={(v) => {
- if (!v) {
- return;
- }
- setAdvancedAddMode(v as ManualAddMode);
- if (v === 'checkpoint') {
- setIsCheckpoint(true);
- } else {
- setIsCheckpoint(false);
- }
- }}
+ onChange={handleChangeAddMode}
/>
{isCheckpoint ? (
{
+ const scanAgainHandler = useCallback(() => {
refetchFoundModels();
- };
+ }, [refetchFoundModels]);
+
+ const handleClickClearCheckpointFolder = useCallback(() => {
+ dispatch(setSearchFolder(null));
+ dispatch(setAdvancedAddScanModel(null));
+ }, [dispatch]);
return (
}
size="sm"
- onClick={() => {
- dispatch(setSearchFolder(null));
- dispatch(setAdvancedAddScanModel(null));
- }}
+ onClick={handleClickClearCheckpointFolder}
isDisabled={!searchFolder}
colorScheme="red"
/>
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ImportModelsPanel.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ImportModelsPanel.tsx
index b0a8c124eb..acf6b705db 100644
--- a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ImportModelsPanel.tsx
+++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ImportModelsPanel.tsx
@@ -1,6 +1,6 @@
import { ButtonGroup, Flex } from '@chakra-ui/react';
import IAIButton from 'common/components/IAIButton';
-import { useState } from 'react';
+import { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import AddModels from './AddModelsPanel/AddModels';
import ScanModels from './AddModelsPanel/ScanModels';
@@ -11,11 +11,14 @@ export default function ImportModelsPanel() {
const [addModelTab, setAddModelTab] = useState('add');
const { t } = useTranslation();
+ const handleClickAddTab = useCallback(() => setAddModelTab('add'), []);
+ const handleClickScanTab = useCallback(() => setAddModelTab('scan'), []);
+
return (
setAddModelTab('add')}
+ onClick={handleClickAddTab}
isChecked={addModelTab == 'add'}
size="sm"
width="100%"
@@ -23,7 +26,7 @@ export default function ImportModelsPanel() {
{t('modelManager.addModel')}
setAddModelTab('scan')}
+ onClick={handleClickScanTab}
isChecked={addModelTab == 'scan'}
size="sm"
width="100%"
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/MergeModelsPanel.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/MergeModelsPanel.tsx
index e5c68ba6cf..f9132517c2 100644
--- a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/MergeModelsPanel.tsx
+++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/MergeModelsPanel.tsx
@@ -9,7 +9,7 @@ import IAISlider from 'common/components/IAISlider';
import { addToast } from 'features/system/store/systemSlice';
import { makeToast } from 'features/system/util/makeToast';
import { pickBy } from 'lodash-es';
-import { useMemo, useState } from 'react';
+import { ChangeEvent, useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { ALL_BASE_MODELS } from 'services/api/constants';
import {
@@ -94,13 +94,58 @@ export default function MergeModelsPanel() {
modelsMap[baseModel as keyof typeof modelsMap]
).filter((model) => model !== modelOne && model !== modelTwo);
- const handleBaseModelChange = (v: string) => {
+ const handleBaseModelChange = useCallback((v: string) => {
setBaseModel(v as BaseModelType);
setModelOne(null);
setModelTwo(null);
- };
+ }, []);
- const mergeModelsHandler = () => {
+ const handleChangeModelOne = useCallback((v: string) => {
+ setModelOne(v);
+ }, []);
+ const handleChangeModelTwo = useCallback((v: string) => {
+ setModelTwo(v);
+ }, []);
+ const handleChangeModelThree = useCallback((v: string) => {
+ if (!v) {
+ setModelThree(null);
+ setModelMergeInterp('add_difference');
+ } else {
+ setModelThree(v);
+ setModelMergeInterp('weighted_sum');
+ }
+ }, []);
+ const handleChangeMergedModelName = useCallback(
+ (e: ChangeEvent) => setMergedModelName(e.target.value),
+ []
+ );
+ const handleChangeModelMergeAlpha = useCallback(
+ (v: number) => setModelMergeAlpha(v),
+ []
+ );
+ const handleResetModelMergeAlpha = useCallback(
+ () => setModelMergeAlpha(0.5),
+ []
+ );
+ const handleChangeMergeInterp = useCallback(
+ (v: MergeInterpolationMethods) => setModelMergeInterp(v),
+ []
+ );
+ const handleChangeMergeSaveLocType = useCallback(
+ (v: 'root' | 'custom') => setModelMergeSaveLocType(v),
+ []
+ );
+ const handleChangeMergeCustomSaveLoc = useCallback(
+ (e: ChangeEvent) =>
+ setModelMergeCustomSaveLoc(e.target.value),
+ []
+ );
+ const handleChangeModelMergeForce = useCallback(
+ (e: ChangeEvent) => setModelMergeForce(e.target.checked),
+ []
+ );
+
+ const mergeModelsHandler = useCallback(() => {
const models_names: string[] = [];
let modelsToMerge: (string | null)[] = [modelOne, modelTwo, modelThree];
@@ -150,7 +195,21 @@ export default function MergeModelsPanel() {
);
}
});
- };
+ }, [
+ baseModel,
+ dispatch,
+ mergeModels,
+ mergedModelName,
+ modelMergeAlpha,
+ modelMergeCustomSaveLoc,
+ modelMergeForce,
+ modelMergeInterp,
+ modelMergeSaveLocType,
+ modelOne,
+ modelThree,
+ modelTwo,
+ t,
+ ]);
return (
@@ -180,7 +239,7 @@ export default function MergeModelsPanel() {
value={modelOne}
placeholder={t('modelManager.selectModel')}
data={modelOneList}
- onChange={(v) => setModelOne(v)}
+ onChange={handleChangeModelOne}
/>
setModelTwo(v)}
+ onChange={handleChangeModelTwo}
/>
{
- if (!v) {
- setModelThree(null);
- setModelMergeInterp('add_difference');
- } else {
- setModelThree(v);
- setModelMergeInterp('weighted_sum');
- }
- }}
+ onChange={handleChangeModelThree}
/>
setMergedModelName(e.target.value)}
+ onChange={handleChangeMergedModelName}
/>
setModelMergeAlpha(v)}
+ onChange={handleChangeModelMergeAlpha}
withInput
withReset
- handleReset={() => setModelMergeAlpha(0.5)}
+ handleReset={handleResetModelMergeAlpha}
withSliderMarks
/>
@@ -257,10 +308,7 @@ export default function MergeModelsPanel() {
{t('modelManager.interpolationType')}
- setModelMergeInterp(v)}
- >
+
{modelThree === null ? (
<>
@@ -305,7 +353,7 @@ export default function MergeModelsPanel() {
setModelMergeSaveLocType(v)}
+ onChange={handleChangeMergeSaveLocType}
>
@@ -323,7 +371,7 @@ export default function MergeModelsPanel() {
setModelMergeCustomSaveLoc(e.target.value)}
+ onChange={handleChangeMergeCustomSaveLoc}
/>
)}
@@ -331,7 +379,7 @@ export default function MergeModelsPanel() {
setModelMergeForce(e.target.checked)}
+ onChange={handleChangeModelMergeForce}
fontWeight="500"
/>
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/CheckpointModelEdit.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/CheckpointModelEdit.tsx
index f4943d3ce1..e6a8abbaaf 100644
--- a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/CheckpointModelEdit.tsx
+++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/CheckpointModelEdit.tsx
@@ -59,6 +59,11 @@ export default function CheckpointModelEdit(props: CheckpointModelEditProps) {
},
});
+ const handleChangeUseCustomConfig = useCallback(
+ () => setUseCustomConfig((prev) => !prev),
+ []
+ );
+
const editModelFormSubmitHandler = useCallback(
(values: CheckpointModelConfig) => {
const responseBody = {
@@ -181,7 +186,7 @@ export default function CheckpointModelEdit(props: CheckpointModelEditProps) {
)}
setUseCustomConfig(!useCustomConfig)}
+ onChange={handleChangeUseCustomConfig}
label="Use Custom Config"
/>
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/ModelConvert.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/ModelConvert.tsx
index 56dcdfd52f..1b92981bda 100644
--- a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/ModelConvert.tsx
+++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/ModelConvert.tsx
@@ -14,7 +14,7 @@ import IAIAlertDialog from 'common/components/IAIAlertDialog';
import IAIButton from 'common/components/IAIButton';
import IAIInput from 'common/components/IAIInput';
import { addToast } from 'features/system/store/systemSlice';
-import { useEffect, useState } from 'react';
+import { ChangeEvent, useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useConvertMainModelsMutation } from 'services/api/endpoints/models';
@@ -42,11 +42,21 @@ export default function ModelConvert(props: ModelConvertProps) {
setSaveLocation('InvokeAIRoot');
}, [model]);
- const modelConvertCancelHandler = () => {
+ const modelConvertCancelHandler = useCallback(() => {
setSaveLocation('InvokeAIRoot');
- };
+ }, []);
- const modelConvertHandler = () => {
+ const handleChangeSaveLocation = useCallback((v: string) => {
+ setSaveLocation(v as SaveLocation);
+ }, []);
+ const handleChangeCustomSaveLocation = useCallback(
+ (e: ChangeEvent) => {
+ setCustomSaveLocation(e.target.value);
+ },
+ []
+ );
+
+ const modelConvertHandler = useCallback(() => {
const queryArg = {
base_model: model.base_model,
model_name: model.model_name,
@@ -101,7 +111,15 @@ export default function ModelConvert(props: ModelConvertProps) {
)
);
});
- };
+ }, [
+ convertModel,
+ customSaveLocation,
+ dispatch,
+ model.base_model,
+ model.model_name,
+ saveLocation,
+ t,
+ ]);
return (
{t('modelManager.convertToDiffusersSaveLocation')}
- setSaveLocation(v as SaveLocation)}
- >
+
@@ -162,9 +177,7 @@ export default function ModelConvert(props: ModelConvertProps) {
{
- setCustomSaveLocation(e.target.value);
- }}
+ onChange={handleChangeCustomSaveLocation}
width="full"
/>
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/ModelList.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/ModelList.tsx
index a77d58d07f..879aea0f6c 100644
--- a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/ModelList.tsx
+++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/ModelList.tsx
@@ -100,7 +100,7 @@ const ModelList = (props: ModelListProps) => {
setModelFormatFilter('all')}
+ onClick={setModelFormatFilter.bind(null, 'all')}
isChecked={modelFormatFilter === 'all'}
size="sm"
>
@@ -108,35 +108,35 @@ const ModelList = (props: ModelListProps) => {
setModelFormatFilter('diffusers')}
+ onClick={setModelFormatFilter.bind(null, 'diffusers')}
isChecked={modelFormatFilter === 'diffusers'}
>
{t('modelManager.diffusersModels')}
setModelFormatFilter('checkpoint')}
+ onClick={setModelFormatFilter.bind(null, 'checkpoint')}
isChecked={modelFormatFilter === 'checkpoint'}
>
{t('modelManager.checkpointModels')}
setModelFormatFilter('onnx')}
+ onClick={setModelFormatFilter.bind(null, 'onnx')}
isChecked={modelFormatFilter === 'onnx'}
>
{t('modelManager.onnxModels')}
setModelFormatFilter('olive')}
+ onClick={setModelFormatFilter.bind(null, 'olive')}
isChecked={modelFormatFilter === 'olive'}
>
{t('modelManager.oliveModels')}
setModelFormatFilter('lora')}
+ onClick={setModelFormatFilter.bind(null, 'lora')}
isChecked={modelFormatFilter === 'lora'}
>
{t('modelManager.loraModels')}
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton.tsx
index 33ee345ef7..c58abaaae5 100644
--- a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton.tsx
+++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton.tsx
@@ -4,6 +4,7 @@ import IAIButton from 'common/components/IAIButton';
import IAIIconButton from 'common/components/IAIIconButton';
import { addToast } from 'features/system/store/systemSlice';
import { makeToast } from 'features/system/util/makeToast';
+import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { FaSync } from 'react-icons/fa';
import { useSyncModelsMutation } from 'services/api/endpoints/models';
@@ -19,7 +20,7 @@ export default function SyncModelsButton(props: SyncModelsButtonProps) {
const [syncModels, { isLoading }] = useSyncModelsMutation();
- const syncModelsHandler = () => {
+ const syncModelsHandler = useCallback(() => {
syncModels()
.unwrap()
.then((_) => {
@@ -44,7 +45,7 @@ export default function SyncModelsButton(props: SyncModelsButtonProps) {
);
}
});
- };
+ }, [dispatch, syncModels, t]);
return !iconMode ? (
Date: Mon, 13 Nov 2023 16:23:46 +1100
Subject: [PATCH 3/4] chore(ui): move useCopyImageToClipboard to
`common/hooks/`
---
.../{features/ui => common}/hooks/useCopyImageToClipboard.ts | 0
.../canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx | 2 +-
.../components/ImageContextMenu/SingleSelectionMenuItems.tsx | 2 +-
3 files changed, 2 insertions(+), 2 deletions(-)
rename invokeai/frontend/web/src/{features/ui => common}/hooks/useCopyImageToClipboard.ts (100%)
diff --git a/invokeai/frontend/web/src/features/ui/hooks/useCopyImageToClipboard.ts b/invokeai/frontend/web/src/common/hooks/useCopyImageToClipboard.ts
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/hooks/useCopyImageToClipboard.ts
rename to invokeai/frontend/web/src/common/hooks/useCopyImageToClipboard.ts
diff --git a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx
index 7c04208349..89a710c14d 100644
--- a/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx
+++ b/invokeai/frontend/web/src/features/canvas/components/IAICanvasToolbar/IAICanvasToolbar.tsx
@@ -25,7 +25,7 @@ import {
LAYER_NAMES_DICT,
} from 'features/canvas/store/canvasTypes';
import { getCanvasBaseLayer } from 'features/canvas/util/konvaInstanceProvider';
-import { useCopyImageToClipboard } from 'features/ui/hooks/useCopyImageToClipboard';
+import { useCopyImageToClipboard } from 'common/hooks/useCopyImageToClipboard';
import { isEqual } from 'lodash-es';
import { memo, useCallback } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx
index ed12eb5ff4..5a88ef320f 100644
--- a/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/ImageContextMenu/SingleSelectionMenuItems.tsx
@@ -13,7 +13,7 @@ import { workflowLoadRequested } from 'features/nodes/store/actions';
import { useRecallParameters } from 'features/parameters/hooks/useRecallParameters';
import { initialImageSelected } from 'features/parameters/store/actions';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
-import { useCopyImageToClipboard } from 'features/ui/hooks/useCopyImageToClipboard';
+import { useCopyImageToClipboard } from 'common/hooks/useCopyImageToClipboard';
import { setActiveTab } from 'features/ui/store/uiSlice';
import { memo, useCallback } from 'react';
import { flushSync } from 'react-dom';
From bb52861896f74680d965deade9903610a71dc828 Mon Sep 17 00:00:00 2001
From: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date: Mon, 13 Nov 2023 16:32:03 +1100
Subject: [PATCH 4/4] chore(ui): move MM components & store to `features/`
Somehow they had ended up in `features/ui/tabs` which isn't right
---
invokeai/frontend/web/src/app/store/store.ts | 2 +-
.../store/modelManagerSlice.ts | 0
.../subpanels/AddModelsPanel/AddModels.tsx | 0
.../subpanels/AddModelsPanel/AdvancedAddCheckpoint.tsx | 0
.../subpanels/AddModelsPanel/AdvancedAddDiffusers.tsx | 0
.../subpanels/AddModelsPanel/AdvancedAddModels.tsx | 0
.../subpanels/AddModelsPanel/FoundModelsList.tsx | 0
.../subpanels/AddModelsPanel/ScanAdvancedAddModels.tsx | 0
.../subpanels/AddModelsPanel/ScanModels.tsx | 0
.../subpanels/AddModelsPanel/SearchFolderForm.tsx | 0
.../subpanels/AddModelsPanel/SimpleAddModels.tsx | 0
.../subpanels/AddModelsPanel/util.ts | 0
.../subpanels/ImportModelsPanel.tsx | 0
.../subpanels/MergeModelsPanel.tsx | 0
.../subpanels/ModelManagerPanel.tsx | 0
.../subpanels/ModelManagerPanel/CheckpointModelEdit.tsx | 0
.../subpanels/ModelManagerPanel/DiffusersModelEdit.tsx | 0
.../subpanels/ModelManagerPanel/LoRAModelEdit.tsx | 0
.../subpanels/ModelManagerPanel/ModelConvert.tsx | 0
.../subpanels/ModelManagerPanel/ModelList.tsx | 0
.../subpanels/ModelManagerPanel/ModelListItem.tsx | 0
.../subpanels/ModelManagerSettingsPanel.tsx | 0
.../subpanels/ModelManagerSettingsPanel/SyncModels.tsx | 0
.../ModelManagerSettingsPanel/SyncModelsButton.tsx | 0
.../subpanels/shared/BaseModelSelect.tsx | 0
.../subpanels/shared/CheckpointConfigsSelect.tsx | 0
.../subpanels/shared/ModelVariantSelect.tsx | 0
.../Invocation/fields/inputs/MainModelInputField.tsx | 2 +-
.../Invocation/fields/inputs/RefinerModelInputField.tsx | 2 +-
.../Invocation/fields/inputs/SDXLMainModelInputField.tsx | 2 +-
.../Parameters/MainModel/ParamMainModelSelect.tsx | 2 +-
.../SDXLRefiner/ParamSDXLRefinerModelSelect.tsx | 2 +-
.../ui/components/tabs/ModelManager/ModelManagerTab.tsx | 8 ++++----
33 files changed, 10 insertions(+), 10 deletions(-)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/store/modelManagerSlice.ts (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/AddModelsPanel/AddModels.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/AddModelsPanel/AdvancedAddCheckpoint.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/AddModelsPanel/AdvancedAddDiffusers.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/AddModelsPanel/AdvancedAddModels.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/AddModelsPanel/FoundModelsList.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/AddModelsPanel/ScanAdvancedAddModels.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/AddModelsPanel/ScanModels.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/AddModelsPanel/SearchFolderForm.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/AddModelsPanel/SimpleAddModels.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/AddModelsPanel/util.ts (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/ImportModelsPanel.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/MergeModelsPanel.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/ModelManagerPanel.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/ModelManagerPanel/CheckpointModelEdit.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/ModelManagerPanel/DiffusersModelEdit.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/ModelManagerPanel/LoRAModelEdit.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/ModelManagerPanel/ModelConvert.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/ModelManagerPanel/ModelList.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/ModelManagerPanel/ModelListItem.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/ModelManagerSettingsPanel.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/ModelManagerSettingsPanel/SyncModels.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/ModelManagerSettingsPanel/SyncModelsButton.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/shared/BaseModelSelect.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/shared/CheckpointConfigsSelect.tsx (100%)
rename invokeai/frontend/web/src/features/{ui/components/tabs/ModelManager => modelManager}/subpanels/shared/ModelVariantSelect.tsx (100%)
diff --git a/invokeai/frontend/web/src/app/store/store.ts b/invokeai/frontend/web/src/app/store/store.ts
index 00cbdcccd1..49315b80dd 100644
--- a/invokeai/frontend/web/src/app/store/store.ts
+++ b/invokeai/frontend/web/src/app/store/store.ts
@@ -19,7 +19,7 @@ import sdxlReducer from 'features/sdxl/store/sdxlSlice';
import configReducer from 'features/system/store/configSlice';
import systemReducer from 'features/system/store/systemSlice';
import queueReducer from 'features/queue/store/queueSlice';
-import modelmanagerReducer from 'features/ui/components/tabs/ModelManager/store/modelManagerSlice';
+import modelmanagerReducer from 'features/modelManager/store/modelManagerSlice';
import hotkeysReducer from 'features/ui/store/hotkeysSlice';
import uiReducer from 'features/ui/store/uiSlice';
import dynamicMiddlewares from 'redux-dynamic-middlewares';
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/store/modelManagerSlice.ts b/invokeai/frontend/web/src/features/modelManager/store/modelManagerSlice.ts
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/store/modelManagerSlice.ts
rename to invokeai/frontend/web/src/features/modelManager/store/modelManagerSlice.ts
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModels.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AddModels.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AddModels.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AddModels.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AdvancedAddCheckpoint.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AdvancedAddCheckpoint.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AdvancedAddCheckpoint.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AdvancedAddCheckpoint.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AdvancedAddDiffusers.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AdvancedAddDiffusers.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AdvancedAddDiffusers.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AdvancedAddDiffusers.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AdvancedAddModels.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AdvancedAddModels.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/AdvancedAddModels.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/AdvancedAddModels.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/FoundModelsList.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/FoundModelsList.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/FoundModelsList.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/FoundModelsList.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ScanAdvancedAddModels.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/ScanAdvancedAddModels.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ScanAdvancedAddModels.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/ScanAdvancedAddModels.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ScanModels.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/ScanModels.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/ScanModels.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/ScanModels.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/SearchFolderForm.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/SearchFolderForm.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/SearchFolderForm.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/SearchFolderForm.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/SimpleAddModels.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/SimpleAddModels.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/SimpleAddModels.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/SimpleAddModels.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/util.ts b/invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/util.ts
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/AddModelsPanel/util.ts
rename to invokeai/frontend/web/src/features/modelManager/subpanels/AddModelsPanel/util.ts
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ImportModelsPanel.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ImportModelsPanel.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ImportModelsPanel.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/ImportModelsPanel.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/MergeModelsPanel.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/MergeModelsPanel.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/MergeModelsPanel.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/MergeModelsPanel.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/CheckpointModelEdit.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/CheckpointModelEdit.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/CheckpointModelEdit.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/CheckpointModelEdit.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/DiffusersModelEdit.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/DiffusersModelEdit.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/DiffusersModelEdit.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/DiffusersModelEdit.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/LoRAModelEdit.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/LoRAModelEdit.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/LoRAModelEdit.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/LoRAModelEdit.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/ModelConvert.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/ModelConvert.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/ModelConvert.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/ModelConvert.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/ModelList.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/ModelList.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/ModelList.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/ModelList.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/ModelListItem.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/ModelListItem.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerPanel/ModelListItem.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerPanel/ModelListItem.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerSettingsPanel.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerSettingsPanel.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel/SyncModels.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerSettingsPanel/SyncModels.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel/SyncModels.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerSettingsPanel/SyncModels.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/shared/BaseModelSelect.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/shared/BaseModelSelect.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/shared/BaseModelSelect.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/shared/BaseModelSelect.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/shared/CheckpointConfigsSelect.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/shared/CheckpointConfigsSelect.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/shared/CheckpointConfigsSelect.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/shared/CheckpointConfigsSelect.tsx
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/shared/ModelVariantSelect.tsx b/invokeai/frontend/web/src/features/modelManager/subpanels/shared/ModelVariantSelect.tsx
similarity index 100%
rename from invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/subpanels/shared/ModelVariantSelect.tsx
rename to invokeai/frontend/web/src/features/modelManager/subpanels/shared/ModelVariantSelect.tsx
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/MainModelInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/MainModelInputField.tsx
index 08483986e3..af68b4291c 100644
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/MainModelInputField.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/MainModelInputField.tsx
@@ -11,7 +11,7 @@ import {
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
import { modelIdToMainModelParam } from 'features/parameters/util/modelIdToMainModelParam';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
-import SyncModelsButton from 'features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton';
+import SyncModelsButton from 'features/modelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton';
import { forEach } from 'lodash-es';
import { memo, useCallback, useMemo } from 'react';
import { NON_SDXL_MAIN_MODELS } from 'services/api/constants';
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/RefinerModelInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/RefinerModelInputField.tsx
index 19f2c5ac8e..e6db6031b8 100644
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/RefinerModelInputField.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/RefinerModelInputField.tsx
@@ -11,7 +11,7 @@ import {
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
import { modelIdToMainModelParam } from 'features/parameters/util/modelIdToMainModelParam';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
-import SyncModelsButton from 'features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton';
+import SyncModelsButton from 'features/modelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton';
import { forEach } from 'lodash-es';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
diff --git a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/SDXLMainModelInputField.tsx b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/SDXLMainModelInputField.tsx
index 89cb8d5150..c6ef5c6bb4 100644
--- a/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/SDXLMainModelInputField.tsx
+++ b/invokeai/frontend/web/src/features/nodes/components/flow/nodes/Invocation/fields/inputs/SDXLMainModelInputField.tsx
@@ -11,7 +11,7 @@ import {
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
import { modelIdToMainModelParam } from 'features/parameters/util/modelIdToMainModelParam';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
-import SyncModelsButton from 'features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton';
+import SyncModelsButton from 'features/modelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton';
import { forEach } from 'lodash-es';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/MainModel/ParamMainModelSelect.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/MainModel/ParamMainModelSelect.tsx
index f4d7421eed..74b6e7e0f3 100644
--- a/invokeai/frontend/web/src/features/parameters/components/Parameters/MainModel/ParamMainModelSelect.tsx
+++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/MainModel/ParamMainModelSelect.tsx
@@ -12,7 +12,7 @@ import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions';
import { modelSelected } from 'features/parameters/store/actions';
import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
import { modelIdToMainModelParam } from 'features/parameters/util/modelIdToMainModelParam';
-import SyncModelsButton from 'features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton';
+import SyncModelsButton from 'features/modelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton';
import { activeTabNameSelector } from 'features/ui/store/uiSelectors';
import { forEach } from 'lodash-es';
import { NON_REFINER_BASE_MODELS } from 'services/api/constants';
diff --git a/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerModelSelect.tsx b/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerModelSelect.tsx
index cb337740ed..292f20f1fc 100644
--- a/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerModelSelect.tsx
+++ b/invokeai/frontend/web/src/features/sdxl/components/SDXLRefiner/ParamSDXLRefinerModelSelect.tsx
@@ -9,7 +9,7 @@ import { MODEL_TYPE_MAP } from 'features/parameters/types/constants';
import { modelIdToSDXLRefinerModelParam } from 'features/parameters/util/modelIdToSDXLRefinerModelParam';
import { refinerModelChanged } from 'features/sdxl/store/sdxlSlice';
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
-import SyncModelsButton from 'features/ui/components/tabs/ModelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton';
+import SyncModelsButton from 'features/modelManager/subpanels/ModelManagerSettingsPanel/SyncModelsButton';
import { forEach } from 'lodash-es';
import { memo, useCallback, useMemo } from 'react';
import { REFINER_BASE_MODELS } from 'services/api/constants';
diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/ModelManagerTab.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/ModelManagerTab.tsx
index 1c8ea3a735..50a9b3b581 100644
--- a/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/ModelManagerTab.tsx
+++ b/invokeai/frontend/web/src/features/ui/components/tabs/ModelManager/ModelManagerTab.tsx
@@ -1,10 +1,10 @@
import { Tab, TabList, TabPanel, TabPanels, Tabs } from '@chakra-ui/react';
import i18n from 'i18n';
import { ReactNode, memo } from 'react';
-import ImportModelsPanel from './subpanels/ImportModelsPanel';
-import MergeModelsPanel from './subpanels/MergeModelsPanel';
-import ModelManagerPanel from './subpanels/ModelManagerPanel';
-import ModelManagerSettingsPanel from './subpanels/ModelManagerSettingsPanel';
+import ImportModelsPanel from '../../../../modelManager/subpanels/ImportModelsPanel';
+import MergeModelsPanel from '../../../../modelManager/subpanels/MergeModelsPanel';
+import ModelManagerPanel from '../../../../modelManager/subpanels/ModelManagerPanel';
+import ModelManagerSettingsPanel from '../../../../modelManager/subpanels/ModelManagerSettingsPanel';
type ModelManagerTabName =
| 'modelManager'