From a30933b09c3a801dd262e2e7cff4430960689d3b Mon Sep 17 00:00:00 2001
From: psychedelicious <4822129+psychedelicious@users.noreply.github.com>
Date: Fri, 20 Jun 2025 17:01:19 +1000
Subject: [PATCH] feat(ui): clean up image view components & code
---
.../SimpleSession/SimpleSession.tsx | 35 ------
.../ImageViewer/CurrentImageButtons.tsx | 32 ++----
.../ImageViewer/CurrentImagePreview.tsx | 19 +---
.../ImageViewer/CurrentImagePreview2.tsx | 105 ------------------
.../ImageViewer/GenerationProgressPanel.tsx | 2 +-
.../components/ImageViewer/ImageViewer.tsx | 22 +++-
.../components/ImageViewer/ImageViewer2.tsx | 42 -------
.../ImageViewer/ImageViewerPanel.tsx | 4 +-
.../components/ImageViewer/ProgressImage.tsx | 45 +++++---
.../components/ImageViewer/ProgressImage2.tsx | 56 ----------
.../ToggleMetadataViewerButton.tsx | 9 +-
.../components/ImageViewer/ViewerToolbar.tsx | 30 ++---
.../components/ImageViewer/ViewerToolbar2.tsx | 18 ---
.../features/gallery/hooks/useImageActions.ts | 43 +++++--
.../ui/components/MainPanelContent.tsx | 39 -------
15 files changed, 110 insertions(+), 391 deletions(-)
delete mode 100644 invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/SimpleSession.tsx
delete mode 100644 invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImagePreview2.tsx
delete mode 100644 invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewer2.tsx
delete mode 100644 invokeai/frontend/web/src/features/gallery/components/ImageViewer/ProgressImage2.tsx
delete mode 100644 invokeai/frontend/web/src/features/gallery/components/ImageViewer/ViewerToolbar2.tsx
delete mode 100644 invokeai/frontend/web/src/features/ui/components/MainPanelContent.tsx
diff --git a/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/SimpleSession.tsx b/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/SimpleSession.tsx
deleted file mode 100644
index 693fa27e1f..0000000000
--- a/invokeai/frontend/web/src/features/controlLayers/components/SimpleSession/SimpleSession.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import { Flex, Tab, TabList, TabPanel, TabPanels, Tabs } from '@invoke-ai/ui-library';
-import { GenerateLaunchpadPanel } from 'features/controlLayers/components/SimpleSession/GenerateLaunchpadPanel';
-import { ImageViewer } from 'features/gallery/components/ImageViewer/ImageViewer2';
-import { ProgressImage } from 'features/gallery/components/ImageViewer/ProgressImage2';
-import { ViewerToolbar } from 'features/gallery/components/ImageViewer/ViewerToolbar2';
-import { memo } from 'react';
-
-export const SimpleSession = memo(() => {
- return (
-
-
- Launchpad
- Viewer
- Generation Progress
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
-});
-SimpleSession.displayName = 'SimpleSession';
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImageButtons.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImageButtons.tsx
index 9bef56ccd2..9332a2bfaf 100644
--- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImageButtons.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImageButtons.tsx
@@ -22,25 +22,13 @@ import {
PiRulerBold,
} from 'react-icons/pi';
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
-import type { ImageDTO } from 'services/api/types';
-const CurrentImageButtons = () => {
+export const CurrentImageButtons = memo(() => {
const lastSelectedImage = useAppSelector(selectLastSelectedImage);
const { currentData: imageDTO } = useGetImageDTOQuery(lastSelectedImage?.image_name ?? skipToken);
-
- if (!imageDTO) {
- return null;
- }
-
- return ;
-};
-
-export default memo(CurrentImageButtons);
-
-const CurrentImageButtonsContent = memo(({ imageDTO }: { imageDTO: ImageDTO }) => {
const { t } = useTranslation();
const hasTemplates = useStore($hasTemplates);
- const imageActions = useImageActions(imageDTO);
+ const imageActions = useImageActions(imageDTO ?? null);
const isStaging = useAppSelector(selectIsStaging);
const isUpscalingEnabled = useFeatureStatus('upscaling');
@@ -65,7 +53,7 @@ const CurrentImageButtonsContent = memo(({ imageDTO }: { imageDTO: ImageDTO }) =
icon={}
tooltip={`${t('nodes.loadWorkflow')} (W)`}
aria-label={`${t('nodes.loadWorkflow')} (W)`}
- isDisabled={!imageActions.hasWorkflow || !hasTemplates}
+ isDisabled={!imageDTO || !imageActions.hasWorkflow || !hasTemplates}
variant="link"
alignSelf="stretch"
onClick={imageActions.loadWorkflow}
@@ -74,7 +62,7 @@ const CurrentImageButtonsContent = memo(({ imageDTO }: { imageDTO: ImageDTO }) =
icon={}
tooltip={`${t('parameters.remixImage')} (R)`}
aria-label={`${t('parameters.remixImage')} (R)`}
- isDisabled={!imageActions.hasMetadata}
+ isDisabled={!imageDTO || !imageActions.hasMetadata}
variant="link"
alignSelf="stretch"
onClick={imageActions.remix}
@@ -83,7 +71,7 @@ const CurrentImageButtonsContent = memo(({ imageDTO }: { imageDTO: ImageDTO }) =
icon={}
tooltip={`${t('parameters.usePrompt')} (P)`}
aria-label={`${t('parameters.usePrompt')} (P)`}
- isDisabled={!imageActions.hasPrompts}
+ isDisabled={!imageDTO || !imageActions.hasPrompts}
variant="link"
alignSelf="stretch"
onClick={imageActions.recallPrompts}
@@ -92,7 +80,7 @@ const CurrentImageButtonsContent = memo(({ imageDTO }: { imageDTO: ImageDTO }) =
icon={}
tooltip={`${t('parameters.useSeed')} (S)`}
aria-label={`${t('parameters.useSeed')} (S)`}
- isDisabled={!imageActions.hasSeed}
+ isDisabled={!imageDTO || !imageActions.hasSeed}
variant="link"
alignSelf="stretch"
onClick={imageActions.recallSeed}
@@ -104,13 +92,13 @@ const CurrentImageButtonsContent = memo(({ imageDTO }: { imageDTO: ImageDTO }) =
variant="link"
alignSelf="stretch"
onClick={imageActions.recallSize}
- isDisabled={isStaging}
+ isDisabled={!imageDTO || isStaging}
/>
}
tooltip={`${t('parameters.useAll')} (A)`}
aria-label={`${t('parameters.useAll')} (A)`}
- isDisabled={!imageActions.hasMetadata}
+ isDisabled={!imageDTO || !imageActions.hasMetadata}
variant="link"
alignSelf="stretch"
onClick={imageActions.recallAll}
@@ -120,9 +108,9 @@ const CurrentImageButtonsContent = memo(({ imageDTO }: { imageDTO: ImageDTO }) =
-
+
>
);
});
-CurrentImageButtonsContent.displayName = 'CurrentImageButtonsContent';
+CurrentImageButtons.displayName = 'CurrentImageButtons';
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImagePreview.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImagePreview.tsx
index b2f5158b7a..7b153a74cf 100644
--- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImagePreview.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImagePreview.tsx
@@ -1,21 +1,18 @@
import { Box, Flex } from '@invoke-ai/ui-library';
-import { useStore } from '@nanostores/react';
import { useAppSelector } from 'app/store/storeHooks';
import { CanvasAlertsInvocationProgress } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsInvocationProgress';
import { DndImage } from 'features/dnd/DndImage';
import ImageMetadataViewer from 'features/gallery/components/ImageMetadataViewer/ImageMetadataViewer';
import NextPrevImageButtons from 'features/gallery/components/NextPrevImageButtons';
-import { selectShouldShowImageDetails, selectShouldShowProgressInViewer } from 'features/ui/store/uiSelectors';
+import { selectShouldShowImageDetails } from 'features/ui/store/uiSelectors';
import type { AnimationProps } from 'framer-motion';
import { AnimatePresence, motion } from 'framer-motion';
import { memo, useCallback, useRef, useState } from 'react';
import type { ImageDTO } from 'services/api/types';
-import { $hasLastProgressImage } from 'services/events/stores';
import { NoContentForViewer } from './NoContentForViewer';
-import ProgressImage from './ProgressImage';
-const CurrentImagePreview = ({ imageDTO }: { imageDTO?: ImageDTO }) => {
+export const CurrentImagePreview = memo(({ imageDTO }: { imageDTO?: ImageDTO }) => {
const shouldShowImageDetails = useAppSelector(selectShouldShowImageDetails);
// Show and hide the next/prev buttons on mouse move
@@ -79,18 +76,10 @@ const CurrentImagePreview = ({ imageDTO }: { imageDTO?: ImageDTO }) => {
);
-};
-
-export default memo(CurrentImagePreview);
+});
+CurrentImagePreview.displayName = 'CurrentImagePreview';
const ImageContent = memo(({ imageDTO }: { imageDTO?: ImageDTO }) => {
- const hasProgressImage = useStore($hasLastProgressImage);
- const shouldShowProgressInViewer = useAppSelector(selectShouldShowProgressInViewer);
-
- if (hasProgressImage && shouldShowProgressInViewer) {
- return ;
- }
-
if (!imageDTO) {
return ;
}
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImagePreview2.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImagePreview2.tsx
deleted file mode 100644
index 7b153a74cf..0000000000
--- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImagePreview2.tsx
+++ /dev/null
@@ -1,105 +0,0 @@
-import { Box, Flex } from '@invoke-ai/ui-library';
-import { useAppSelector } from 'app/store/storeHooks';
-import { CanvasAlertsInvocationProgress } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsInvocationProgress';
-import { DndImage } from 'features/dnd/DndImage';
-import ImageMetadataViewer from 'features/gallery/components/ImageMetadataViewer/ImageMetadataViewer';
-import NextPrevImageButtons from 'features/gallery/components/NextPrevImageButtons';
-import { selectShouldShowImageDetails } from 'features/ui/store/uiSelectors';
-import type { AnimationProps } from 'framer-motion';
-import { AnimatePresence, motion } from 'framer-motion';
-import { memo, useCallback, useRef, useState } from 'react';
-import type { ImageDTO } from 'services/api/types';
-
-import { NoContentForViewer } from './NoContentForViewer';
-
-export const CurrentImagePreview = memo(({ imageDTO }: { imageDTO?: ImageDTO }) => {
- const shouldShowImageDetails = useAppSelector(selectShouldShowImageDetails);
-
- // Show and hide the next/prev buttons on mouse move
- const [shouldShowNextPrevButtons, setShouldShowNextPrevButtons] = useState(false);
- const timeoutId = useRef(0);
- const onMouseOver = useCallback(() => {
- setShouldShowNextPrevButtons(true);
- window.clearTimeout(timeoutId.current);
- }, []);
- const onMouseOut = useCallback(() => {
- timeoutId.current = window.setTimeout(() => {
- setShouldShowNextPrevButtons(false);
- }, 500);
- }, []);
-
- return (
-
-
-
-
-
- {shouldShowImageDetails && imageDTO && (
-
-
-
- )}
-
- {shouldShowNextPrevButtons && imageDTO && (
-
-
-
- )}
-
-
- );
-});
-CurrentImagePreview.displayName = 'CurrentImagePreview';
-
-const ImageContent = memo(({ imageDTO }: { imageDTO?: ImageDTO }) => {
- if (!imageDTO) {
- return ;
- }
-
- return (
-
-
-
- );
-});
-ImageContent.displayName = 'ImageContent';
-
-const initial: AnimationProps['initial'] = {
- opacity: 0,
-};
-const animateArrows: AnimationProps['animate'] = {
- opacity: 1,
- transition: { duration: 0.07 },
-};
-const exit: AnimationProps['exit'] = {
- opacity: 0,
- transition: { duration: 0.07 },
-};
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/GenerationProgressPanel.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/GenerationProgressPanel.tsx
index bfcda19650..23cce5ce90 100644
--- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/GenerationProgressPanel.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/GenerationProgressPanel.tsx
@@ -1,5 +1,5 @@
import { Flex } from '@invoke-ai/ui-library';
-import { ProgressImage } from 'features/gallery/components/ImageViewer/ProgressImage2';
+import { ProgressImage } from 'features/gallery/components/ImageViewer/ProgressImage';
import { memo } from 'react';
export const GenerationProgressPanel = memo(() => (
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewer.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewer.tsx
index 6f27298eb6..6ca2e1b8c5 100644
--- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewer.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewer.tsx
@@ -1,12 +1,32 @@
import { skipToken } from '@reduxjs/toolkit/query';
import { useAppSelector } from 'app/store/storeHooks';
import { selectImageToCompare } from 'features/gallery/components/ImageViewer/common';
-import CurrentImagePreview from 'features/gallery/components/ImageViewer/CurrentImagePreview';
+import { CurrentImagePreview } from 'features/gallery/components/ImageViewer/CurrentImagePreview';
import { ImageComparison } from 'features/gallery/components/ImageViewer/ImageComparison';
import { selectLastSelectedImageName } from 'features/gallery/store/gallerySelectors';
import { memo } from 'react';
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
+// type Props = {
+// closeButton?: ReactNode;
+// };
+
+// const useFocusRegionOptions = {
+// focusOnMount: true,
+// };
+
+// const FOCUS_REGION_STYLES: SystemStyleObject = {
+// display: 'flex',
+// width: 'full',
+// height: 'full',
+// position: 'absolute',
+// flexDirection: 'column',
+// inset: 0,
+// alignItems: 'center',
+// justifyContent: 'center',
+// overflow: 'hidden',
+// };
+
export const ImageViewer = memo(() => {
const lastSelectedImageName = useAppSelector(selectLastSelectedImageName);
const { data: lastSelectedImageDTO } = useGetImageDTOQuery(lastSelectedImageName ?? skipToken);
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewer2.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewer2.tsx
deleted file mode 100644
index 510a974a25..0000000000
--- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewer2.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { skipToken } from '@reduxjs/toolkit/query';
-import { useAppSelector } from 'app/store/storeHooks';
-import { selectImageToCompare } from 'features/gallery/components/ImageViewer/common';
-import { CurrentImagePreview } from 'features/gallery/components/ImageViewer/CurrentImagePreview2';
-import { ImageComparison } from 'features/gallery/components/ImageViewer/ImageComparison';
-import { selectLastSelectedImageName } from 'features/gallery/store/gallerySelectors';
-import { memo } from 'react';
-import { useGetImageDTOQuery } from 'services/api/endpoints/images';
-
-// type Props = {
-// closeButton?: ReactNode;
-// };
-
-// const useFocusRegionOptions = {
-// focusOnMount: true,
-// };
-
-// const FOCUS_REGION_STYLES: SystemStyleObject = {
-// display: 'flex',
-// width: 'full',
-// height: 'full',
-// position: 'absolute',
-// flexDirection: 'column',
-// inset: 0,
-// alignItems: 'center',
-// justifyContent: 'center',
-// overflow: 'hidden',
-// };
-
-export const ImageViewer = memo(() => {
- const lastSelectedImageName = useAppSelector(selectLastSelectedImageName);
- const { data: lastSelectedImageDTO } = useGetImageDTOQuery(lastSelectedImageName ?? skipToken);
- const comparisonImageDTO = useAppSelector(selectImageToCompare);
-
- if (lastSelectedImageDTO && comparisonImageDTO) {
- return ;
- }
-
- return ;
-});
-
-ImageViewer.displayName = 'ImageViewer';
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewerPanel.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewerPanel.tsx
index 0fd32cfa54..765a6e0909 100644
--- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewerPanel.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewerPanel.tsx
@@ -1,6 +1,6 @@
import { Divider, Flex } from '@invoke-ai/ui-library';
-import { ImageViewer } from 'features/gallery/components/ImageViewer/ImageViewer2';
-import { ViewerToolbar } from 'features/gallery/components/ImageViewer/ViewerToolbar2';
+import { ImageViewer } from 'features/gallery/components/ImageViewer/ImageViewer';
+import { ViewerToolbar } from 'features/gallery/components/ImageViewer/ViewerToolbar';
import { memo } from 'react';
export const ImageViewerPanel = memo(() => (
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ProgressImage.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ProgressImage.tsx
index 03453e4c56..850ebc63e1 100644
--- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ProgressImage.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ProgressImage.tsx
@@ -1,10 +1,12 @@
import type { SystemStyleObject } from '@invoke-ai/ui-library';
-import { Image } from '@invoke-ai/ui-library';
+import { Flex, Image } from '@invoke-ai/ui-library';
import { useStore } from '@nanostores/react';
import { createSelector } from '@reduxjs/toolkit';
import { useAppSelector } from 'app/store/storeHooks';
+import { IAINoContentFallback } from 'common/components/IAIImageFallback';
import { selectSystemSlice } from 'features/system/store/systemSlice';
import { memo, useMemo } from 'react';
+import { PiPulseBold } from 'react-icons/pi';
import { $lastProgressImage } from 'services/events/stores';
const selectShouldAntialiasProgressImage = createSelector(
@@ -12,7 +14,7 @@ const selectShouldAntialiasProgressImage = createSelector(
(system) => system.shouldAntialiasProgressImage
);
-const CurrentImagePreview = () => {
+export const ProgressImage = memo(() => {
const progressImage = useStore($lastProgressImage);
const shouldAntialiasProgressImage = useAppSelector(selectShouldAntialiasProgressImage);
@@ -24,24 +26,31 @@ const CurrentImagePreview = () => {
);
if (!progressImage) {
- return null;
+ return (
+
+
+
+ );
}
return (
-
+
+
+
);
-};
+});
-export default memo(CurrentImagePreview);
+ProgressImage.displayName = 'ProgressImage';
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ProgressImage2.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ProgressImage2.tsx
deleted file mode 100644
index 850ebc63e1..0000000000
--- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ProgressImage2.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import type { SystemStyleObject } from '@invoke-ai/ui-library';
-import { Flex, Image } from '@invoke-ai/ui-library';
-import { useStore } from '@nanostores/react';
-import { createSelector } from '@reduxjs/toolkit';
-import { useAppSelector } from 'app/store/storeHooks';
-import { IAINoContentFallback } from 'common/components/IAIImageFallback';
-import { selectSystemSlice } from 'features/system/store/systemSlice';
-import { memo, useMemo } from 'react';
-import { PiPulseBold } from 'react-icons/pi';
-import { $lastProgressImage } from 'services/events/stores';
-
-const selectShouldAntialiasProgressImage = createSelector(
- selectSystemSlice,
- (system) => system.shouldAntialiasProgressImage
-);
-
-export const ProgressImage = memo(() => {
- const progressImage = useStore($lastProgressImage);
- const shouldAntialiasProgressImage = useAppSelector(selectShouldAntialiasProgressImage);
-
- const sx = useMemo(
- () => ({
- imageRendering: shouldAntialiasProgressImage ? 'auto' : 'pixelated',
- }),
- [shouldAntialiasProgressImage]
- );
-
- if (!progressImage) {
- return (
-
-
-
- );
- }
-
- return (
-
-
-
- );
-});
-
-ProgressImage.displayName = 'ProgressImage';
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ToggleMetadataViewerButton.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ToggleMetadataViewerButton.tsx
index 5d552e57d9..e40cb510c6 100644
--- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ToggleMetadataViewerButton.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ToggleMetadataViewerButton.tsx
@@ -14,16 +14,14 @@ export const ToggleMetadataViewerButton = memo(() => {
const imageDTO = useAppSelector(selectLastSelectedImage);
const { t } = useTranslation();
- const toggleMetadataViewer = useCallback(
- () => dispatch(setShouldShowImageDetails(!shouldShowImageDetails)),
- [dispatch, shouldShowImageDetails]
- );
+ const toggleMetadataViewer = useCallback(() => {
+ dispatch(setShouldShowImageDetails(!shouldShowImageDetails));
+ }, [dispatch, shouldShowImageDetails]);
useRegisteredHotkeys({
id: 'toggleMetadata',
category: 'viewer',
callback: toggleMetadataViewer,
- options: { enabled: Boolean(imageDTO) },
dependencies: [imageDTO, shouldShowImageDetails],
});
@@ -33,7 +31,6 @@ export const ToggleMetadataViewerButton = memo(() => {
tooltip={`${t('parameters.info')} (I)`}
aria-label={`${t('parameters.info')} (I)`}
onClick={toggleMetadataViewer}
- isDisabled={!imageDTO}
variant="link"
alignSelf="stretch"
colorScheme={shouldShowImageDetails ? 'invokeBlue' : 'base'}
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ViewerToolbar.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ViewerToolbar.tsx
index e4bdf895f4..1c5a67bae8 100644
--- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ViewerToolbar.tsx
+++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ViewerToolbar.tsx
@@ -1,32 +1,16 @@
-import { Flex } from '@invoke-ai/ui-library';
+import { ButtonGroup, Flex } from '@invoke-ai/ui-library';
import { ToggleMetadataViewerButton } from 'features/gallery/components/ImageViewer/ToggleMetadataViewerButton';
-import { ToggleProgressButton } from 'features/gallery/components/ImageViewer/ToggleProgressButton';
-import type { ReactNode } from 'react';
import { memo } from 'react';
-import CurrentImageButtons from './CurrentImageButtons';
+import { CurrentImageButtons } from './CurrentImageButtons';
-type Props = {
- closeButton?: ReactNode;
-};
-
-export const ViewerToolbar = memo(({ closeButton }: Props) => {
+export const ViewerToolbar = memo(() => {
return (
-
-
-
-
-
-
-
-
+
+
+
-
-
-
- {closeButton}
-
-
+
);
});
diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ViewerToolbar2.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ViewerToolbar2.tsx
deleted file mode 100644
index f8dc34d654..0000000000
--- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ViewerToolbar2.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import { ButtonGroup, Flex } from '@invoke-ai/ui-library';
-import { ToggleMetadataViewerButton } from 'features/gallery/components/ImageViewer/ToggleMetadataViewerButton';
-import { memo } from 'react';
-
-import CurrentImageButtons from './CurrentImageButtons';
-
-export const ViewerToolbar = memo(() => {
- return (
-
-
-
-
-
-
- );
-});
-
-ViewerToolbar.displayName = 'ViewerToolbar';
diff --git a/invokeai/frontend/web/src/features/gallery/hooks/useImageActions.ts b/invokeai/frontend/web/src/features/gallery/hooks/useImageActions.ts
index cb37c2c11c..90cc41e689 100644
--- a/invokeai/frontend/web/src/features/gallery/hooks/useImageActions.ts
+++ b/invokeai/frontend/web/src/features/gallery/hooks/useImageActions.ts
@@ -24,12 +24,12 @@ import { useTranslation } from 'react-i18next';
import { useDebouncedMetadata } from 'services/api/hooks/useDebouncedMetadata';
import type { ImageDTO } from 'services/api/types';
-export const useImageActions = (imageDTO: ImageDTO) => {
+export const useImageActions = (imageDTO: ImageDTO | null) => {
const { dispatch, getState } = useAppStore();
const { t } = useTranslation();
const activeStylePresetId = useAppSelector(selectStylePresetActivePresetId);
const isStaging = useAppSelector(selectIsStaging);
- const { metadata } = useDebouncedMetadata(imageDTO.image_name);
+ const { metadata } = useDebouncedMetadata(imageDTO?.image_name ?? null);
const [hasMetadata, setHasMetadata] = useState(false);
const [hasSeed, setHasSeed] = useState(false);
const [hasPrompts, setHasPrompts] = useState(false);
@@ -79,15 +79,21 @@ export const useImageActions = (imageDTO: ImageDTO) => {
}, [dispatch, activeStylePresetId, t]);
const recallAll = useCallback(() => {
+ if (!imageDTO) {
+ return;
+ }
if (!metadata) {
return;
}
const activeTabName = selectActiveTab(getState());
parseAndRecallAllMetadata(metadata, activeTabName === 'canvas', isStaging ? ['width', 'height'] : []);
clearStylePreset();
- }, [metadata, getState, isStaging, clearStylePreset]);
+ }, [imageDTO, metadata, getState, isStaging, clearStylePreset]);
const remix = useCallback(() => {
+ if (!imageDTO) {
+ return;
+ }
if (!metadata) {
return;
}
@@ -95,9 +101,12 @@ export const useImageActions = (imageDTO: ImageDTO) => {
// Recalls all metadata parameters except seed
parseAndRecallAllMetadata(metadata, activeTabName === 'canvas', ['seed']);
clearStylePreset();
- }, [metadata, getState, clearStylePreset]);
+ }, [imageDTO, metadata, getState, clearStylePreset]);
const recallSeed = useCallback(() => {
+ if (!imageDTO) {
+ return;
+ }
if (!metadata) {
return;
}
@@ -109,17 +118,23 @@ export const useImageActions = (imageDTO: ImageDTO) => {
.catch(() => {
// no-op, the toast will show the error
});
- }, [metadata]);
+ }, [imageDTO, metadata]);
const recallPrompts = useCallback(() => {
+ if (!imageDTO) {
+ return;
+ }
if (!metadata) {
return;
}
parseAndRecallPrompts(metadata);
clearStylePreset();
- }, [metadata, clearStylePreset]);
+ }, [imageDTO, metadata, clearStylePreset]);
const createAsPreset = useCallback(async () => {
+ if (!imageDTO) {
+ return;
+ }
if (!metadata) {
return;
}
@@ -153,14 +168,20 @@ export const useImageActions = (imageDTO: ImageDTO) => {
const loadWorkflowWithDialog = useLoadWorkflowWithDialog();
const loadWorkflowFromImage = useCallback(() => {
+ if (!imageDTO) {
+ return;
+ }
if (!imageDTO.has_workflow || !hasTemplates) {
return;
}
loadWorkflowWithDialog({ type: 'image', data: imageDTO.image_name });
- }, [hasTemplates, imageDTO.has_workflow, imageDTO.image_name, loadWorkflowWithDialog]);
+ }, [hasTemplates, imageDTO, loadWorkflowWithDialog]);
const recallSize = useCallback(() => {
+ if (!imageDTO) {
+ return;
+ }
if (isStaging) {
return;
}
@@ -168,10 +189,16 @@ export const useImageActions = (imageDTO: ImageDTO) => {
}, [imageDTO, isStaging]);
const upscale = useCallback(() => {
+ if (!imageDTO) {
+ return;
+ }
dispatch(adHocPostProcessingRequested({ imageDTO }));
}, [dispatch, imageDTO]);
const _delete = useCallback(() => {
+ if (!imageDTO) {
+ return;
+ }
deleteImageModal.delete([imageDTO]);
}, [deleteImageModal, imageDTO]);
@@ -185,7 +212,7 @@ export const useImageActions = (imageDTO: ImageDTO) => {
recallPrompts,
createAsPreset,
loadWorkflow: loadWorkflowFromImage,
- hasWorkflow: imageDTO.has_workflow,
+ hasWorkflow: imageDTO?.has_workflow ?? false,
recallSize,
upscale,
delete: _delete,
diff --git a/invokeai/frontend/web/src/features/ui/components/MainPanelContent.tsx b/invokeai/frontend/web/src/features/ui/components/MainPanelContent.tsx
deleted file mode 100644
index ec5e41deff..0000000000
--- a/invokeai/frontend/web/src/features/ui/components/MainPanelContent.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-import { useAppSelector } from 'app/store/storeHooks';
-import { AdvancedSession } from 'features/controlLayers/components/AdvancedSession/AdvancedSession';
-import { SimpleSession } from 'features/controlLayers/components/SimpleSession/SimpleSession';
-import { selectCanvasSessionId } from 'features/controlLayers/store/canvasStagingAreaSlice';
-import { ImageViewer } from 'features/gallery/components/ImageViewer/ImageViewer';
-import ModelManagerTab from 'features/ui/components/tabs/ModelManagerTab';
-import QueueTab from 'features/ui/components/tabs/QueueTab';
-import { WorkflowsMainPanel } from 'features/ui/components/tabs/WorkflowsTabContent';
-import { selectActiveTab } from 'features/ui/store/uiSelectors';
-import { memo } from 'react';
-import type { Equals } from 'tsafe';
-import { assert } from 'tsafe';
-
-export const MainPanelContent = memo(() => {
- const tab = useAppSelector(selectActiveTab);
- const canvasId = useAppSelector(selectCanvasSessionId);
-
- if (tab === 'generate') {
- return ;
- }
- if (tab === 'canvas') {
- return ;
- }
- if (tab === 'upscaling') {
- return ;
- }
- if (tab === 'workflows') {
- return ;
- }
- if (tab === 'models') {
- return ;
- }
- if (tab === 'queue') {
- return ;
- }
-
- assert>(false);
-});
-MainPanelContent.displayName = 'MainPanelContent';