Added infinite scroll (#5418)
- Added an infinite scroll to the changelog to avoid overloading the DOM
This commit is contained in:
@ -0,0 +1,85 @@
|
|||||||
|
'use client';
|
||||||
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
import { Line } from '@/app/_components/releases/Line';
|
||||||
|
import { Release } from '@/app/_components/releases/Release';
|
||||||
|
import { ReleaseNote } from '@/app/releases/api/route';
|
||||||
|
import { getGithubReleaseDateFromReleaseNote } from '@/app/releases/utils/get-github-release-date-from-release-note';
|
||||||
|
import { GithubReleases } from '@/database/model';
|
||||||
|
|
||||||
|
interface ReleaseProps {
|
||||||
|
visibleReleasesNotes: ReleaseNote[];
|
||||||
|
githubReleases: GithubReleases[];
|
||||||
|
mdxReleasesContent: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ReleaseContainer = ({
|
||||||
|
visibleReleasesNotes,
|
||||||
|
githubReleases,
|
||||||
|
mdxReleasesContent,
|
||||||
|
}: ReleaseProps) => {
|
||||||
|
const [page, setPage] = useState(1);
|
||||||
|
const [releases, setReleases] = useState<ReleaseNote[]>(
|
||||||
|
visibleReleasesNotes.slice(0, 5),
|
||||||
|
);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const loaderRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (page === 1) return;
|
||||||
|
|
||||||
|
const loadMoreReleases = () => {
|
||||||
|
const start = (page - 1) * 5;
|
||||||
|
const end = start + 5;
|
||||||
|
const newReleases = visibleReleasesNotes.slice(start, end);
|
||||||
|
setReleases((prevReleases) => [...prevReleases, ...newReleases]);
|
||||||
|
};
|
||||||
|
|
||||||
|
setLoading(true);
|
||||||
|
loadMoreReleases();
|
||||||
|
setLoading(false);
|
||||||
|
}, [page]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
(entries) => {
|
||||||
|
if (entries[0].isIntersecting && !loading) {
|
||||||
|
setPage((prevPage) => prevPage + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
threshold: 1.0,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (loaderRef.current) {
|
||||||
|
observer.observe(loaderRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (loaderRef.current) {
|
||||||
|
observer.unobserve(loaderRef.current);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [loading]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{releases.map((note, index) => (
|
||||||
|
<React.Fragment key={note.slug}>
|
||||||
|
<Release
|
||||||
|
githubPublishedAt={getGithubReleaseDateFromReleaseNote(
|
||||||
|
githubReleases,
|
||||||
|
note.release,
|
||||||
|
note.date,
|
||||||
|
)}
|
||||||
|
release={note}
|
||||||
|
mdxReleaseContent={mdxReleasesContent[index]}
|
||||||
|
/>
|
||||||
|
{index != releases.length - 1 && <Line />}
|
||||||
|
</React.Fragment>
|
||||||
|
))}
|
||||||
|
<div ref={loaderRef}>{loading && <p>Loading more releases...</p>}</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -2,11 +2,9 @@ import React from 'react';
|
|||||||
import { desc } from 'drizzle-orm';
|
import { desc } from 'drizzle-orm';
|
||||||
import { Metadata } from 'next';
|
import { Metadata } from 'next';
|
||||||
|
|
||||||
import { Line } from '@/app/_components/releases/Line';
|
import { ReleaseContainer } from '@/app/_components/releases/ReleaseContainer';
|
||||||
import { Release } from '@/app/_components/releases/Release';
|
|
||||||
import { Title } from '@/app/_components/releases/StyledTitle';
|
import { Title } from '@/app/_components/releases/StyledTitle';
|
||||||
import { ContentContainer } from '@/app/_components/ui/layout/ContentContainer';
|
import { ContentContainer } from '@/app/_components/ui/layout/ContentContainer';
|
||||||
import { getGithubReleaseDateFromReleaseNote } from '@/app/releases/utils/get-github-release-date-from-release-note';
|
|
||||||
import {
|
import {
|
||||||
getMdxReleasesContent,
|
getMdxReleasesContent,
|
||||||
getReleases,
|
getReleases,
|
||||||
@ -43,21 +41,11 @@ const Home = async () => {
|
|||||||
return (
|
return (
|
||||||
<ContentContainer>
|
<ContentContainer>
|
||||||
<Title />
|
<Title />
|
||||||
|
<ReleaseContainer
|
||||||
{visibleReleasesNotes.map((note, index) => (
|
visibleReleasesNotes={visibleReleasesNotes}
|
||||||
<React.Fragment key={note.slug}>
|
githubReleases={githubReleases}
|
||||||
<Release
|
mdxReleasesContent={mdxReleasesContent}
|
||||||
githubPublishedAt={getGithubReleaseDateFromReleaseNote(
|
/>
|
||||||
githubReleases,
|
|
||||||
note.release,
|
|
||||||
note.date,
|
|
||||||
)}
|
|
||||||
release={note}
|
|
||||||
mdxReleaseContent={mdxReleasesContent[index]}
|
|
||||||
/>
|
|
||||||
{index != releaseNotes.length - 1 && <Line />}
|
|
||||||
</React.Fragment>
|
|
||||||
))}
|
|
||||||
</ContentContainer>
|
</ContentContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user