diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index 4b102d6cf3..048b1b4fd9 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -370,6 +370,7 @@ "deleteImage_other": "Delete {{count}} Images", "deleteImageBin": "Deleted images will be sent to your operating system's Bin.", "deleteImagePermanent": "Deleted images cannot be restored.", + "displaySearch": "Display Search", "download": "Download", "featuresWillReset": "If you delete this image, those features will immediately be reset.", "galleryImageSize": "Image Size", diff --git a/invokeai/frontend/web/src/features/gallery/components/GalleryBoardName.tsx b/invokeai/frontend/web/src/features/gallery/components/GalleryBoardName.tsx index 233aa8a8c1..367bd47008 100644 --- a/invokeai/frontend/web/src/features/gallery/components/GalleryBoardName.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/GalleryBoardName.tsx @@ -1,17 +1,51 @@ -import { Flex, Text } from '@invoke-ai/ui-library'; +import { Button, Flex, Icon, Spacer } from '@invoke-ai/ui-library'; import { useAppSelector } from 'app/store/storeHooks'; -import { memo } from 'react'; +import { memo, useMemo } from 'react'; +import { PiCaretUpBold } from 'react-icons/pi'; import { useBoardName } from 'services/api/hooks/useBoardName'; -const GalleryBoardName = () => { +type Props = { + isOpen: boolean; + onToggle: () => void; +}; + +const GalleryBoardName = (props: Props) => { + const { isOpen, onToggle } = props; const selectedBoardId = useAppSelector((s) => s.gallery.selectedBoardId); const boardName = useBoardName(selectedBoardId); + const formattedBoardName = useMemo(() => { + if (boardName.length > 20) { + return `${boardName.substring(0, 20)}...`; + } + return boardName; + }, [boardName]); + return ( - - - {boardName} - + + + {formattedBoardName} + + ); }; diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx index 665d96a006..eaefe9cd80 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageGalleryContent.tsx @@ -1,24 +1,47 @@ -import { Button, ButtonGroup, Flex, Tab, TabList, Tabs } from '@invoke-ai/ui-library'; +import type { ChakraProps } from '@invoke-ai/ui-library'; +import { Box, Collapse, Flex, IconButton, Tab, TabList, Tabs, useDisclosure } from '@invoke-ai/ui-library'; import { useStore } from '@nanostores/react'; import { $galleryHeader } from 'app/store/nanostores/galleryHeader'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import { galleryViewChanged } from 'features/gallery/store/gallerySlice'; import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { PiImagesBold } from 'react-icons/pi'; -import { RiServerLine } from 'react-icons/ri'; +import { PiImagesBold, PiMagnifyingGlassBold } from 'react-icons/pi'; import BoardsList from './Boards/BoardsList/BoardsList'; import GalleryBoardName from './GalleryBoardName'; import GalleryImageGrid from './ImageGrid/GalleryImageGrid'; import { GalleryPagination } from './ImageGrid/GalleryPagination'; import { GallerySearch } from './ImageGrid/GallerySearch'; +import GallerySettingsPopover from './GallerySettingsPopover/GallerySettingsPopover'; + +const baseStyles: ChakraProps['sx'] = { + fontWeight: 'semibold', + fontSize: 'md', + color: 'base.300', + borderBottom: '1px solid', + borderBottomColor: 'invokeBlue.800', +}; + +const selectedStyles: ChakraProps['sx'] = { + borderColor: 'invokeBlue.800', + borderBottomColor: 'base.850', + color: 'invokeBlue.300', +}; + +const searchIconStyles: ChakraProps['sx'] = { + borderBottom: '1px solid', + borderBottomColor: 'invokeBlue.800', + maxW: '16', +}; const ImageGalleryContent = () => { const { t } = useTranslation(); const galleryView = useAppSelector((s) => s.gallery.galleryView); const dispatch = useAppDispatch(); const galleryHeader = useStore($galleryHeader); + const searchDisclosure = useDisclosure({ defaultIsOpen: false }); + const { isOpen: isBoardListOpen, onToggle: onToggleBoardList } = useDisclosure({ defaultIsOpen: true }); const handleClickImages = useCallback(() => { dispatch(galleryViewChanged('images')); @@ -29,51 +52,48 @@ const ImageGalleryContent = () => { }, [dispatch]); return ( - + {galleryHeader} - - - - - - } - data-testid="images-tab" - > + + + + + + + + + + {t('parameters.images')} - - } - data-testid="assets-tab" - > + + + + + {t('gallery.assets')} - - + + + + } + fontSize={16} + textAlign="center" + color="base.400" + variant="unstyled" + minW="unset" + /> + - - + + + + +