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);