diff --git a/app/(home-pages)/reader/GlobalContent.tsx b/app/(home-pages)/reader/GlobalContent.tsx new file mode 100644 index 00000000..fba3deab --- /dev/null +++ b/app/(home-pages)/reader/GlobalContent.tsx @@ -0,0 +1,9 @@ +"use client"; + +export const GlobalContent = () => { + return ( +
+ Nothing here yet… +
+ ); +}; diff --git a/app/(home-pages)/reader/InboxContent.tsx b/app/(home-pages)/reader/InboxContent.tsx new file mode 100644 index 00000000..a2ea6e07 --- /dev/null +++ b/app/(home-pages)/reader/InboxContent.tsx @@ -0,0 +1,100 @@ +"use client"; +import { ButtonPrimary } from "components/Buttons"; +import { DiscoverSmall } from "components/Icons/DiscoverSmall"; +import type { Cursor, Post } from "./getReaderFeed"; +import useSWRInfinite from "swr/infinite"; +import { getReaderFeed } from "./getReaderFeed"; +import { useEffect, useRef } from "react"; +import Link from "next/link"; +import { PostListing } from "components/PostListing"; + +export const InboxContent = (props: { + posts: Post[]; + nextCursor: Cursor | null; +}) => { + const getKey = ( + pageIndex: number, + previousPageData: { + posts: Post[]; + nextCursor: Cursor | null; + } | null, + ) => { + // Reached the end + if (previousPageData && !previousPageData.nextCursor) return null; + + // First page, we don't have previousPageData + if (pageIndex === 0) return ["reader-feed", null] as const; + + // Add the cursor to the key + return ["reader-feed", previousPageData?.nextCursor] as const; + }; + + const { data, size, setSize, isValidating } = useSWRInfinite( + getKey, + ([_, cursor]) => getReaderFeed(cursor), + { + fallbackData: [{ posts: props.posts, nextCursor: props.nextCursor }], + revalidateFirstPage: false, + }, + ); + + const loadMoreRef = useRef(null); + + // Set up intersection observer to load more when trigger element is visible + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + if (entries[0].isIntersecting && !isValidating) { + const hasMore = data && data[data.length - 1]?.nextCursor; + if (hasMore) { + setSize(size + 1); + } + } + }, + { threshold: 0.1 }, + ); + + if (loadMoreRef.current) { + observer.observe(loadMoreRef.current); + } + + return () => observer.disconnect(); + }, [data, size, setSize, isValidating]); + + const allPosts = data ? data.flatMap((page) => page.posts) : []; + + if (allPosts.length === 0 && !isValidating) return ; + + return ( +
+ {allPosts.map((p) => ( + + ))} + {/* Trigger element for loading more posts */} + + ); +}; + +export const ReaderEmpty = () => { + return ( +
+ Nothing to read yet…
+ Subscribe to publications and find their posts here! + + + Discover Publications + + +
+ ); +}; diff --git a/app/(home-pages)/reader/LocalContent.tsx b/app/(home-pages)/reader/LocalContent.tsx new file mode 100644 index 00000000..7061c545 --- /dev/null +++ b/app/(home-pages)/reader/LocalContent.tsx @@ -0,0 +1,9 @@ +"use client"; + +export const LocalContent = () => { + return ( +
+ Nothing here yet… +
+ ); +};