mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
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.
This commit is contained in:
parent
64e60a7fde
commit
ce55a96125
@ -19,8 +19,6 @@ export const CanvasEditor = memo(() => {
|
||||
<Flex
|
||||
tabIndex={-1}
|
||||
ref={ref}
|
||||
layerStyle="first"
|
||||
p={2}
|
||||
borderRadius="base"
|
||||
position="relative"
|
||||
flexDirection="column"
|
||||
|
@ -82,10 +82,11 @@ export const StageComponent = memo(({ asPreview = false }: Props) => {
|
||||
);
|
||||
|
||||
return (
|
||||
<Flex position="relative" w="full" h="full" bg={dynamicGrid ? 'base.850' : 'base.900'}>
|
||||
<Flex position="relative" w="full" h="full" bg={dynamicGrid ? 'base.850' : 'base.900'} borderRadius="base">
|
||||
{!dynamicGrid && (
|
||||
<Flex
|
||||
position="absolute"
|
||||
borderRadius="base"
|
||||
bgImage={TRANSPARENCY_CHECKER_PATTERN}
|
||||
top={0}
|
||||
right={0}
|
||||
@ -102,9 +103,6 @@ export const StageComponent = memo(({ asPreview = false }: Props) => {
|
||||
left={0}
|
||||
ref={containerRef}
|
||||
borderRadius="base"
|
||||
border={1}
|
||||
borderStyle="solid"
|
||||
borderColor="base.700"
|
||||
overflow="hidden"
|
||||
data-testid="control-layers-canvas"
|
||||
/>
|
||||
|
@ -59,7 +59,7 @@ const GalleryPanelContent = () => {
|
||||
}, [boardSearchText.length, boardSearchDisclosure, boardsListPanel, dispatch]);
|
||||
|
||||
return (
|
||||
<Flex ref={ref} position="relative" flexDirection="column" h="full" w="full" pt={2} tabIndex={-1}>
|
||||
<Flex ref={ref} position="relative" flexDirection="column" h="full" w="full" tabIndex={-1}>
|
||||
<Flex alignItems="center" gap={0}>
|
||||
<GalleryHeader />
|
||||
<Flex alignItems="center" justifyContent="space-between" w="full">
|
||||
|
@ -21,7 +21,7 @@ export const ImageViewer = memo(() => {
|
||||
<Flex
|
||||
ref={ref}
|
||||
tabIndex={-1}
|
||||
layerStyle="first"
|
||||
layerStyle="body"
|
||||
borderRadius="base"
|
||||
position="absolute"
|
||||
flexDirection="column"
|
||||
@ -29,7 +29,6 @@ export const ImageViewer = memo(() => {
|
||||
right={0}
|
||||
bottom={0}
|
||||
left={0}
|
||||
p={2}
|
||||
rowGap={4}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
|
@ -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<Coordinate | null>(null);
|
||||
const menuButtonRef = useRef<HTMLButtonElement>(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 (
|
||||
<Box pos="relative">
|
||||
<Menu isOpen={isOpen} onOpen={onOpen} onClose={onClose} placement="bottom-end">
|
||||
<MenuButton as={IconButton} aria-label="Queue Actions Menu" icon={<RiListCheck />} />
|
||||
<MenuButton ref={menuButtonRef} as={IconButton} aria-label="Queue Actions Menu" icon={<RiListCheck />} />
|
||||
<MenuList>
|
||||
<MenuItem
|
||||
isDestructive
|
||||
@ -89,10 +100,18 @@ export const QueueActionsMenuButton = memo(() => {
|
||||
</MenuItem>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
{queueSize > 0 && (
|
||||
<Badge pos="absolute" insetInlineStart={-3} insetBlockStart={-1.5} colorScheme="invokeYellow" zIndex="docked">
|
||||
{queueSize > 0 && badgePos !== null && (
|
||||
<Portal>
|
||||
<Badge
|
||||
pos="absolute"
|
||||
insetInlineStart={badgePos.x}
|
||||
insetBlockStart={badgePos.y}
|
||||
colorScheme="invokeYellow"
|
||||
zIndex="docked"
|
||||
>
|
||||
{queueSize}
|
||||
</Badge>
|
||||
</Portal>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
|
@ -11,7 +11,7 @@ import { QueueActionsMenuButton } from './QueueActionsMenuButton';
|
||||
const QueueControls = () => {
|
||||
const isPrependEnabled = useFeatureStatus('prependQueue');
|
||||
return (
|
||||
<Flex w="full" position="relative" borderRadius="base" gap={2} pt={2} flexDir="column">
|
||||
<Flex w="full" position="relative" borderRadius="base" gap={2} flexDir="column">
|
||||
<ButtonGroup size="lg" isAttached={false}>
|
||||
{isPrependEnabled && <QueueFrontButton />}
|
||||
<InvokeQueueBackButton />
|
||||
|
@ -18,7 +18,7 @@ export const VerticalNavBar = memo(() => {
|
||||
const customNavComponent = useStore($customNavComponent);
|
||||
|
||||
return (
|
||||
<Flex flexDir="column" alignItems="center" pt={4} pb={2} gap={4}>
|
||||
<Flex flexDir="column" alignItems="center" py={2} gap={4}>
|
||||
<InvokeAILogoComponent />
|
||||
<Flex gap={4} pt={6} h="full" flexDir="column">
|
||||
<TabMountGate tab="generation">
|
||||
|
Loading…
Reference in New Issue
Block a user