File size: 4,349 Bytes
8a37e0a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
import { Box, Flex } from '@invoke-ai/ui-library';
import { useStore } from '@nanostores/react';
import { skipToken } from '@reduxjs/toolkit/query';
import { useAppSelector } from 'app/store/storeHooks';
import { CanvasAlertsInvocationProgress } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsInvocationProgress';
import { CanvasAlertsSendingToCanvas } from 'features/controlLayers/components/CanvasAlerts/CanvasAlertsSendingTo';
import { DndImage } from 'features/dnd/DndImage';
import ImageMetadataViewer from 'features/gallery/components/ImageMetadataViewer/ImageMetadataViewer';
import NextPrevImageButtons from 'features/gallery/components/NextPrevImageButtons';
import { selectLastSelectedImageName } from 'features/gallery/store/gallerySelectors';
import { selectShouldShowImageDetails, selectShouldShowProgressInViewer } from 'features/ui/store/uiSelectors';
import type { AnimationProps } from 'framer-motion';
import { AnimatePresence, motion } from 'framer-motion';
import { memo, useCallback, useRef, useState } from 'react';
import { useGetImageDTOQuery } from 'services/api/endpoints/images';
import type { ImageDTO } from 'services/api/types';
import { $hasProgressImage, $isProgressFromCanvas } from 'services/events/stores';
import { NoContentForViewer } from './NoContentForViewer';
import ProgressImage from './ProgressImage';
const CurrentImagePreview = () => {
const shouldShowImageDetails = useAppSelector(selectShouldShowImageDetails);
const imageName = useAppSelector(selectLastSelectedImageName);
const { currentData: imageDTO } = useGetImageDTOQuery(imageName ?? skipToken);
// Show and hide the next/prev buttons on mouse move
const [shouldShowNextPrevButtons, setShouldShowNextPrevButtons] = useState<boolean>(false);
const timeoutId = useRef(0);
const onMouseOver = useCallback(() => {
setShouldShowNextPrevButtons(true);
window.clearTimeout(timeoutId.current);
}, []);
const onMouseOut = useCallback(() => {
timeoutId.current = window.setTimeout(() => {
setShouldShowNextPrevButtons(false);
}, 500);
}, []);
return (
<Flex
onMouseOver={onMouseOver}
onMouseOut={onMouseOut}
width="full"
height="full"
alignItems="center"
justifyContent="center"
position="relative"
>
<ImageContent imageDTO={imageDTO} />
<Flex
flexDir="column"
gap={2}
position="absolute"
top={0}
insetInlineStart={0}
pointerEvents="none"
alignItems="flex-start"
>
<CanvasAlertsSendingToCanvas />
<CanvasAlertsInvocationProgress />
</Flex>
{shouldShowImageDetails && imageDTO && (
<Box position="absolute" opacity={0.8} top={0} width="full" height="full" borderRadius="base">
<ImageMetadataViewer image={imageDTO} />
</Box>
)}
<AnimatePresence>
{shouldShowNextPrevButtons && imageDTO && (
<Box
as={motion.div}
key="nextPrevButtons"
initial={initial}
animate={animateArrows}
exit={exit}
position="absolute"
top={0}
right={0}
bottom={0}
left={0}
pointerEvents="none"
>
<NextPrevImageButtons />
</Box>
)}
</AnimatePresence>
</Flex>
);
};
export default memo(CurrentImagePreview);
const ImageContent = memo(({ imageDTO }: { imageDTO?: ImageDTO }) => {
const hasProgressImage = useStore($hasProgressImage);
const isProgressFromCanvas = useStore($isProgressFromCanvas);
const shouldShowProgressInViewer = useAppSelector(selectShouldShowProgressInViewer);
if (hasProgressImage && !isProgressFromCanvas && shouldShowProgressInViewer) {
return <ProgressImage />;
}
if (!imageDTO) {
return <NoContentForViewer />;
}
return (
<Flex w="full" h="full" position="absolute" alignItems="center" justifyContent="center">
<DndImage imageDTO={imageDTO} />
</Flex>
);
});
ImageContent.displayName = 'ImageContent';
const initial: AnimationProps['initial'] = {
opacity: 0,
};
const animateArrows: AnimationProps['animate'] = {
opacity: 1,
transition: { duration: 0.07 },
};
const exit: AnimationProps['exit'] = {
opacity: 0,
transition: { duration: 0.07 },
};
|