File size: 2,924 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 |
import type { ChakraProps } from '@invoke-ai/ui-library';
import { Box, IconButton } from '@invoke-ai/ui-library';
import { useGalleryImages } from 'features/gallery/hooks/useGalleryImages';
import { useGalleryNavigation } from 'features/gallery/hooks/useGalleryNavigation';
import { useGalleryPagination } from 'features/gallery/hooks/useGalleryPagination';
import { memo, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { PiCaretLeftBold, PiCaretRightBold } from 'react-icons/pi';
const NextPrevImageButtons = ({ inset = 8 }: { inset?: ChakraProps['insetInlineStart' | 'insetInlineEnd'] }) => {
const { t } = useTranslation();
const { prevImage, nextImage, isOnFirstImageOfView, isOnLastImageOfView } = useGalleryNavigation();
const { isFetching } = useGalleryImages().queryResult;
const { isNextEnabled, goNext, isPrevEnabled, goPrev } = useGalleryPagination();
const shouldShowLeftArrow = useMemo(() => {
if (!isOnFirstImageOfView) {
return true;
}
if (isPrevEnabled) {
return true;
}
return false;
}, [isOnFirstImageOfView, isPrevEnabled]);
const onClickLeftArrow = useCallback(() => {
if (isOnFirstImageOfView) {
if (isPrevEnabled && !isFetching) {
goPrev('arrow');
}
} else {
prevImage();
}
}, [goPrev, isFetching, isOnFirstImageOfView, isPrevEnabled, prevImage]);
const shouldShowRightArrow = useMemo(() => {
if (!isOnLastImageOfView) {
return true;
}
if (isNextEnabled) {
return true;
}
return false;
}, [isNextEnabled, isOnLastImageOfView]);
const onClickRightArrow = useCallback(() => {
if (isOnLastImageOfView) {
if (isNextEnabled && !isFetching) {
goNext('arrow');
}
} else {
nextImage();
}
}, [goNext, isFetching, isNextEnabled, isOnLastImageOfView, nextImage]);
return (
<Box pos="relative" h="full" w="full">
{shouldShowLeftArrow && (
<IconButton
position="absolute"
top="50%"
transform="translate(0, -50%)"
aria-label={t('accessibility.previousImage')}
icon={<PiCaretLeftBold size={64} />}
variant="unstyled"
onClick={onClickLeftArrow}
isDisabled={isFetching}
color="base.100"
pointerEvents="auto"
insetInlineStart={inset}
/>
)}
{shouldShowRightArrow && (
<IconButton
position="absolute"
top="50%"
transform="translate(0, -50%)"
aria-label={t('accessibility.nextImage')}
icon={<PiCaretRightBold size={64} />}
variant="unstyled"
onClick={onClickRightArrow}
isDisabled={isFetching}
color="base.100"
pointerEvents="auto"
insetInlineEnd={inset}
/>
)}
</Box>
);
};
export default memo(NextPrevImageButtons);
|