mirror of
https://github.com/Radiquum/AniX.git
synced 2025-04-07 00:34:41 +00:00
feat: add infinite scrolling
This commit is contained in:
parent
7f2b4f17a4
commit
15740651df
2 changed files with 61 additions and 8 deletions
|
@ -1,10 +1,12 @@
|
||||||
"use client";
|
"use client";
|
||||||
import useSWR from "swr";
|
import useSWRInfinite from "swr/infinite";
|
||||||
import { ReleaseSection } from "../../components/ReleaseSection/ReleaseSection";
|
import { ReleaseSection } from "../../components/ReleaseSection/ReleaseSection";
|
||||||
import { Spinner } from "../../components/Spinner/Spinner";
|
import { Spinner } from "../../components/Spinner/Spinner";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { useScrollPosition } from "@/app/hooks/useScrollPosition";
|
||||||
|
|
||||||
const fetcher = async (...args) => {
|
const fetcher = async url => {
|
||||||
const res = await fetch(...args);
|
const res = await fetch(url);
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
const error = new Error("An error occurred while fetching the data.");
|
const error = new Error("An error occurred while fetching the data.");
|
||||||
|
@ -24,11 +26,35 @@ const SectionTitleMapping = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function HomeStatus({ params }) {
|
export default function HomeStatus({ params }) {
|
||||||
const { data, error, isLoading } = useSWR(
|
const getKey = (pageIndex, previousPageData) => {
|
||||||
`/api/home?status=${params.slug}`,
|
if (previousPageData && !previousPageData.content.length) return null;
|
||||||
fetcher
|
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 <div>failed to load</div>;
|
if (error) return <div>failed to load</div>;
|
||||||
if (isLoading)
|
if (isLoading)
|
||||||
return (
|
return (
|
||||||
|
@ -39,12 +65,13 @@ export default function HomeStatus({ params }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main className="flex flex-col pt-2 pb-16 sm:pt-4 sm:pb-0">
|
<main className="flex flex-col pt-2 pb-16 sm:pt-4 sm:pb-0">
|
||||||
{data && (
|
{content && (
|
||||||
<ReleaseSection
|
<ReleaseSection
|
||||||
sectionTitle={SectionTitleMapping[params.slug]}
|
sectionTitle={SectionTitleMapping[params.slug]}
|
||||||
content={data.content}
|
content={content}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<button className="mx-auto w-[calc(100%-10rem)] border border-black rounded-lg p-4 mb-6 flex items-center justify-center gap-2 hover:bg-black hover:text-white transition" onClick={() => setSize(size + 1)}> <span className="w-10 h-10 iconify mdi--plus"> </span> <span className="text-lg">Load More</span></button>
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
26
app/hooks/useScrollPosition.js
Normal file
26
app/hooks/useScrollPosition.js
Normal file
|
@ -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);
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue