From ce55a96125198f95478a2aecce9921f52a99aa37 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Wed, 28 Aug 2024 16:37:50 +1000 Subject: [PATCH] feat(ui): fix queue item count badge positioning Previously this badge, floating over the queue menu button next to the invoke button, was rendered within the existing layout. When I initially positioned it, the app layout interfered - it would extend into an area reserved for a flex gap, which cut off the badge. As a (bad) workaround, I had shifted the whole app down a few pixels to make room for it. What I should have done is what I've done in this commit - render the badge in a portal to take it out of the layout so we don't need that extra vertical padding. Sleekified some styling a bit too. --- .../components/ControlLayersEditor.tsx | 2 -- .../components/StageComponent.tsx | 6 ++-- .../components/GalleryPanelContent.tsx | 2 +- .../components/ImageViewer/ImageViewer.tsx | 3 +- .../components/QueueActionsMenuButton.tsx | 31 +++++++++++++++---- .../queue/components/QueueControls.tsx | 2 +- .../features/ui/components/VerticalNavBar.tsx | 2 +- 7 files changed, 31 insertions(+), 17 deletions(-) diff --git a/invokeai/frontend/web/src/features/controlLayers/components/ControlLayersEditor.tsx b/invokeai/frontend/web/src/features/controlLayers/components/ControlLayersEditor.tsx index 494a5a4ba0..02aa1c973e 100644 --- a/invokeai/frontend/web/src/features/controlLayers/components/ControlLayersEditor.tsx +++ b/invokeai/frontend/web/src/features/controlLayers/components/ControlLayersEditor.tsx @@ -19,8 +19,6 @@ export const CanvasEditor = memo(() => { { ); return ( - + {!dynamicGrid && ( { left={0} ref={containerRef} borderRadius="base" - border={1} - borderStyle="solid" - borderColor="base.700" overflow="hidden" data-testid="control-layers-canvas" /> diff --git a/invokeai/frontend/web/src/features/gallery/components/GalleryPanelContent.tsx b/invokeai/frontend/web/src/features/gallery/components/GalleryPanelContent.tsx index 962ae6cf9a..2406be7a08 100644 --- a/invokeai/frontend/web/src/features/gallery/components/GalleryPanelContent.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/GalleryPanelContent.tsx @@ -59,7 +59,7 @@ const GalleryPanelContent = () => { }, [boardSearchText.length, boardSearchDisclosure, boardsListPanel, dispatch]); return ( - + 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 46c7bcfbda..431af16e23 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewer.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewer.tsx @@ -21,7 +21,7 @@ export const ImageViewer = memo(() => { { right={0} bottom={0} left={0} - p={2} rowGap={4} alignItems="center" justifyContent="center" diff --git a/invokeai/frontend/web/src/features/queue/components/QueueActionsMenuButton.tsx b/invokeai/frontend/web/src/features/queue/components/QueueActionsMenuButton.tsx index 99456b042f..ce96322606 100644 --- a/invokeai/frontend/web/src/features/queue/components/QueueActionsMenuButton.tsx +++ b/invokeai/frontend/web/src/features/queue/components/QueueActionsMenuButton.tsx @@ -7,16 +7,18 @@ import { MenuDivider, MenuItem, MenuList, + Portal, useDisclosure, } from '@invoke-ai/ui-library'; import { useAppDispatch } from 'app/store/storeHooks'; +import type { Coordinate } from 'features/controlLayers/store/types'; import { useClearQueueConfirmationAlertDialog } from 'features/queue/components/ClearQueueConfirmationAlertDialog'; import { useClearQueue } from 'features/queue/hooks/useClearQueue'; import { usePauseProcessor } from 'features/queue/hooks/usePauseProcessor'; import { useResumeProcessor } from 'features/queue/hooks/useResumeProcessor'; import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus'; import { setActiveTab } from 'features/ui/store/uiSlice'; -import { memo, useCallback } from 'react'; +import { memo, useCallback, useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { PiPauseFill, PiPlayFill, PiTrashSimpleBold } from 'react-icons/pi'; import { RiListCheck, RiPlayList2Fill } from 'react-icons/ri'; @@ -26,6 +28,8 @@ export const QueueActionsMenuButton = memo(() => { const { isOpen, onOpen, onClose } = useDisclosure(); const dispatch = useAppDispatch(); const { t } = useTranslation(); + const [badgePos, setBadgePos] = useState(null); + const menuButtonRef = useRef(null); const dialogState = useClearQueueConfirmationAlertDialog(); const isPauseEnabled = useFeatureStatus('pauseQueue'); const isResumeEnabled = useFeatureStatus('resumeQueue'); @@ -49,10 +53,17 @@ export const QueueActionsMenuButton = memo(() => { dispatch(setActiveTab('queue')); }, [dispatch]); + useEffect(() => { + if (menuButtonRef.current) { + const { x, y } = menuButtonRef.current.getBoundingClientRect(); + setBadgePos({ x: x - 10, y: y - 10 }); + } + }, []); + return ( - } /> + } /> { - {queueSize > 0 && ( - - {queueSize} - + {queueSize > 0 && badgePos !== null && ( + + + {queueSize} + + )} ); diff --git a/invokeai/frontend/web/src/features/queue/components/QueueControls.tsx b/invokeai/frontend/web/src/features/queue/components/QueueControls.tsx index 570708642d..1acbd6b697 100644 --- a/invokeai/frontend/web/src/features/queue/components/QueueControls.tsx +++ b/invokeai/frontend/web/src/features/queue/components/QueueControls.tsx @@ -11,7 +11,7 @@ import { QueueActionsMenuButton } from './QueueActionsMenuButton'; const QueueControls = () => { const isPrependEnabled = useFeatureStatus('prependQueue'); return ( - + {isPrependEnabled && } diff --git a/invokeai/frontend/web/src/features/ui/components/VerticalNavBar.tsx b/invokeai/frontend/web/src/features/ui/components/VerticalNavBar.tsx index 402ba6aa26..28168b563e 100644 --- a/invokeai/frontend/web/src/features/ui/components/VerticalNavBar.tsx +++ b/invokeai/frontend/web/src/features/ui/components/VerticalNavBar.tsx @@ -18,7 +18,7 @@ export const VerticalNavBar = memo(() => { const customNavComponent = useStore($customNavComponent); return ( - +