From 0b0abfbe8f2e5d96987000dfe61157f79da59cf4 Mon Sep 17 00:00:00 2001 From: Mary Hipp Date: Wed, 7 Aug 2024 10:36:38 -0400 Subject: [PATCH] clean up image implementation --- invokeai/app/api/routers/style_presets.py | 7 +- .../style_preset_images_default.py | 2 + .../components/ActiveStylePreset.tsx | 32 ++-- .../components/StylePresetImage.tsx | 16 +- .../components/StylePresetListItem.tsx | 139 ++++++++++-------- .../components/StylePresetMenuTrigger.tsx | 4 +- .../hooks/useStylePresetFields.ts | 4 +- .../ParametersPanelTextToImage.tsx | 95 ++++++------ 8 files changed, 167 insertions(+), 132 deletions(-) diff --git a/invokeai/app/api/routers/style_presets.py b/invokeai/app/api/routers/style_presets.py index 6e31e226c5..f7157c6ec3 100644 --- a/invokeai/app/api/routers/style_presets.py +++ b/invokeai/app/api/routers/style_presets.py @@ -8,6 +8,7 @@ from PIL import Image from invokeai.app.api.dependencies import ApiDependencies from invokeai.app.api.routers.model_manager import IMAGE_MAX_AGE +from invokeai.app.services.style_preset_images.style_preset_images_common import StylePresetImageFileNotFoundException from invokeai.app.services.style_preset_records.style_preset_records_common import ( PresetData, StylePresetChanges, @@ -91,7 +92,11 @@ async def delete_style_preset( style_preset_id: str = Path(description="The style preset to delete"), ) -> None: """Deletes a style preset""" - ApiDependencies.invoker.services.style_preset_images_service.delete(style_preset_id) + try: + ApiDependencies.invoker.services.style_preset_images_service.delete(style_preset_id) + except StylePresetImageFileNotFoundException: + pass + ApiDependencies.invoker.services.style_preset_records.delete(style_preset_id) diff --git a/invokeai/app/services/style_preset_images/style_preset_images_default.py b/invokeai/app/services/style_preset_images/style_preset_images_default.py index 5f907c78ac..3efcdaf610 100644 --- a/invokeai/app/services/style_preset_images/style_preset_images_default.py +++ b/invokeai/app/services/style_preset_images/style_preset_images_default.py @@ -72,6 +72,8 @@ class StylePresetImageFileStorageDisk(StylePresetImageFileStorageBase): send2trash(path) + except StylePresetImageFileNotFoundException as e: + raise StylePresetImageFileNotFoundException from e except Exception as e: raise StylePresetImageFileDeleteException from e diff --git a/invokeai/frontend/web/src/features/stylePresets/components/ActiveStylePreset.tsx b/invokeai/frontend/web/src/features/stylePresets/components/ActiveStylePreset.tsx index e6a81d256f..3ad7aa2f44 100644 --- a/invokeai/frontend/web/src/features/stylePresets/components/ActiveStylePreset.tsx +++ b/invokeai/frontend/web/src/features/stylePresets/components/ActiveStylePreset.tsx @@ -1,12 +1,11 @@ -import { Flex, IconButton, Text } from '@invoke-ai/ui-library'; +import { Flex, IconButton, Text, Box, ButtonGroup } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { negativePromptChanged, positivePromptChanged } from 'features/controlLayers/store/controlLayersSlice'; import { usePresetModifiedPrompts } from 'features/stylePresets/hooks/usePresetModifiedPrompts'; import { activeStylePresetChanged } from 'features/stylePresets/store/stylePresetSlice'; import type { MouseEventHandler } from 'react'; import { useCallback } from 'react'; -import { CgPushDown } from 'react-icons/cg'; -import { PiXBold } from 'react-icons/pi'; +import { PiStackSimpleBold, PiXBold } from 'react-icons/pi'; import StylePresetImage from './StylePresetImage'; export const ActiveStylePreset = () => { @@ -34,18 +33,21 @@ export const ActiveStylePreset = () => { ); if (!activeStylePreset) { - return <>Choose Preset; + return ( + + + Choose Preset + + + ); } return ( <> - - + + - - Prompt Style - - + {activeStylePreset.name} @@ -53,15 +55,15 @@ export const ActiveStylePreset = () => { } + icon={} /> } /> diff --git a/invokeai/frontend/web/src/features/stylePresets/components/StylePresetImage.tsx b/invokeai/frontend/web/src/features/stylePresets/components/StylePresetImage.tsx index 057967485d..1f71a767c1 100644 --- a/invokeai/frontend/web/src/features/stylePresets/components/StylePresetImage.tsx +++ b/invokeai/frontend/web/src/features/stylePresets/components/StylePresetImage.tsx @@ -5,29 +5,29 @@ import { PiImage } from 'react-icons/pi'; const IMAGE_THUMBNAIL_SIZE = '40px'; const FALLBACK_ICON_SIZE = '24px'; -const StylePresetImage = ({ presetImageUrl }: { presetImageUrl: string | null }) => { +const StylePresetImage = ({ presetImageUrl, imageWidth }: { presetImageUrl: string | null; imageWidth?: number }) => { return ( - + } objectFit="cover" objectPosition="50% 50%" - height={IMAGE_THUMBNAIL_SIZE} - width={IMAGE_THUMBNAIL_SIZE} - minHeight={IMAGE_THUMBNAIL_SIZE} - minWidth={IMAGE_THUMBNAIL_SIZE} + height={imageWidth || IMAGE_THUMBNAIL_SIZE} + width={imageWidth || IMAGE_THUMBNAIL_SIZE} + minHeight={imageWidth || IMAGE_THUMBNAIL_SIZE} + minWidth={imageWidth || IMAGE_THUMBNAIL_SIZE} borderRadius="base" /> ); diff --git a/invokeai/frontend/web/src/features/stylePresets/components/StylePresetListItem.tsx b/invokeai/frontend/web/src/features/stylePresets/components/StylePresetListItem.tsx index ba4a479ced..a8306ff68f 100644 --- a/invokeai/frontend/web/src/features/stylePresets/components/StylePresetListItem.tsx +++ b/invokeai/frontend/web/src/features/stylePresets/components/StylePresetListItem.tsx @@ -1,4 +1,4 @@ -import { Badge, Flex, IconButton, Text } from '@invoke-ai/ui-library'; +import { Badge, ConfirmationAlertDialog, Flex, IconButton, Text, useDisclosure } from '@invoke-ai/ui-library'; import type { MouseEvent } from 'react'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import ModelImage from 'features/modelManagerV2/subpanels/ModelManagerPanel/ModelImage'; @@ -14,6 +14,7 @@ export const StylePresetListItem = ({ preset }: { preset: StylePresetRecordWithI const dispatch = useAppDispatch(); const [deleteStylePreset] = useDeleteStylePresetMutation(); const activeStylePreset = useAppSelector((s) => s.stylePreset.activeStylePreset); + const { isOpen, onOpen, onClose } = useDisclosure(); const handleClickEdit = useCallback( (e: MouseEvent) => { @@ -29,72 +30,94 @@ export const StylePresetListItem = ({ preset }: { preset: StylePresetRecordWithI dispatch(isMenuOpenChanged(false)); }, [dispatch, preset]); - const handleDeletePreset = useCallback( - async (e: MouseEvent) => { + const handleClickDelete = useCallback( + (e: MouseEvent) => { e.stopPropagation(); - try { - await deleteStylePreset(preset.id); - } catch (error) {} + onOpen(); }, - [preset] + [dispatch, preset] ); + const handleDeletePreset = useCallback(async () => { + try { + await deleteStylePreset(preset.id); + } catch (error) {} + }, [preset]); + return ( - - - - - - {preset.name} - {activeStylePreset && activeStylePreset.id === preset.id && ( - - Active - - )} + <> + + + + + + {preset.name} + {activeStylePreset && activeStylePreset.id === preset.id && ( + + Active + + )} + + + + } + /> + } + /> + - - } /> - } - /> + + + + Positive prompt: + {' '} + {preset.preset_data.positive_prompt} + + + + Negative prompt: + {' '} + {preset.preset_data.negative_prompt} + - - - - - Positive prompt: - {' '} - {preset.preset_data.positive_prompt} - - - - Negative prompt: - {' '} - {preset.preset_data.negative_prompt} - - - + +

{'Delete Preset?'}

+
+
+ ); }; diff --git a/invokeai/frontend/web/src/features/stylePresets/components/StylePresetMenuTrigger.tsx b/invokeai/frontend/web/src/features/stylePresets/components/StylePresetMenuTrigger.tsx index fe442e2888..4ed1321e81 100644 --- a/invokeai/frontend/web/src/features/stylePresets/components/StylePresetMenuTrigger.tsx +++ b/invokeai/frontend/web/src/features/stylePresets/components/StylePresetMenuTrigger.tsx @@ -16,16 +16,18 @@ export const StylePresetMenuTrigger = () => { return ( - + ); }; diff --git a/invokeai/frontend/web/src/features/stylePresets/hooks/useStylePresetFields.ts b/invokeai/frontend/web/src/features/stylePresets/hooks/useStylePresetFields.ts index 9262893ded..ff9e114d5d 100644 --- a/invokeai/frontend/web/src/features/stylePresets/hooks/useStylePresetFields.ts +++ b/invokeai/frontend/web/src/features/stylePresets/hooks/useStylePresetFields.ts @@ -24,8 +24,8 @@ export const useStylePresetFields = (preset: StylePresetRecordWithImage | null) return { name: preset.name, - positivePrompt: preset.preset_data.positive_prompt, - negativePrompt: preset.preset_data.negative_prompt, + positivePrompt: preset.preset_data.positive_prompt || "", + negativePrompt: preset.preset_data.negative_prompt || "", image: file }; } diff --git a/invokeai/frontend/web/src/features/ui/components/ParametersPanels/ParametersPanelTextToImage.tsx b/invokeai/frontend/web/src/features/ui/components/ParametersPanels/ParametersPanelTextToImage.tsx index ec669b05ca..21de3fb998 100644 --- a/invokeai/frontend/web/src/features/ui/components/ParametersPanels/ParametersPanelTextToImage.tsx +++ b/invokeai/frontend/web/src/features/ui/components/ParametersPanels/ParametersPanelTextToImage.tsx @@ -1,5 +1,5 @@ import type { ChakraProps } from '@invoke-ai/ui-library'; -import { Box, Flex, Portal,Tab, TabList, TabPanel, TabPanels, Tabs } from '@invoke-ai/ui-library'; +import { Box, Flex, Portal, Tab, TabList, TabPanel, TabPanels, Tabs } from '@invoke-ai/ui-library'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { overlayScrollbarsParams } from 'common/components/OverlayScrollbars/constants'; import { ControlLayersPanelContent } from 'features/controlLayers/components/ControlLayersPanelContent'; @@ -71,63 +71,64 @@ const ParametersPanelTextToImage = () => { {isMenuOpen && ( - + - + )} - - - - - - - {t('common.settingsLabel')} - - - {controlLayersTitle} - - - - - - - - {activeTabName !== 'generation' && } - {activeTabName === 'canvas' && } - {isSDXL && } - - - - - - - - - - + {!isMenuOpen && ( + + + + + + + {t('common.settingsLabel')} + + + {controlLayersTitle} + + + + + + + + {activeTabName !== 'generation' && } + {activeTabName === 'canvas' && } + {isSDXL && } + + + + + + + + + + + )}