reactions
This commit is contained in:
parent
48e7094c5e
commit
c21e193fbf
9 changed files with 97 additions and 119 deletions
|
@ -1,36 +1,5 @@
|
|||
import { useCallback, useRef, useState } from 'react'
|
||||
import { Post } from '../posts/posts.ts'
|
||||
import { produce, WritableDraft } from 'immer'
|
||||
|
||||
const PageSize = 20
|
||||
|
||||
export function useFeedViewModel(
|
||||
loadMore: (cursor: string | null, amount: number) => Promise<Post[]>,
|
||||
) {
|
||||
const [pages, setPages] = useState<Post[][]>([])
|
||||
const [hasMore, setHasMore] = useState(true)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
const cursor = useRef<string | null>(null)
|
||||
const loading = useRef(false)
|
||||
|
||||
const loadNextPage = useCallback(async () => {
|
||||
if (loading.current || !hasMore || error) return
|
||||
loading.current = true
|
||||
|
||||
try {
|
||||
const delay = new Promise((resolve) => setTimeout(resolve, 500))
|
||||
const pagePromise = loadMore(cursor.current, PageSize)
|
||||
const [page] = await Promise.all([pagePromise, delay])
|
||||
setHasMore(page.length >= PageSize)
|
||||
cursor.current = page.at(-1)?.postId ?? null
|
||||
setPages((prev) => [...prev, page])
|
||||
} catch (e: unknown) {
|
||||
const err = e as Error
|
||||
setError(err.message)
|
||||
} finally {
|
||||
loading.current = false
|
||||
}
|
||||
}, [loadMore, hasMore, error])
|
||||
|
||||
return { pages, setPages, loadNextPage, error } as const
|
||||
}
|
||||
|
|
|
@ -4,15 +4,14 @@ import { Post } from '../posts/posts.ts'
|
|||
import PostItem from './PostItem.tsx'
|
||||
|
||||
interface FeedViewProps {
|
||||
pages: Post[][]
|
||||
posts: Post[]
|
||||
onLoadMore: () => Promise<void>
|
||||
addReaction: (postId: string, emoji: string) => void
|
||||
clearReaction: (postId: string, emoji: string) => void
|
||||
}
|
||||
|
||||
export default function FeedView({ pages, onLoadMore, addReaction, clearReaction }: FeedViewProps) {
|
||||
export default function FeedView({ posts, onLoadMore, addReaction, clearReaction }: FeedViewProps) {
|
||||
const sentinelRef = useRef<HTMLDivElement | null>(null)
|
||||
const posts = pages.flat()
|
||||
|
||||
useIntersectionLoad(onLoadMore, sentinelRef)
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Post, PostMedia } from '../posts/posts.ts'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
interface PostItemProps {
|
||||
|
@ -31,10 +30,7 @@ export default function PostItem({ post, addReaction, clearReaction }: PostItemP
|
|||
return (
|
||||
<article className={`w-full p-4 ${opacity} transition-opacity duration-500`} key={post.postId}>
|
||||
<div className="text-sm text-gray-500 mb-3">
|
||||
<Link to={`/u/${post.authorName}`} className="text-gray-400 hover:underline mr-2">
|
||||
@{post.authorName}
|
||||
</Link>
|
||||
• {formattedDate}
|
||||
<span className="text-gray-400 mr-2">@{post.authorName}</span>• {formattedDate}
|
||||
</div>
|
||||
|
||||
<div className="text-gray-800 mb-4 whitespace-pre-wrap">{post.content}</div>
|
||||
|
@ -77,10 +73,11 @@ function PostReactions({ post, addReaction, clearReaction }: PostReactionsProps)
|
|||
|
||||
return (
|
||||
<PostReactionButton
|
||||
key={emoji}
|
||||
emoji={emoji}
|
||||
didReact={didReact}
|
||||
count={count}
|
||||
onClick={() => onClick()}
|
||||
onClick={onClick}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue