expo-popcore-app/hooks/useWorksList.ts

96 lines
2.7 KiB
TypeScript

import { useState, useCallback } from 'react'
import type { WorkItem } from '@/components/WorksGallery'
interface UseWorksListResult {
works: WorkItem[]
loading: boolean
error: string | null
refreshing: boolean
hasMore: boolean
loadMore: () => Promise<void>
refresh: () => Promise<void>
}
const PAGE_SIZE = 20
// TODO: Replace with actual API call when backend is ready
const mockFetchWorks = async (page: number): Promise<WorkItem[]> => {
await new Promise(resolve => setTimeout(resolve, 800))
if (page > 2) return []
const baseData: WorkItem[] = [
{ id: 1, date: new Date(2025, 10, 28), duration: '00:05', category: '萌宠' },
{ id: 2, date: new Date(2025, 10, 28), duration: '00:05', category: '写真' },
{ id: 3, date: new Date(2025, 10, 27), duration: '00:05', category: '萌宠' },
{ id: 4, date: new Date(2025, 10, 27), duration: '00:05', category: '合拍' },
{ id: 5, date: new Date(2025, 10, 27), duration: '00:05', category: '写真' },
{ id: 6, date: new Date(2025, 10, 27), duration: '00:05', category: '萌宠' },
{ id: 7, date: new Date(2025, 10, 26), duration: '00:05', category: '合拍' },
{ id: 8, date: new Date(2025, 10, 26), duration: '00:05', category: '写真' },
]
return baseData.map(item => ({
...item,
id: item.id + (page * PAGE_SIZE),
}))
}
export function useWorksList(): UseWorksListResult {
const [works, setWorks] = useState<WorkItem[]>([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const [refreshing, setRefreshing] = useState(false)
const [page, setPage] = useState(0)
const [hasMore, setHasMore] = useState(true)
const loadWorks = useCallback(async (pageNum: number, isRefresh = false) => {
try {
const data = await mockFetchWorks(pageNum)
if (isRefresh) {
setWorks(data)
} else {
setWorks(prev => [...prev, ...data])
}
setHasMore(data.length === PAGE_SIZE)
setError(null)
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to load works')
}
}, [])
const loadMore = useCallback(async () => {
if (!hasMore || loading) return
const nextPage = page + 1
setPage(nextPage)
await loadWorks(nextPage)
}, [hasMore, loading, page, loadWorks])
const refresh = useCallback(async () => {
setRefreshing(true)
setPage(0)
await loadWorks(0, true)
setRefreshing(false)
}, [loadWorks])
// Initial load
const [initialized, setInitialized] = useState(false)
if (!initialized) {
setInitialized(true)
loadWorks(0).finally(() => setLoading(false))
}
return {
works,
loading,
error,
refreshing,
hasMore,
loadMore,
refresh,
}
}