roshikhan301's picture
Upload 2113 files
8a37e0a verified
import { Box, Flex, IconButton } from '@invoke-ai/ui-library';
import { useAppSelector } from 'app/store/storeHooks';
import { useFocusRegion } from 'common/hooks/focus';
import { useAssertSingleton } from 'common/hooks/useAssertSingleton';
import { CompareToolbar } from 'features/gallery/components/ImageViewer/CompareToolbar';
import CurrentImagePreview from 'features/gallery/components/ImageViewer/CurrentImagePreview';
import { ImageComparison } from 'features/gallery/components/ImageViewer/ImageComparison';
import { ImageComparisonDroppable } from 'features/gallery/components/ImageViewer/ImageComparisonDroppable';
import { ViewerToolbar } from 'features/gallery/components/ImageViewer/ViewerToolbar';
import { selectHasImageToCompare } from 'features/gallery/store/gallerySelectors';
import type { ReactNode } from 'react';
import { memo, useRef } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import { useTranslation } from 'react-i18next';
import { PiXBold } from 'react-icons/pi';
import { useMeasure } from 'react-use';
import { useImageViewer } from './useImageViewer';
type Props = {
closeButton?: ReactNode;
};
const useFocusRegionOptions = {
focusOnMount: true,
};
export const ImageViewer = memo(({ closeButton }: Props) => {
useAssertSingleton('ImageViewer');
const hasImageToCompare = useAppSelector(selectHasImageToCompare);
const [containerRef, containerDims] = useMeasure<HTMLDivElement>();
const ref = useRef<HTMLDivElement>(null);
useFocusRegion('viewer', ref, useFocusRegionOptions);
return (
<Flex
ref={ref}
tabIndex={-1}
layerStyle="first"
borderRadius="base"
position="absolute"
flexDirection="column"
top={0}
right={0}
bottom={0}
left={0}
alignItems="center"
justifyContent="center"
>
{hasImageToCompare && <CompareToolbar />}
{!hasImageToCompare && <ViewerToolbar closeButton={closeButton} />}
<Box ref={containerRef} w="full" h="full" p={2}>
{!hasImageToCompare && <CurrentImagePreview />}
{hasImageToCompare && <ImageComparison containerDims={containerDims} />}
</Box>
<ImageComparisonDroppable />
</Flex>
);
});
ImageViewer.displayName = 'ImageViewer';
export const GatedImageViewer = memo(() => {
const imageViewer = useImageViewer();
if (!imageViewer.isOpen) {
return null;
}
return <ImageViewer closeButton={<ImageViewerCloseButton />} />;
});
GatedImageViewer.displayName = 'GatedImageViewer';
const ImageViewerCloseButton = memo(() => {
const { t } = useTranslation();
const imageViewer = useImageViewer();
useAssertSingleton('ImageViewerCloseButton');
useHotkeys('esc', imageViewer.close);
return (
<IconButton
tooltip={t('gallery.closeViewer')}
aria-label={t('gallery.closeViewer')}
icon={<PiXBold />}
variant="link"
alignSelf="stretch"
onClick={imageViewer.close}
/>
);
});
ImageViewerCloseButton.displayName = 'ImageViewerCloseButton';
const GatedImageViewerCloseButton = memo(() => {
const imageViewer = useImageViewer();
if (!imageViewer.isOpen) {
return null;
}
return <ImageViewerCloseButton />;
});
GatedImageViewerCloseButton.displayName = 'GatedImageViewerCloseButton';