diff --git a/packages/twenty-website/src/app/_components/releases/ReleaseContainer.tsx b/packages/twenty-website/src/app/_components/releases/ReleaseContainer.tsx new file mode 100644 index 000000000..df7873ba9 --- /dev/null +++ b/packages/twenty-website/src/app/_components/releases/ReleaseContainer.tsx @@ -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( + visibleReleasesNotes.slice(0, 5), + ); + const [loading, setLoading] = useState(false); + const loaderRef = useRef(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) => ( + + + {index != releases.length - 1 && } + + ))} +
{loading &&

Loading more releases...

}
+ + ); +}; diff --git a/packages/twenty-website/src/app/releases/page.tsx b/packages/twenty-website/src/app/releases/page.tsx index 40a2fe7da..8470ee033 100644 --- a/packages/twenty-website/src/app/releases/page.tsx +++ b/packages/twenty-website/src/app/releases/page.tsx @@ -2,11 +2,9 @@ import React from 'react'; import { desc } from 'drizzle-orm'; import { Metadata } from 'next'; -import { Line } from '@/app/_components/releases/Line'; -import { Release } from '@/app/_components/releases/Release'; +import { ReleaseContainer } from '@/app/_components/releases/ReleaseContainer'; import { Title } from '@/app/_components/releases/StyledTitle'; import { ContentContainer } from '@/app/_components/ui/layout/ContentContainer'; -import { getGithubReleaseDateFromReleaseNote } from '@/app/releases/utils/get-github-release-date-from-release-note'; import { getMdxReleasesContent, getReleases, @@ -43,21 +41,11 @@ const Home = async () => { return ( - - {visibleReleasesNotes.map((note, index) => ( - <React.Fragment key={note.slug}> - <Release - githubPublishedAt={getGithubReleaseDateFromReleaseNote( - githubReleases, - note.release, - note.date, - )} - release={note} - mdxReleaseContent={mdxReleasesContent[index]} - /> - {index != releaseNotes.length - 1 && <Line />} - </React.Fragment> - ))} + <ReleaseContainer + visibleReleasesNotes={visibleReleasesNotes} + githubReleases={githubReleases} + mdxReleasesContent={mdxReleasesContent} + /> </ContentContainer> ); };