mirror of
https://github.com/invoke-ai/InvokeAI.git
synced 2026-04-23 03:00:31 -04:00
feat(ui): animations for send to alerts
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
||||
Spacer,
|
||||
} from '@invoke-ai/ui-library';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import { useBoolean } from 'common/hooks/useBoolean';
|
||||
import {
|
||||
setRightPanelTabToGallery,
|
||||
setRightPanelTabToLayers,
|
||||
@@ -18,31 +19,12 @@ import { useImageViewer } from 'features/gallery/components/ImageViewer/useImage
|
||||
import { useCurrentDestination } from 'features/queue/hooks/useCurrentDestination';
|
||||
import { selectShowSendToAlerts, showSendToAlertsChanged } from 'features/system/store/systemSlice';
|
||||
import { setActiveTab } from 'features/ui/store/uiSlice';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import type { PropsWithChildren, ReactNode } from 'react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
import { PiXBold } from 'react-icons/pi';
|
||||
|
||||
const DontShowMeTheseAgainButton = () => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const onClick = useCallback(() => {
|
||||
dispatch(showSendToAlertsChanged(false));
|
||||
}, [dispatch]);
|
||||
return (
|
||||
<IconButton
|
||||
variant="link"
|
||||
icon={<Icon as={PiXBold} fill="base.50 !important" />}
|
||||
tooltip={t('common.dontShowMeThese')}
|
||||
aria-label={t('common.dontShowMeThese')}
|
||||
right={-1}
|
||||
top={-2}
|
||||
onClick={onClick}
|
||||
minW="auto"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const ActivateImageViewerButton = (props: PropsWithChildren) => {
|
||||
const imageViewer = useImageViewer();
|
||||
const onClick = useCallback(() => {
|
||||
@@ -59,32 +41,26 @@ const ActivateImageViewerButton = (props: PropsWithChildren) => {
|
||||
export const SendingToGalleryAlert = () => {
|
||||
const { t } = useTranslation();
|
||||
const destination = useCurrentDestination();
|
||||
const showSendToAlerts = useAppSelector(selectShowSendToAlerts);
|
||||
const isVisible = useMemo(() => {
|
||||
if (!destination) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!showSendToAlerts) {
|
||||
return null;
|
||||
}
|
||||
if (destination === 'canvas') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!destination) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (destination === 'canvas') {
|
||||
return null;
|
||||
}
|
||||
return true;
|
||||
}, [destination]);
|
||||
|
||||
return (
|
||||
<Alert status="warning" flexDir="column" pointerEvents="auto" borderRadius="base" fontSize="sm" shadow="md">
|
||||
<Flex w="full" alignItems="center">
|
||||
<AlertIcon />
|
||||
<AlertTitle>{t('controlLayers.sendingToGallery')}</AlertTitle>
|
||||
<Spacer />
|
||||
<DontShowMeTheseAgainButton />
|
||||
</Flex>
|
||||
<AlertDescription>
|
||||
<AlertWrapper
|
||||
title={t('controlLayers.sendingToGallery')}
|
||||
description={
|
||||
<Trans i18nKey="controlLayers.viewProgressInViewer" components={{ Btn: <ActivateImageViewerButton /> }} />
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
}
|
||||
isVisible={isVisible}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -106,31 +82,80 @@ const ActivateCanvasButton = (props: PropsWithChildren) => {
|
||||
export const SendingToCanvasAlert = () => {
|
||||
const { t } = useTranslation();
|
||||
const destination = useCurrentDestination();
|
||||
const showSendToAlerts = useAppSelector(selectShowSendToAlerts);
|
||||
const isVisible = useMemo(() => {
|
||||
if (!destination) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!showSendToAlerts) {
|
||||
return null;
|
||||
}
|
||||
if (destination !== 'canvas') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!destination) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (destination !== 'canvas') {
|
||||
return null;
|
||||
}
|
||||
return true;
|
||||
}, [destination]);
|
||||
|
||||
return (
|
||||
<Alert status="warning" flexDir="column" pointerEvents="auto" borderRadius="base" fontSize="sm" shadow="md">
|
||||
<Flex w="full" alignItems="center">
|
||||
<AlertIcon />
|
||||
<AlertTitle>{t('controlLayers.sendingToCanvas')}</AlertTitle>
|
||||
<Spacer />
|
||||
<DontShowMeTheseAgainButton />
|
||||
</Flex>
|
||||
<AlertDescription>
|
||||
<AlertWrapper
|
||||
title={t('controlLayers.sendingToCanvas')}
|
||||
description={
|
||||
<Trans i18nKey="controlLayers.viewProgressOnCanvas" components={{ Btn: <ActivateCanvasButton /> }} />
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
}
|
||||
isVisible={isVisible}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const AlertWrapper = ({
|
||||
title,
|
||||
description,
|
||||
isVisible,
|
||||
}: {
|
||||
title: ReactNode;
|
||||
description: ReactNode;
|
||||
isVisible: boolean;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const dispatch = useAppDispatch();
|
||||
const showSendToAlerts = useAppSelector(selectShowSendToAlerts);
|
||||
const isHovered = useBoolean(false);
|
||||
const onClickDontShowMeThese = useCallback(() => {
|
||||
dispatch(showSendToAlertsChanged(false));
|
||||
isHovered.setFalse();
|
||||
}, [dispatch, isHovered]);
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{(isVisible || isHovered.isTrue) && showSendToAlerts && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1, transition: { duration: 0.1, ease: 'easeOut' } }}
|
||||
exit={{
|
||||
opacity: 0,
|
||||
transition: { duration: 0.1, delay: !isHovered.isTrue ? 1 : 0.1, ease: 'easeIn' },
|
||||
}}
|
||||
onMouseEnter={isHovered.setTrue}
|
||||
onMouseLeave={isHovered.setFalse}
|
||||
>
|
||||
<Alert status="warning" flexDir="column" pointerEvents="auto" borderRadius="base" fontSize="sm" shadow="md">
|
||||
<Flex w="full" alignItems="center">
|
||||
<AlertIcon />
|
||||
<AlertTitle>{title}</AlertTitle>
|
||||
<Spacer />
|
||||
<IconButton
|
||||
variant="link"
|
||||
icon={<Icon as={PiXBold} fill="base.50 !important" />}
|
||||
tooltip={t('common.dontShowMeThese')}
|
||||
aria-label={t('common.dontShowMeThese')}
|
||||
right={-1}
|
||||
top={-2}
|
||||
onClick={onClickDontShowMeThese}
|
||||
minW="auto"
|
||||
/>
|
||||
</Flex>
|
||||
<AlertDescription>{description}</AlertDescription>
|
||||
</Alert>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user