mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): restore floating options and gallery buttons
This commit is contained in:
parent
8db14911d7
commit
2d922a0a65
@ -1,27 +1,23 @@
|
|||||||
import type { ChakraProps } from '@chakra-ui/react';
|
import type { ChakraProps } from '@chakra-ui/react';
|
||||||
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
import { useCancelCurrentQueueItem } from 'features/queue/hooks/useCancelCurrentQueueItem';
|
import { useCancelCurrentQueueItem } from 'features/queue/hooks/useCancelCurrentQueueItem';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaTimes } from 'react-icons/fa';
|
import { FaTimes } from 'react-icons/fa';
|
||||||
|
|
||||||
import QueueButton from './common/QueueButton';
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
asIconButton?: boolean;
|
|
||||||
sx?: ChakraProps['sx'];
|
sx?: ChakraProps['sx'];
|
||||||
};
|
};
|
||||||
|
|
||||||
const CancelCurrentQueueItemButton = ({ asIconButton, sx }: Props) => {
|
const CancelCurrentQueueItemIconButton = ({ sx }: Props) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { cancelQueueItem, isLoading, isDisabled } =
|
const { cancelQueueItem, isLoading, isDisabled } =
|
||||||
useCancelCurrentQueueItem();
|
useCancelCurrentQueueItem();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<QueueButton
|
<InvIconButton
|
||||||
isDisabled={isDisabled}
|
isDisabled={isDisabled}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
asIconButton={asIconButton}
|
aria-label={t('queue.cancel')}
|
||||||
label={t('queue.cancel')}
|
|
||||||
tooltip={t('queue.cancelTooltip')}
|
tooltip={t('queue.cancelTooltip')}
|
||||||
icon={<FaTimes />}
|
icon={<FaTimes />}
|
||||||
onClick={cancelQueueItem}
|
onClick={cancelQueueItem}
|
||||||
@ -31,4 +27,4 @@ const CancelCurrentQueueItemButton = ({ asIconButton, sx }: Props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(CancelCurrentQueueItemButton);
|
export default memo(CancelCurrentQueueItemIconButton);
|
@ -1,47 +1,34 @@
|
|||||||
import { type ChakraProps, useDisclosure } from '@chakra-ui/react';
|
import { useDisclosure } from '@chakra-ui/react';
|
||||||
import { InvConfirmationAlertDialog } from 'common/components/InvConfirmationAlertDialog/InvConfirmationAlertDialog';
|
import { InvButton } from 'common/components/InvButton/InvButton';
|
||||||
import { InvText } from 'common/components/InvText/wrapper';
|
import type { InvButtonProps } from 'common/components/InvButton/types';
|
||||||
|
import ClearQueueConfirmationAlertDialog from 'features/queue/components/ClearQueueConfirmationAlertDialog';
|
||||||
import { useClearQueue } from 'features/queue/hooks/useClearQueue';
|
import { useClearQueue } from 'features/queue/hooks/useClearQueue';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaTrash } from 'react-icons/fa';
|
import { FaTrash } from 'react-icons/fa';
|
||||||
|
|
||||||
import QueueButton from './common/QueueButton';
|
type Props = InvButtonProps;
|
||||||
|
|
||||||
type Props = {
|
const ClearQueueButton = (props: Props) => {
|
||||||
asIconButton?: boolean;
|
|
||||||
sx?: ChakraProps['sx'];
|
|
||||||
};
|
|
||||||
|
|
||||||
const ClearQueueButton = ({ asIconButton, sx }: Props) => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { isOpen, onClose, onOpen } = useDisclosure();
|
const disclosure = useDisclosure();
|
||||||
const { clearQueue, isLoading, isDisabled } = useClearQueue();
|
const { isLoading, isDisabled } = useClearQueue();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<QueueButton
|
<InvButton
|
||||||
isDisabled={isDisabled}
|
isDisabled={isDisabled}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
asIconButton={asIconButton}
|
|
||||||
label={t('queue.clear')}
|
|
||||||
tooltip={t('queue.clearTooltip')}
|
tooltip={t('queue.clearTooltip')}
|
||||||
icon={<FaTrash />}
|
leftIcon={<FaTrash />}
|
||||||
colorScheme="error"
|
colorScheme="error"
|
||||||
sx={sx}
|
onClick={disclosure.onOpen}
|
||||||
onClick={onOpen}
|
data-testid={t('queue.clear')}
|
||||||
/>
|
{...props}
|
||||||
<InvConfirmationAlertDialog
|
|
||||||
isOpen={isOpen}
|
|
||||||
onClose={onClose}
|
|
||||||
title={t('queue.clearTooltip')}
|
|
||||||
acceptCallback={clearQueue}
|
|
||||||
acceptButtonText={t('queue.clear')}
|
|
||||||
>
|
>
|
||||||
<InvText>{t('queue.clearQueueAlertDialog')}</InvText>
|
{t('queue.clear')}
|
||||||
<br />
|
</InvButton>
|
||||||
<InvText>{t('queue.clearQueueAlertDialog2')}</InvText>
|
<ClearQueueConfirmationAlertDialog disclosure={disclosure} />
|
||||||
</InvConfirmationAlertDialog>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
import type {
|
||||||
|
UseDisclosureReturn} from '@chakra-ui/react';
|
||||||
|
import { InvConfirmationAlertDialog } from 'common/components/InvConfirmationAlertDialog/InvConfirmationAlertDialog';
|
||||||
|
import { InvText } from 'common/components/InvText/wrapper';
|
||||||
|
import { useClearQueue } from 'features/queue/hooks/useClearQueue';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
disclosure: UseDisclosureReturn;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ClearQueueButton = ({ disclosure }: Props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { clearQueue } = useClearQueue();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<InvConfirmationAlertDialog
|
||||||
|
isOpen={disclosure.isOpen}
|
||||||
|
onClose={disclosure.onClose}
|
||||||
|
title={t('queue.clearTooltip')}
|
||||||
|
acceptCallback={clearQueue}
|
||||||
|
acceptButtonText={t('queue.clear')}
|
||||||
|
>
|
||||||
|
<InvText>{t('queue.clearQueueAlertDialog')}</InvText>
|
||||||
|
<br />
|
||||||
|
<InvText>{t('queue.clearQueueAlertDialog2')}</InvText>
|
||||||
|
</InvConfirmationAlertDialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(ClearQueueButton);
|
@ -0,0 +1,35 @@
|
|||||||
|
import { useDisclosure } from '@chakra-ui/react';
|
||||||
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
|
import type { InvIconButtonProps } from 'common/components/InvIconButton/types';
|
||||||
|
import ClearQueueConfirmationAlertDialog from 'features/queue/components/ClearQueueConfirmationAlertDialog';
|
||||||
|
import { useClearQueue } from 'features/queue/hooks/useClearQueue';
|
||||||
|
import { memo } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { FaTrash } from 'react-icons/fa';
|
||||||
|
|
||||||
|
type Props = Omit<InvIconButtonProps, 'aria-label'>;
|
||||||
|
|
||||||
|
const ClearQueueIconButton = (props: Props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const disclosure = useDisclosure();
|
||||||
|
const { isLoading, isDisabled } = useClearQueue();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<InvIconButton
|
||||||
|
isDisabled={isDisabled}
|
||||||
|
isLoading={isLoading}
|
||||||
|
aria-label={t('queue.clear')}
|
||||||
|
tooltip={t('queue.clearTooltip')}
|
||||||
|
icon={<FaTrash />}
|
||||||
|
colorScheme="error"
|
||||||
|
onClick={disclosure.onOpen}
|
||||||
|
data-testid={t('queue.clear')}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
<ClearQueueConfirmationAlertDialog disclosure={disclosure} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(ClearQueueIconButton);
|
@ -1,6 +1,6 @@
|
|||||||
import { Flex, Spacer } from '@chakra-ui/react';
|
import { Flex, Spacer } from '@chakra-ui/react';
|
||||||
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
||||||
import ClearQueueButton from 'features/queue/components/ClearQueueButton';
|
import ClearQueueIconButton from 'features/queue/components/ClearQueueIconButton';
|
||||||
import QueueFrontButton from 'features/queue/components/QueueFrontButton';
|
import QueueFrontButton from 'features/queue/components/QueueFrontButton';
|
||||||
import ProgressBar from 'features/system/components/ProgressBar';
|
import ProgressBar from 'features/system/components/ProgressBar';
|
||||||
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
import { useFeatureStatus } from 'features/system/hooks/useFeatureStatus';
|
||||||
@ -28,7 +28,7 @@ const QueueControls = () => {
|
|||||||
{/* <CancelCurrentQueueItemButton asIconButton />
|
{/* <CancelCurrentQueueItemButton asIconButton />
|
||||||
{isResumeEnabled && <ResumeProcessorButton asIconButton />}
|
{isResumeEnabled && <ResumeProcessorButton asIconButton />}
|
||||||
{isPauseEnabled && <PauseProcessorButton asIconButton />} */}
|
{isPauseEnabled && <PauseProcessorButton asIconButton />} */}
|
||||||
<ClearQueueButton asIconButton />
|
<ClearQueueIconButton />
|
||||||
</InvButtonGroup>
|
</InvButtonGroup>
|
||||||
<ProgressBar />
|
<ProgressBar />
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -1,22 +1,20 @@
|
|||||||
import { Flex } from '@chakra-ui/layout';
|
import { Flex } from '@chakra-ui/layout';
|
||||||
import { Portal } from '@chakra-ui/portal';
|
import { Portal } from '@chakra-ui/portal';
|
||||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
|
import { InvTooltip } from 'common/components/InvTooltip/InvTooltip';
|
||||||
|
import type { UsePanelReturn } from 'features/ui/hooks/usePanel';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { MdPhotoLibrary } from 'react-icons/md';
|
import { MdPhotoLibrary } from 'react-icons/md';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isGalleryCollapsed: boolean;
|
panelApi: UsePanelReturn;
|
||||||
expandGallery: () => void;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const FloatingGalleryButton = ({
|
const FloatingGalleryButton = (props: Props) => {
|
||||||
isGalleryCollapsed,
|
|
||||||
expandGallery,
|
|
||||||
}: Props) => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
if (!isGalleryCollapsed) {
|
if (!props.panelApi.isCollapsed) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,18 +25,21 @@ const FloatingGalleryButton = ({
|
|||||||
transform="translate(0, -50%)"
|
transform="translate(0, -50%)"
|
||||||
minW={8}
|
minW={8}
|
||||||
top="50%"
|
top="50%"
|
||||||
insetInlineEnd="1.63rem"
|
insetInlineEnd={0}
|
||||||
>
|
>
|
||||||
<InvIconButton
|
<InvTooltip
|
||||||
tooltip="Show Gallery (G)"
|
label={t('accessibility.showGalleryPanel')}
|
||||||
aria-label={t('accessibility.showGalleryPanel')}
|
placement="start"
|
||||||
onClick={expandGallery}
|
>
|
||||||
icon={<MdPhotoLibrary />}
|
<InvIconButton
|
||||||
p={0}
|
aria-label={t('accessibility.showGalleryPanel')}
|
||||||
px={3}
|
onClick={props.panelApi.expand}
|
||||||
h={48}
|
icon={<MdPhotoLibrary />}
|
||||||
borderEndRadius={0}
|
p={0}
|
||||||
/>
|
h={48}
|
||||||
|
borderEndRadius={0}
|
||||||
|
/>
|
||||||
|
</InvTooltip>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Portal>
|
</Portal>
|
||||||
);
|
);
|
||||||
|
@ -1,40 +1,45 @@
|
|||||||
import type { ChakraProps } from '@chakra-ui/react';
|
import { SpinnerIcon } from '@chakra-ui/icons';
|
||||||
|
import type { SystemStyleObject } from '@chakra-ui/react';
|
||||||
import { Flex, Portal } from '@chakra-ui/react';
|
import { Flex, Portal } from '@chakra-ui/react';
|
||||||
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
import { InvButtonGroup } from 'common/components/InvButtonGroup/InvButtonGroup';
|
||||||
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
import { InvIconButton } from 'common/components/InvIconButton/InvIconButton';
|
||||||
import CancelCurrentQueueItemButton from 'features/queue/components/CancelCurrentQueueItemButton';
|
import CancelCurrentQueueItemIconButton from 'features/queue/components/CancelCurrentQueueItemIconButton';
|
||||||
import ClearQueueButton from 'features/queue/components/ClearQueueButton';
|
import ClearQueueIconButton from 'features/queue/components/ClearQueueIconButton';
|
||||||
import { QueueButtonTooltip } from 'features/queue/components/QueueButtonTooltip';
|
import { QueueButtonTooltip } from 'features/queue/components/QueueButtonTooltip';
|
||||||
import { useQueueBack } from 'features/queue/hooks/useQueueBack';
|
import { useQueueBack } from 'features/queue/hooks/useQueueBack';
|
||||||
import type { RefObject } from 'react';
|
import type { UsePanelReturn } from 'features/ui/hooks/usePanel';
|
||||||
import { memo, useCallback } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaSlidersH } from 'react-icons/fa';
|
import { FaSlidersH } from 'react-icons/fa';
|
||||||
import { IoSparkles } from 'react-icons/io5';
|
import { IoSparkles } from 'react-icons/io5';
|
||||||
import type { ImperativePanelHandle } from 'react-resizable-panels';
|
import { useGetQueueStatusQuery } from 'services/api/endpoints/queue';
|
||||||
|
import { spinAnimationSlow } from 'theme/animations';
|
||||||
|
|
||||||
const floatingButtonStyles: ChakraProps['sx'] = {
|
const floatingButtonStyles: SystemStyleObject = {
|
||||||
borderStartRadius: 0,
|
borderStartRadius: 0,
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isSidePanelCollapsed: boolean;
|
panelApi: UsePanelReturn;
|
||||||
sidePanelRef: RefObject<ImperativePanelHandle>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const FloatingSidePanelButtons = ({
|
const FloatingSidePanelButtons = (props: Props) => {
|
||||||
isSidePanelCollapsed,
|
|
||||||
sidePanelRef,
|
|
||||||
}: Props) => {
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { queueBack, isLoading, isDisabled } = useQueueBack();
|
const { queueBack, isLoading, isDisabled } = useQueueBack();
|
||||||
|
const { data: queueStatus } = useGetQueueStatusQuery();
|
||||||
|
|
||||||
const handleShowSidePanel = useCallback(() => {
|
const queueButtonIcon = useMemo(
|
||||||
sidePanelRef.current?.expand();
|
() =>
|
||||||
}, [sidePanelRef]);
|
queueStatus?.processor.is_processing ? (
|
||||||
|
<SpinnerIcon animation={spinAnimationSlow} />
|
||||||
|
) : (
|
||||||
|
<IoSparkles />
|
||||||
|
),
|
||||||
|
[queueStatus?.processor.is_processing]
|
||||||
|
);
|
||||||
|
|
||||||
if (!isSidePanelCollapsed) {
|
if (!props.panelApi.isCollapsed) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +50,7 @@ const FloatingSidePanelButtons = ({
|
|||||||
transform="translate(0, -50%)"
|
transform="translate(0, -50%)"
|
||||||
minW={8}
|
minW={8}
|
||||||
top="50%"
|
top="50%"
|
||||||
insetInlineStart="5.13rem"
|
insetInlineStart="54px"
|
||||||
direction="column"
|
direction="column"
|
||||||
gap={2}
|
gap={2}
|
||||||
h={48}
|
h={48}
|
||||||
@ -54,29 +59,23 @@ const FloatingSidePanelButtons = ({
|
|||||||
<InvIconButton
|
<InvIconButton
|
||||||
tooltip={t('parameters.showOptionsPanel')}
|
tooltip={t('parameters.showOptionsPanel')}
|
||||||
aria-label={t('parameters.showOptionsPanel')}
|
aria-label={t('parameters.showOptionsPanel')}
|
||||||
onClick={handleShowSidePanel}
|
onClick={props.panelApi.expand}
|
||||||
sx={floatingButtonStyles}
|
sx={floatingButtonStyles}
|
||||||
icon={<FaSlidersH />}
|
icon={<FaSlidersH />}
|
||||||
/>
|
/>
|
||||||
<InvIconButton
|
<InvIconButton
|
||||||
aria-label={t('queue.queueBack')}
|
aria-label={t('queue.queueBack')}
|
||||||
pos="absolute"
|
|
||||||
insetInlineStart={0}
|
|
||||||
onClick={queueBack}
|
onClick={queueBack}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
isDisabled={isDisabled}
|
isDisabled={isDisabled}
|
||||||
icon={<IoSparkles />}
|
icon={queueButtonIcon}
|
||||||
variant="solid"
|
colorScheme="invokeYellow"
|
||||||
colorScheme="yellow"
|
|
||||||
tooltip={<QueueButtonTooltip />}
|
tooltip={<QueueButtonTooltip />}
|
||||||
sx={floatingButtonStyles}
|
sx={floatingButtonStyles}
|
||||||
/>
|
/>
|
||||||
<CancelCurrentQueueItemButton
|
<CancelCurrentQueueItemIconButton sx={floatingButtonStyles} />
|
||||||
asIconButton
|
|
||||||
sx={floatingButtonStyles}
|
|
||||||
/>
|
|
||||||
</InvButtonGroup>
|
</InvButtonGroup>
|
||||||
<ClearQueueButton asIconButton sx={floatingButtonStyles} />
|
<ClearQueueIconButton sx={floatingButtonStyles} />
|
||||||
</Flex>
|
</Flex>
|
||||||
</Portal>
|
</Portal>
|
||||||
);
|
);
|
||||||
|
@ -16,6 +16,8 @@ import NodeEditorPanelGroup from 'features/nodes/components/sidePanel/NodeEditor
|
|||||||
import InvokeAILogoComponent from 'features/system/components/InvokeAILogoComponent';
|
import InvokeAILogoComponent from 'features/system/components/InvokeAILogoComponent';
|
||||||
import SettingsMenu from 'features/system/components/SettingsModal/SettingsMenu';
|
import SettingsMenu from 'features/system/components/SettingsModal/SettingsMenu';
|
||||||
import StatusIndicator from 'features/system/components/StatusIndicator';
|
import StatusIndicator from 'features/system/components/StatusIndicator';
|
||||||
|
import FloatingGalleryButton from 'features/ui/components/FloatingGalleryButton';
|
||||||
|
import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons';
|
||||||
import type { UsePanelOptions } from 'features/ui/hooks/usePanel';
|
import type { UsePanelOptions } from 'features/ui/hooks/usePanel';
|
||||||
import { usePanel } from 'features/ui/hooks/usePanel';
|
import { usePanel } from 'features/ui/hooks/usePanel';
|
||||||
import { usePanelStorage } from 'features/ui/hooks/usePanelStorage';
|
import { usePanelStorage } from 'features/ui/hooks/usePanelStorage';
|
||||||
@ -99,8 +101,8 @@ const enabledTabsSelector = createMemoizedSelector(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const NO_GALLERY_TABS: InvokeTabName[] = ['modelManager', 'queue'];
|
export const NO_GALLERY_PANEL_TABS: InvokeTabName[] = ['modelManager', 'queue'];
|
||||||
export const NO_SIDE_PANEL_TABS: InvokeTabName[] = ['modelManager', 'queue'];
|
export const NO_OPTIONS_PANEL_TABS: InvokeTabName[] = ['modelManager', 'queue'];
|
||||||
const panelStyles: CSSProperties = { height: '100%', width: '100%' };
|
const panelStyles: CSSProperties = { height: '100%', width: '100%' };
|
||||||
const GALLERY_MIN_SIZE_PX = 310;
|
const GALLERY_MIN_SIZE_PX = 310;
|
||||||
const GALLERY_MIN_SIZE_PCT = 20;
|
const GALLERY_MIN_SIZE_PCT = 20;
|
||||||
@ -121,6 +123,14 @@ const InvokeTabs = () => {
|
|||||||
e.target.blur();
|
e.target.blur();
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
const shouldShowOptionsPanel = useMemo(
|
||||||
|
() => !NO_OPTIONS_PANEL_TABS.includes(activeTabName),
|
||||||
|
[activeTabName]
|
||||||
|
);
|
||||||
|
const shouldShowGalleryPanel = useMemo(
|
||||||
|
() => !NO_GALLERY_PANEL_TABS.includes(activeTabName),
|
||||||
|
[activeTabName]
|
||||||
|
);
|
||||||
|
|
||||||
const tabs = useMemo(
|
const tabs = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@ -185,60 +195,38 @@ const InvokeTabs = () => {
|
|||||||
|
|
||||||
const panelStorage = usePanelStorage();
|
const panelStorage = usePanelStorage();
|
||||||
|
|
||||||
const {
|
const optionsPanel = usePanel(optionsPanelUsePanelOptions);
|
||||||
ref: optionsPanelRef,
|
|
||||||
minSize: optionsPanelMinSize,
|
|
||||||
isCollapsed: isOptionsPanelCollapsed,
|
|
||||||
onCollapse: onCollapseOptionsPanel,
|
|
||||||
onExpand: onExpandOptionsPanel,
|
|
||||||
reset: resetOptionsPanel,
|
|
||||||
expand: expandOptionsPanel,
|
|
||||||
collapse: collapseOptionsPanel,
|
|
||||||
toggle: toggleOptionsPanel,
|
|
||||||
onDoubleClickHandle: onDoubleClickOptionsPanelHandle,
|
|
||||||
} = usePanel(optionsPanelUsePanelOptions);
|
|
||||||
|
|
||||||
const {
|
const galleryPanel = usePanel(galleryPanelUsePanelOptions);
|
||||||
ref: galleryPanelRef,
|
|
||||||
minSize: galleryPanelMinSize,
|
|
||||||
isCollapsed: isGalleryPanelCollapsed,
|
|
||||||
onCollapse: onCollapseGalleryPanel,
|
|
||||||
onExpand: onExpandGalleryPanel,
|
|
||||||
reset: resetGalleryPanel,
|
|
||||||
expand: expandGalleryPanel,
|
|
||||||
collapse: collapseGalleryPanel,
|
|
||||||
toggle: toggleGalleryPanel,
|
|
||||||
onDoubleClickHandle: onDoubleClickGalleryPanelHandle,
|
|
||||||
} = usePanel(galleryPanelUsePanelOptions);
|
|
||||||
|
|
||||||
useHotkeys('g', toggleGalleryPanel, [toggleGalleryPanel]);
|
useHotkeys('g', galleryPanel.toggle, [galleryPanel.toggle]);
|
||||||
useHotkeys(['t', 'o'], toggleOptionsPanel, [toggleOptionsPanel]);
|
useHotkeys(['t', 'o'], optionsPanel.toggle, [optionsPanel.toggle]);
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
'shift+r',
|
'shift+r',
|
||||||
() => {
|
() => {
|
||||||
resetOptionsPanel();
|
optionsPanel.reset();
|
||||||
resetGalleryPanel();
|
galleryPanel.reset();
|
||||||
},
|
},
|
||||||
[resetOptionsPanel, resetGalleryPanel]
|
[optionsPanel.reset, galleryPanel.reset]
|
||||||
);
|
);
|
||||||
useHotkeys(
|
useHotkeys(
|
||||||
'f',
|
'f',
|
||||||
() => {
|
() => {
|
||||||
if (isOptionsPanelCollapsed || isGalleryPanelCollapsed) {
|
if (optionsPanel.isCollapsed || galleryPanel.isCollapsed) {
|
||||||
expandOptionsPanel();
|
optionsPanel.expand();
|
||||||
expandGalleryPanel();
|
galleryPanel.expand();
|
||||||
} else {
|
} else {
|
||||||
collapseOptionsPanel();
|
optionsPanel.collapse();
|
||||||
collapseGalleryPanel();
|
galleryPanel.collapse();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
isOptionsPanelCollapsed,
|
optionsPanel.isCollapsed,
|
||||||
isGalleryPanelCollapsed,
|
galleryPanel.isCollapsed,
|
||||||
expandOptionsPanel,
|
optionsPanel.expand,
|
||||||
expandGalleryPanel,
|
galleryPanel.expand,
|
||||||
collapseOptionsPanel,
|
optionsPanel.collapse,
|
||||||
collapseGalleryPanel,
|
galleryPanel.collapse,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -272,16 +260,16 @@ const InvokeTabs = () => {
|
|||||||
style={panelStyles}
|
style={panelStyles}
|
||||||
storage={panelStorage}
|
storage={panelStorage}
|
||||||
>
|
>
|
||||||
{!NO_SIDE_PANEL_TABS.includes(activeTabName) && (
|
{shouldShowOptionsPanel && (
|
||||||
<>
|
<>
|
||||||
<Panel
|
<Panel
|
||||||
id="options-panel"
|
id="options-panel"
|
||||||
ref={optionsPanelRef}
|
ref={optionsPanel.ref}
|
||||||
order={0}
|
order={0}
|
||||||
defaultSize={optionsPanelMinSize}
|
defaultSize={optionsPanel.minSize}
|
||||||
minSize={optionsPanelMinSize}
|
minSize={optionsPanel.minSize}
|
||||||
onCollapse={onCollapseOptionsPanel}
|
onCollapse={optionsPanel.onCollapse}
|
||||||
onExpand={onExpandOptionsPanel}
|
onExpand={optionsPanel.onExpand}
|
||||||
collapsible
|
collapsible
|
||||||
>
|
>
|
||||||
{activeTabName === 'nodes' ? (
|
{activeTabName === 'nodes' ? (
|
||||||
@ -292,7 +280,7 @@ const InvokeTabs = () => {
|
|||||||
</Panel>
|
</Panel>
|
||||||
<ResizeHandle
|
<ResizeHandle
|
||||||
id="options-main-handle"
|
id="options-main-handle"
|
||||||
onDoubleClick={onDoubleClickOptionsPanelHandle}
|
onDoubleClick={optionsPanel.onDoubleClickHandle}
|
||||||
orientation="vertical"
|
orientation="vertical"
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
@ -302,21 +290,21 @@ const InvokeTabs = () => {
|
|||||||
{tabPanels}
|
{tabPanels}
|
||||||
</InvTabPanels>
|
</InvTabPanels>
|
||||||
</Panel>
|
</Panel>
|
||||||
{!NO_GALLERY_TABS.includes(activeTabName) && (
|
{shouldShowGalleryPanel && (
|
||||||
<>
|
<>
|
||||||
<ResizeHandle
|
<ResizeHandle
|
||||||
id="main-gallery-handle"
|
id="main-gallery-handle"
|
||||||
orientation="vertical"
|
orientation="vertical"
|
||||||
onDoubleClick={onDoubleClickGalleryPanelHandle}
|
onDoubleClick={galleryPanel.onDoubleClickHandle}
|
||||||
/>
|
/>
|
||||||
<Panel
|
<Panel
|
||||||
id="gallery-panel"
|
id="gallery-panel"
|
||||||
ref={galleryPanelRef}
|
ref={galleryPanel.ref}
|
||||||
order={2}
|
order={2}
|
||||||
defaultSize={galleryPanelMinSize}
|
defaultSize={galleryPanel.minSize}
|
||||||
minSize={galleryPanelMinSize}
|
minSize={galleryPanel.minSize}
|
||||||
onCollapse={onCollapseGalleryPanel}
|
onCollapse={galleryPanel.onCollapse}
|
||||||
onExpand={onExpandGalleryPanel}
|
onExpand={galleryPanel.onExpand}
|
||||||
collapsible
|
collapsible
|
||||||
>
|
>
|
||||||
<ImageGalleryContent />
|
<ImageGalleryContent />
|
||||||
@ -324,6 +312,12 @@ const InvokeTabs = () => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</PanelGroup>
|
</PanelGroup>
|
||||||
|
{shouldShowOptionsPanel && (
|
||||||
|
<FloatingParametersPanelButtons panelApi={optionsPanel} />
|
||||||
|
)}
|
||||||
|
{shouldShowGalleryPanel && (
|
||||||
|
<FloatingGalleryButton panelApi={galleryPanel} />
|
||||||
|
)}
|
||||||
</InvTabs>
|
</InvTabs>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user