import { RepostNote, TextNote, useArk } from "@lume/ark"; import { ArrowRightCircleIcon, LoaderIcon } from "@lume/icons"; import { EmptyFeed } from "@lume/ui"; import { FETCH_LIMIT } from "@lume/utils"; import { NDKEvent, NDKKind } from "@nostr-dev-kit/ndk"; import { useInfiniteQuery, useQueryClient } from "@tanstack/react-query"; import { useEffect, useMemo, useRef } from "react"; import { CacheSnapshot, VList, VListHandle } from "virtua"; export function HomeRoute({ colKey }: { colKey: string }) { const ark = useArk(); const ref = useRef(); const cacheKey = `${colKey}-vlist`; const queryClient = useQueryClient(); const [offset, cache] = useMemo(() => { const serialized = sessionStorage.getItem(cacheKey); if (!serialized) return []; return JSON.parse(serialized) as [number, CacheSnapshot]; }, []); const { data, hasNextPage, isLoading, isFetchingNextPage, fetchNextPage } = useInfiniteQuery({ queryKey: [colKey], initialPageParam: 0, queryFn: async ({ signal, pageParam, }: { signal: AbortSignal; pageParam: number; }) => { const events = await ark.getInfiniteEvents({ filter: { kinds: [NDKKind.Text, NDKKind.Repost], authors: ark.account.contacts, }, limit: FETCH_LIMIT, pageParam, signal, }); return events; }, getNextPageParam: (lastPage) => { const lastEvent = lastPage.at(-1); if (!lastEvent) return; return lastEvent.created_at - 1; }, initialData: () => { const queryCacheData = queryClient.getQueryState([colKey]) ?.data as NDKEvent[]; if (queryCacheData) { return { pageParams: [undefined, 1], pages: [queryCacheData], }; } }, select: (data) => data?.pages.flatMap((page) => page), staleTime: 120 * 1000, refetchOnWindowFocus: false, refetchOnMount: false, }); const renderItem = (event: NDKEvent) => { switch (event.kind) { case NDKKind.Text: return ; case NDKKind.Repost: return ; default: return ; } }; useEffect(() => { if (!ref.current) return; const handle = ref.current; if (offset) { handle.scrollTo(offset); } return () => { sessionStorage.setItem( cacheKey, JSON.stringify([handle.scrollOffset, handle.cache]), ); }; }, []); if (!ark.account.contacts.length) { return (
); } return (
{isLoading ? (
) : ( data.map((item) => renderItem(item)) )}
{hasNextPage ? ( ) : null}
); }