diff --git a/src/components/PostItem.tsx b/src/components/PostItem.tsx index 0af0463..9e99e23 100644 --- a/src/components/PostItem.tsx +++ b/src/components/PostItem.tsx @@ -1,11 +1,13 @@ import { Post } from '../model/posts/posts.ts' import { Link } from 'react-router' +import { useEffect, useState } from 'react' interface PostItemProps { post: Post + index: number } -export default function PostItem({ post }: PostItemProps) { +export default function PostItem({ post, index }: PostItemProps) { const formattedDate = post.createdAt.toLocaleString('en-US', { year: 'numeric', month: 'short', @@ -14,8 +16,23 @@ export default function PostItem({ post }: PostItemProps) { minute: '2-digit', }) + const [visible, setVisible] = useState(false) + + useEffect(() => { + const timeout = setTimeout(() => setVisible(true)) + return () => clearTimeout(timeout) + }, []) + + const opacity = visible ? 'opacity-100' : 'opacity-0' + + const delayMs = index * 100 + return ( -
+
@{post.authorName} diff --git a/src/components/PostsList.tsx b/src/components/PostsList.tsx index 78e1416..6b10cce 100644 --- a/src/components/PostsList.tsx +++ b/src/components/PostsList.tsx @@ -2,14 +2,18 @@ import { Post } from '../model/posts/posts.ts' import PostItem from './PostItem' interface PostsFeedProps { - posts: Post[] + pages: Post[][] } -export default function PostsList({ posts }: PostsFeedProps) { +export default function PostsList({ pages }: PostsFeedProps) { + return
{pages.map(renderPage)}
+} + +function renderPage(posts: Post[]) { return (
- {posts.map((post) => ( - + {posts.map((post, idx) => ( + ))}
) diff --git a/src/pages/AuthorPage.tsx b/src/pages/AuthorPage.tsx index 067c4e3..14f7aed 100644 --- a/src/pages/AuthorPage.tsx +++ b/src/pages/AuthorPage.tsx @@ -2,7 +2,6 @@ import { useCallback } from 'react' import { useParams } from 'react-router' import { loadPostsForAuthor } from '../api/api.ts' import { Post } from '../model/posts/posts.ts' -import './FeedView.css' import FeedView from './FeedView.tsx' export default function AuthorPage() { diff --git a/src/pages/FeedView.css b/src/pages/FeedView.css deleted file mode 100644 index 3ef31cc..0000000 --- a/src/pages/FeedView.css +++ /dev/null @@ -1,6 +0,0 @@ -@media (width >= 48rem) { - main { - display: grid; - grid-template-columns: 1.618fr 1fr; - } -} diff --git a/src/pages/FeedView.tsx b/src/pages/FeedView.tsx index 58ba097..40f2b00 100644 --- a/src/pages/FeedView.tsx +++ b/src/pages/FeedView.tsx @@ -1,7 +1,6 @@ import { Post } from '../model/posts/posts.ts' import PostsList from '../components/PostsList.tsx' import { useCallback, useRef, useState } from 'react' -import './FeedView.css' import { useIntersectionLoad } from '../hooks/useIntersectionLoad.ts' const PageSize = 20 @@ -12,10 +11,7 @@ interface FeedViewProps { export default function FeedView({ loadPosts }: FeedViewProps) { const [pages, setPages] = useState([]) - const posts = pages.flat() - const [hasMore, setHasMore] = useState(true) - const [isLoading, setIsLoading] = useState(false) const cursor = useRef(null) const loading = useRef(false) @@ -24,7 +20,6 @@ export default function FeedView({ loadPosts }: FeedViewProps) { const loadNextPage = useCallback(async () => { if (loading.current || !hasMore) return loading.current = true - setIsLoading(true) try { const delay = new Promise((resolve) => setTimeout(resolve, 500)) @@ -35,27 +30,16 @@ export default function FeedView({ loadPosts }: FeedViewProps) { setPages((prev) => [...prev, page]) } finally { loading.current = false - setIsLoading(false) } }, [loadPosts, hasMore]) useIntersectionLoad(loadNextPage, sentinelRef) return ( -
-
- - {isLoading && ( -
- -
- )} +
+
+
) } - -// Spinner component -const Spinner = () => ( -
-) diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index 56a7252..70b8910 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -1,6 +1,5 @@ import { useCallback } from 'react' import { Post } from '../model/posts/posts.ts' -import './FeedView.css' import { loadPublicFeed } from '../api/api.ts' import FeedView from './FeedView.tsx'