import { RepostNote, TextNote, useArk } from "@lume/ark"; import { ArrowRightCircleIcon, LoaderIcon } from "@lume/icons"; import { FETCH_LIMIT } from "@lume/utils"; import { NDKEvent, NDKFilter, NDKKind } from "@nostr-dev-kit/ndk"; import { useInfiniteQuery } from "@tanstack/react-query"; import { useEffect, useMemo, useRef } from "react"; import { CacheSnapshot, VList, VListHandle } from "virtua"; export function HomeRoute({ colKey, content, }: { colKey: string; content: string }) { const ark = useArk(); const ref = useRef(); const cacheKey = `${colKey}-vlist`; 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; }) => { let filter: NDKFilter; const parsed: { hashtags: string[]; source: string } = JSON.parse(content); if (parsed.source === "contacts") { filter = { kinds: [NDKKind.Text, NDKKind.Repost], "#t": parsed.hashtags.map((item) => item.replace("#", "")), authors: ark.account.contacts, }; } else { filter = { kinds: [NDKKind.Text, NDKKind.Repost], "#t": parsed.hashtags.map((item) => item.replace("#", "")), }; } const events = await ark.getInfiniteEvents({ filter, limit: FETCH_LIMIT, pageParam, signal, }); return events; }, getNextPageParam: (lastPage) => { const lastEvent = lastPage.at(-1); if (!lastEvent) return; return lastEvent.created_at - 1; }, refetchOnWindowFocus: false, }); const allEvents = useMemo( () => (data ? data.pages.flatMap((page) => page) : []), [data], ); 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]), ); }; }, []); return (
{isLoading ? (
) : ( allEvents.map((item) => renderItem(item)) )}
{hasNextPage ? ( ) : null}
); }