From 15740651dfa33f6a6b078ede5696e04ef3d36d35 Mon Sep 17 00:00:00 2001 From: Kentai Radiquum Date: Sat, 13 Jul 2024 06:26:37 +0500 Subject: [PATCH] feat: add infinite scrolling --- app/home/[slug]/page.js | 43 +++++++++++++++++++++++++++------- app/hooks/useScrollPosition.js | 26 ++++++++++++++++++++ 2 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 app/hooks/useScrollPosition.js diff --git a/app/home/[slug]/page.js b/app/home/[slug]/page.js index 61766d2..50c51af 100644 --- a/app/home/[slug]/page.js +++ b/app/home/[slug]/page.js @@ -1,10 +1,12 @@ "use client"; -import useSWR from "swr"; +import useSWRInfinite from "swr/infinite"; import { ReleaseSection } from "../../components/ReleaseSection/ReleaseSection"; import { Spinner } from "../../components/Spinner/Spinner"; +import { useState, useEffect } from "react"; +import { useScrollPosition } from "@/app/hooks/useScrollPosition"; -const fetcher = async (...args) => { - const res = await fetch(...args); +const fetcher = async url => { + const res = await fetch(url); if (!res.ok) { const error = new Error("An error occurred while fetching the data."); @@ -24,11 +26,35 @@ const SectionTitleMapping = { }; export default function HomeStatus({ params }) { - const { data, error, isLoading } = useSWR( - `/api/home?status=${params.slug}`, - fetcher + const getKey = (pageIndex, previousPageData) => { + if (previousPageData && !previousPageData.content.length) return null; + return `/api/home?status=${params.slug}&page=${pageIndex}`; + }; + + const { data, error, isLoading, size, setSize } = useSWRInfinite( + getKey, + fetcher, + {"initialSize": 2, "revalidateFirstPage": false} ); + const [content, setContent] = useState(null); + useEffect(() => { + if (data) { + let allReleases = []; + for (let i = 0; i < data.length; i++) { + allReleases.push(...data[i].content); + } + setContent(allReleases); + } + }, [data]); + + const scrollPosition = useScrollPosition(); + useEffect(() => { + if (scrollPosition >= 98 && scrollPosition <= 99) { + setSize(size + 1) + } + }, [scrollPosition]); + if (error) return
failed to load
; if (isLoading) return ( @@ -39,12 +65,13 @@ export default function HomeStatus({ params }) { return (
- {data && ( + {content && ( )} +
); } diff --git a/app/hooks/useScrollPosition.js b/app/hooks/useScrollPosition.js new file mode 100644 index 0000000..7fa1dd5 --- /dev/null +++ b/app/hooks/useScrollPosition.js @@ -0,0 +1,26 @@ +import { useEffect, useState } from "react"; + +export function useScrollPosition() { + const [scrollPosition, setScrollPosition] = useState(0); + + function handleScroll() { + const height = + document.documentElement.scrollHeight - + document.documentElement.clientHeight; + + const windowScroll = document.documentElement.scrollTop; + + const scrolled = (windowScroll / height) * 100; + + setScrollPosition(scrolled); + } + + useEffect(() => { + window.addEventListener("scroll", handleScroll, { passive: true }); + return () => { + window.removeEventListener("scroll", handleScroll); + }; + }); + + return Math.floor(scrollPosition); +} \ No newline at end of file