Skip to content

Commit ff42af9

Browse files
committed
add infinite scroll
1 parent a1c6a17 commit ff42af9

File tree

5 files changed

+68
-7
lines changed

5 files changed

+68
-7
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"react-animated-cursor": "^2.8.1",
2525
"react-dom": "^18.2.0",
2626
"react-hook-form": "^7.45.1",
27+
"react-infinite-scroll-component": "^6.1.0",
2728
"react-query": "^3.39.3",
2829
"react-toastify": "^9.1.3",
2930
"socket.io-client": "^4.6.1",

src/hooks/useFetchImgs.tsx

+17-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useQuery } from 'react-query';
22
import axios from 'axios';
33
import { IPhoto } from '../services/interface';
44
import { gapi } from 'gapi-script';
5+
import { useState } from 'react';
56

67
// init for google api
78
const initAPI = async () => {
@@ -40,10 +41,20 @@ const fetchFromDrive = async (driveId: string) => {
4041
return imgUrls;
4142
};
4243

44+
interface paginationState {
45+
count: number;
46+
numPage: number;
47+
}
48+
4349
const useFetchImgs = (
4450
setImgArr: (arr: Array<IPhoto>) => void,
4551
driveId: string
4652
) => {
53+
const PAGE_COUNT = 20;
54+
const [pagination, setPagination] = useState<paginationState>({
55+
count: PAGE_COUNT,
56+
numPage: 1,
57+
});
4758
const query = useQuery({
4859
queryKey: ['imgArr'],
4960
queryFn: async () => {
@@ -54,8 +65,13 @@ const useFetchImgs = (
5465
}
5566

5667
const res = await axios.get(
57-
'https://api.slingacademy.com/v1/sample-data/photos?offset=5&limit=2000'
68+
`https://api.slingacademy.com/v1/sample-data/photos?offset=5&limit=${pagination.count}`
5869
);
70+
71+
setPagination((prev) => ({
72+
count: prev.count + PAGE_COUNT,
73+
numPage: prev.count + 1,
74+
}));
5975
if (res?.data) setImgArr(res?.data?.photos);
6076
},
6177
retry: 1,

src/modules/Gallery/Gallery.tsx

+21-6
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,26 @@ import Header from '../Header/Header';
77
import { Notyf } from 'notyf';
88
import 'notyf/notyf.min.css';
99
import { formatUrl } from './helper';
10-
import BouncingDotsLoader from '../../components/Loader/Loader';
10+
// import BouncingDotsLoader from '../../components/Loader/Loader';
11+
// import InfiniteScroll from 'react-infinite-scroll-component';
1112

1213
const Gallery = () => {
13-
var notyf = new Notyf();
14+
// consts
15+
const LIMIT_TOTAL_IMG = 120;
16+
17+
// state
1418
const [imgArr, setImgArr] = useState<Array<IPhoto>>([]);
1519
const [driveId, setDriveId] = useState<string>('');
20+
21+
// hooks
1622
const query = useFetchImgs(setImgArr, driveId);
1723
const topRef = useRef<HTMLDivElement>(null);
1824
const bottomRef = useRef<HTMLDivElement>(null);
1925

26+
// varbs
27+
var notyf = new Notyf();
28+
29+
// functions
2030
const scrollTop = () =>
2131
topRef.current?.scrollIntoView({ behavior: 'smooth' });
2232

@@ -49,7 +59,7 @@ const Gallery = () => {
4959
notyf.success('Img removed successfully');
5060
};
5161

52-
if (query.isFetching) return <BouncingDotsLoader />;
62+
// if (query.isFetching) return <BouncingDotsLoader />;
5363

5464
return (
5565
<>
@@ -62,7 +72,12 @@ const Gallery = () => {
6272
driveId={driveId}
6373
refetch={query.refetch}
6474
/>
65-
<S.GridLayout>
75+
<S.InfiniteScrollGrid
76+
dataLength={imgArr.length}
77+
next={query.refetch}
78+
hasMore={imgArr.length < LIMIT_TOTAL_IMG}
79+
loader={<h4>Loading...</h4>}
80+
>
6681
{imgArr.map((item: IPhoto, index: number) => (
6782
<ImgComponent
6883
url={item.url} // make sure the component can add google drive files too in the url
@@ -74,8 +89,8 @@ const Gallery = () => {
7489
removeFromArr={removeFromArr}
7590
/>
7691
))}
77-
<S.BottomAnchor ref={bottomRef} />
78-
</S.GridLayout>
92+
</S.InfiniteScrollGrid>
93+
<S.BottomAnchor ref={bottomRef} />
7994
</>
8095
);
8196
};

src/modules/Gallery/styled.js

+17
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import styled from 'styled-components';
2+
import InfiniteScroll from 'react-infinite-scroll-component';
23

34
const GridLayout = styled.div`
45
display: grid;
@@ -15,6 +16,21 @@ const GridLayout = styled.div`
1516
}
1617
`;
1718

19+
const InfiniteScrollGrid = styled(InfiniteScroll)`
20+
display: grid;
21+
padding: 0.1rem 0; // this will make space for the header and the footer to not overide photos
22+
height: 100vh;
23+
width: 100vw;
24+
grid-template-columns: repeat(4, 1fr);
25+
grid-template-rows: max-content;
26+
grid-auto-rows: max-content;
27+
gap: 0.1rem;
28+
box-sizing: border-box;
29+
@media (max-width: 750px) {
30+
grid-template-columns: 1fr 1fr 1fr;
31+
}
32+
`;
33+
1834
const TopAnchor = styled.div`
1935
display: flex;
2036
height: 0;
@@ -27,6 +43,7 @@ const BottomAnchor = styled.div`
2743

2844
const S = {
2945
GridLayout,
46+
InfiniteScrollGrid,
3047
TopAnchor,
3148
BottomAnchor,
3249
};

yarn.lock

+12
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,13 @@ react-hook-form@^7.45.1:
13041304
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.45.4.tgz#73d228b704026ae95d7e5f7b207a681b173ec62a"
13051305
integrity sha512-HGDV1JOOBPZj10LB3+OZgfDBTn+IeEsNOKiq/cxbQAIbKaiJUe/KV8DBUzsx0Gx/7IG/orWqRRm736JwOfUSWQ==
13061306

1307+
react-infinite-scroll-component@^6.1.0:
1308+
version "6.1.0"
1309+
resolved "https://registry.yarnpkg.com/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz#7e511e7aa0f728ac3e51f64a38a6079ac522407f"
1310+
integrity sha512-SQu5nCqy8DxQWpnUVLx7V7b7LcA37aM7tvoWjTLZp1dk6EJibM5/4EJKzOnl07/BsM1Y40sKLuqjCwwH/xV0TQ==
1311+
dependencies:
1312+
throttle-debounce "^2.1.0"
1313+
13071314
react-is@^16.7.0:
13081315
version "16.13.1"
13091316
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
@@ -1441,6 +1448,11 @@ svg-parser@^2.0.4:
14411448
resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5"
14421449
integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==
14431450

1451+
throttle-debounce@^2.1.0:
1452+
version "2.3.0"
1453+
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.3.0.tgz#fd31865e66502071e411817e241465b3e9c372e2"
1454+
integrity sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==
1455+
14441456
to-fast-properties@^2.0.0:
14451457
version "2.0.0"
14461458
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"

0 commit comments

Comments
 (0)