fix loading feed
This commit is contained in:
parent
cf5494c15b
commit
95ea2a5f23
4 changed files with 54 additions and 71 deletions
|
@ -1,4 +1,4 @@
|
|||
import { useCallback, useRef, useState } from 'react'
|
||||
import { useRef, useState } from 'react'
|
||||
import { PostsService } from '../posts/postsService.ts'
|
||||
import { useUser } from '../../user/user.ts'
|
||||
import { MediaService } from '../../media/mediaService.ts'
|
||||
|
@ -11,6 +11,7 @@ import { Post } from '../posts/posts.ts'
|
|||
import { produce, WritableDraft } from 'immer'
|
||||
import PostItem from '../components/PostItem.tsx'
|
||||
import { useIntersectionLoad } from '../../../hooks/useIntersectionLoad.ts'
|
||||
import { delay } from '../../../utils/delay.ts'
|
||||
|
||||
interface HomePageProps {
|
||||
postsService: PostsService
|
||||
|
@ -24,13 +25,6 @@ export default function HomePage({ postsService, mediaService }: HomePageProps)
|
|||
useSaveSignupCodeToLocalStorage()
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
|
||||
const fetchPosts = useCallback(
|
||||
async (cursor: string | null, amount: number | null) => {
|
||||
return postsService.loadPublicFeed(cursor, amount)
|
||||
},
|
||||
[postsService],
|
||||
)
|
||||
|
||||
const [posts, setPosts] = useState<Post[]>([])
|
||||
const [hasMore, setHasMore] = useState(true)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
@ -38,56 +32,54 @@ export default function HomePage({ postsService, mediaService }: HomePageProps)
|
|||
const cursor = useRef<string | null>(null)
|
||||
const loading = useRef(false)
|
||||
|
||||
const loadNextPage = useCallback(async () => {
|
||||
const loadNextPage = async () => {
|
||||
if (loading.current || !hasMore || error) return
|
||||
loading.current = true
|
||||
|
||||
try {
|
||||
const delay = new Promise((resolve) => setTimeout(resolve, 500))
|
||||
const pagePromise = fetchPosts(cursor.current, PageSize)
|
||||
const [page] = await Promise.all([pagePromise, delay])
|
||||
setHasMore(page.length >= PageSize)
|
||||
cursor.current = page.at(-1)?.postId ?? null
|
||||
setPosts((prev) => [...prev, ...page])
|
||||
const [{ posts, next }] = await Promise.all([
|
||||
postsService.loadPublicFeed(cursor.current, PageSize),
|
||||
delay(500),
|
||||
])
|
||||
|
||||
setHasMore(posts.length >= PageSize)
|
||||
cursor.current = next
|
||||
setPosts((prev) => [...prev, ...posts])
|
||||
} catch (e: unknown) {
|
||||
const err = e as Error
|
||||
setError(err.message)
|
||||
setError((e as Error).message)
|
||||
} finally {
|
||||
loading.current = false
|
||||
}
|
||||
}, [fetchPosts, hasMore, error])
|
||||
}
|
||||
|
||||
const onCreatePost = useCallback(
|
||||
async (
|
||||
content: string,
|
||||
files: { file: File; width: number; height: number }[],
|
||||
isPublic: boolean,
|
||||
) => {
|
||||
setIsSubmitting(true)
|
||||
if (user == null) throw new Error('Not logged in')
|
||||
try {
|
||||
const media = await Promise.all(
|
||||
files.map(async ({ file, width, height }) => {
|
||||
const { mediaId, url } = await mediaService.uploadImage(file)
|
||||
const onCreatePost = async (
|
||||
content: string,
|
||||
files: { file: File; width: number; height: number }[],
|
||||
isPublic: boolean,
|
||||
) => {
|
||||
setIsSubmitting(true)
|
||||
if (user == null) throw new Error('Not logged in')
|
||||
try {
|
||||
const media = await Promise.all(
|
||||
files.map(async ({ file, width, height }) => {
|
||||
const { mediaId, url } = await mediaService.uploadImage(file)
|
||||
|
||||
return {
|
||||
mediaId,
|
||||
url,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}),
|
||||
)
|
||||
const post = await postsService.createNew(user.id, content, media, isPublic)
|
||||
setPosts((pages) => [post, ...pages])
|
||||
} catch (error) {
|
||||
console.error('Failed to create post:', error)
|
||||
} finally {
|
||||
setIsSubmitting(false)
|
||||
}
|
||||
},
|
||||
[mediaService, postsService, setPosts, user],
|
||||
)
|
||||
return {
|
||||
mediaId,
|
||||
url,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}),
|
||||
)
|
||||
const post = await postsService.createNew(user.id, content, media, isPublic)
|
||||
setPosts((pages) => [post, ...pages])
|
||||
} catch (error) {
|
||||
console.error('Failed to create post:', error)
|
||||
} finally {
|
||||
setIsSubmitting(false)
|
||||
}
|
||||
}
|
||||
|
||||
const isLoggedIn = user != null
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue