import { Clock, Loader2 } from "lucide-react"; import { useCallback, useEffect, useState } from "react"; import { type GetFeedParams, getFeed } from "../../api/client"; import Card from "../../components/common/Card"; import { EmptyState } from "../../components/ui"; import type { AnnotationItem } from "../../types"; const LIMIT = 50; export interface FeedItemsProps extends Omit< GetFeedParams, "limit" | "offset" > { layout: "list" | "mosaic"; emptyMessage: string; } export default function FeedItems({ creator, source, tag, type, motivation, emptyMessage, layout, }: FeedItemsProps) { const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [loadingMore, setLoadingMore] = useState(false); const [hasMore, setHasMore] = useState(false); const [offset, setOffset] = useState(0); useEffect(() => { let cancelled = false; getFeed({ type, motivation, tag, creator, source, limit: LIMIT, offset: 0 }) .then((data) => { if (cancelled) return; const fetched = data.items; setItems(fetched); setHasMore(data.hasMore); setOffset(data.fetchedCount); setLoading(false); }) .catch((e) => { if (cancelled) return; console.error(e); setItems([]); setHasMore(false); setLoading(false); }); return () => { cancelled = true; }; }, [type, motivation, tag, creator, source]); const loadMore = useCallback(async () => { setLoadingMore(true); try { const data = await getFeed({ type, motivation, tag, creator, source, limit: LIMIT, offset, }); const fetched = data?.items || []; setItems((prev) => [...prev, ...fetched]); setHasMore(data.hasMore); setOffset((prev) => prev + data.fetchedCount); } catch (e) { console.error(e); } finally { setLoadingMore(false); } }, [type, motivation, tag, creator, source, offset]); const handleDelete = (uri: string) => { setItems((prev) => prev.filter((i) => i.uri !== uri)); }; if (loading) { return (

Loading...

); } if (items.length === 0) { return ( } title="Nothing here yet" message={emptyMessage} /> ); } const loadMoreButton = hasMore && (
); if (layout === "mosaic") { return ( <>
{items.map((item) => (
))}
{loadMoreButton} ); } return ( <>
{items.map((item) => ( ))}
{loadMoreButton} ); }