diff --git a/src/components/thread/ThreadView.tsx b/src/components/thread/ThreadView.tsx index 711ee3c..cadfb30 100644 --- a/src/components/thread/ThreadView.tsx +++ b/src/components/thread/ThreadView.tsx @@ -4,7 +4,7 @@ import { useAutoResize } from "../../hooks/useAutoResize"; import { useUIStore } from "../../stores/ui"; import { useUserStore } from "../../stores/user"; import { useMuteStore } from "../../stores/mute"; -import { fetchNoteById, fetchThreadEvents, fetchAncestors, publishReply, getNDK, ensureConnected, batchFetchProfileAges } from "../../lib/nostr"; +import { fetchNoteById, fetchThreadEvents, fetchAncestors, publishReply, getNDK, ensureConnected } from "../../lib/nostr"; import { buildThreadTree, getRootEventId } from "../../lib/threadTree"; import type { ThreadNode } from "../../lib/threadTree"; import { debug } from "../../lib/debug"; @@ -106,7 +106,6 @@ export function ThreadView() { const built = buildThreadTree(root.id, allEvents); setTree(built); - batchFetchProfileAges([...new Set(allEvents.map((e) => e.pubkey))]); } catch (err) { debug.error("Failed to load thread:", err); if (!cancelled) setLoadError(`Failed to load: ${err}`); diff --git a/src/lib/nostr/notes.ts b/src/lib/nostr/notes.ts index 1f7016d..09ccde5 100644 --- a/src/lib/nostr/notes.ts +++ b/src/lib/nostr/notes.ts @@ -146,16 +146,16 @@ export async function fetchThreadEvents(rootId: string): Promise { const directEvents = await fetchWithTimeout(instance, directFilter, THREAD_TIMEOUT); const allEvents = new Map(); - for (const e of directEvents) allEvents.set(e.id, e); + // Hard-truncate: relays often ignore `limit` on #e filters, so we enforce it client-side + for (const e of [...directEvents].slice(0, THREAD_EVENT_LIMIT)) allEvents.set(e.id, e); - // Round-trip 2: replies to events in the thread — only if round 1 returned < limit - // Skip deep fetch on large threads to avoid OOM - if (allEvents.size < THREAD_EVENT_LIMIT) { - const knownIds = Array.from(allEvents.keys()).slice(0, 50); // cap #e filter size + // Round-trip 2: only attempt if round 1 was small (skip entirely on big threads) + if (allEvents.size < 50) { + const knownIds = Array.from(allEvents.keys()); if (knownIds.length > 0) { - const deepFilter: NDKFilter = { kinds: [NDKKind.Text], "#e": knownIds, limit: THREAD_EVENT_LIMIT - allEvents.size }; + const deepFilter: NDKFilter = { kinds: [NDKKind.Text], "#e": knownIds, limit: THREAD_EVENT_LIMIT }; const deepEvents = await fetchWithTimeout(instance, deepFilter, THREAD_TIMEOUT); - for (const e of deepEvents) allEvents.set(e.id, e); + for (const e of [...deepEvents].slice(0, THREAD_EVENT_LIMIT - allEvents.size)) allEvents.set(e.id, e); } }