feat(ui): update right arrow gallery load more

- add hotkey support
- add loading state
- only show if there are more images to load
This commit is contained in:
psychedelicious 2023-07-09 00:26:49 +10:00 committed by Kent Keirsey
parent 2c956806d7
commit 3001e4c947
2 changed files with 70 additions and 24 deletions

View File

@ -57,6 +57,7 @@ const selector = createSelector(
images,
allImagesTotal,
isLoading,
isFetching,
categories,
selectedBoardId,
};
@ -82,8 +83,14 @@ const ImageGalleryGrid = () => {
},
});
const { images, isLoading, allImagesTotal, categories, selectedBoardId } =
useAppSelector(selector);
const {
images,
isLoading,
isFetching,
allImagesTotal,
categories,
selectedBoardId,
} = useAppSelector(selector);
const { selectedBoard } = useListAllBoardsQuery(undefined, {
selectFromResult: ({ data }) => ({
@ -176,7 +183,7 @@ const ImageGalleryGrid = () => {
<IAIButton
onClick={handleLoadMoreImages}
isDisabled={!areMoreAvailable}
isLoading={isLoading}
isLoading={isFetching}
loadingText="Loading"
flexShrink={0}
>

View File

@ -1,17 +1,17 @@
import { ChakraProps, Flex, Grid, IconButton } from '@chakra-ui/react';
import { ChakraProps, Flex, Grid, IconButton, Spinner } from '@chakra-ui/react';
import { createSelector } from '@reduxjs/toolkit';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { clamp, isEqual } from 'lodash-es';
import { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { FaAngleLeft, FaAngleRight, FaRedo } from 'react-icons/fa';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import {
imageSelected,
selectFilteredImages,
selectImagesById,
} from 'features/gallery/store/gallerySlice';
import { clamp, isEqual } from 'lodash-es';
import { useCallback, useState } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import { selectFilteredImages } from 'features/gallery/store/gallerySlice';
import { useTranslation } from 'react-i18next';
import { FaAngleDoubleRight, FaAngleLeft, FaAngleRight } from 'react-icons/fa';
import { receivedPageOfImages } from 'services/api/thunks/image';
const nextPrevButtonTriggerAreaStyles: ChakraProps['sx'] = {
@ -27,6 +27,7 @@ const nextPrevButtonStyles: ChakraProps['sx'] = {
export const nextPrevImageButtonsSelector = createSelector(
[stateSelector, selectFilteredImages],
(state, filteredImages) => {
const { total, isFetching } = state.gallery;
const lastSelectedImage =
state.gallery.selection[state.gallery.selection.length - 1];
@ -64,6 +65,8 @@ export const nextPrevImageButtonsSelector = createSelector(
isOnFirstImage: currentImageIndex === 0,
isOnLastImage:
!isNaN(currentImageIndex) && currentImageIndex === imagesLength - 1,
areMoreImagesAvailable: total > imagesLength,
isFetching,
nextImage,
prevImage,
nextImageId,
@ -81,8 +84,14 @@ const NextPrevImageButtons = () => {
const dispatch = useAppDispatch();
const { t } = useTranslation();
const { isOnFirstImage, isOnLastImage, nextImageId, prevImageId } =
useAppSelector(nextPrevImageButtonsSelector);
const {
isOnFirstImage,
isOnLastImage,
nextImageId,
prevImageId,
areMoreImagesAvailable,
isFetching,
} = useAppSelector(nextPrevImageButtonsSelector);
const [shouldShowNextPrevButtons, setShouldShowNextPrevButtons] =
useState<boolean>(false);
@ -122,9 +131,21 @@ const NextPrevImageButtons = () => {
useHotkeys(
'right',
() => {
handleNextImage();
if (isOnLastImage && areMoreImagesAvailable && !isFetching) {
handleLoadMoreImages();
return;
}
if (!isOnLastImage) {
handleNextImage();
}
},
[nextImageId]
[
nextImageId,
isOnLastImage,
areMoreImagesAvailable,
handleLoadMoreImages,
isFetching,
]
);
return (
@ -173,16 +194,34 @@ const NextPrevImageButtons = () => {
sx={nextPrevButtonStyles}
/>
)}
{shouldShowNextPrevButtons && isOnLastImage && (
<IconButton
aria-label={t('accessibility.loadMore')}
icon={<FaRedo size={42} />}
variant="unstyled"
onClick={handleLoadMoreImages}
boxSize={16}
sx={nextPrevButtonStyles}
/>
)}
{shouldShowNextPrevButtons &&
isOnLastImage &&
areMoreImagesAvailable &&
!isFetching && (
<IconButton
aria-label={t('accessibility.loadMore')}
icon={<FaAngleDoubleRight size={64} />}
variant="unstyled"
onClick={handleLoadMoreImages}
boxSize={16}
sx={nextPrevButtonStyles}
/>
)}
{shouldShowNextPrevButtons &&
isOnLastImage &&
areMoreImagesAvailable &&
isFetching && (
<Flex
sx={{
w: 16,
h: 16,
alignItems: 'center',
justifyContent: 'center',
}}
>
<Spinner opacity={0.5} size="xl" />
</Flex>
)}
</Grid>
</Flex>
);