From 401d333e0fcb67ee6a6efd192d72fdb035b46110 Mon Sep 17 00:00:00 2001 From: Gigi Date: Sun, 19 Oct 2025 00:58:07 +0200 Subject: [PATCH] fix(explore): logged-out mode relies solely on centralized nostrverse controllers; start controllers even when logged out --- src/App.tsx | 8 +++++++ src/components/Explore.tsx | 49 ++------------------------------------ 2 files changed, 10 insertions(+), 47 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 7c7c59e5..57083fde 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -128,6 +128,14 @@ function AppRoutes({ } }, [activeAccount, relayPool, eventStore, bookmarks.length, bookmarksLoading, contacts.size, contactsLoading, accountManager]) + // Ensure nostrverse controllers run even when logged out + useEffect(() => { + if (relayPool && eventStore) { + nostrverseHighlightsController.start({ relayPool, eventStore }) + nostrverseWritingsController.start({ relayPool, eventStore }) + } + }, [relayPool, eventStore]) + // Manual refresh (for sidebar button) const handleRefreshBookmarks = useCallback(async () => { if (!relayPool || !activeAccount) { diff --git a/src/components/Explore.tsx b/src/components/Explore.tsx index 7abffdce..a6abf245 100644 --- a/src/components/Explore.tsx +++ b/src/components/Explore.tsx @@ -204,53 +204,8 @@ const Explore: React.FC = ({ relayPool, eventStore, settings, acti // If not logged in, only fetch nostrverse content with streaming posts if (!activeAccount) { - const relayUrls = Array.from(relayPool.relays.values()).map(relay => relay.url) - const highlightPromise = fetchNostrverseHighlights(relayPool, 100, eventStore || undefined) - - // Stream posts as they arrive - const postsPromise = fetchNostrverseBlogPosts( - relayPool, - relayUrls, - 50, - eventStore || undefined, - (post) => { - setBlogPosts(prev => { - const dTag = post.event.tags.find(t => t[0] === 'd')?.[1] || '' - const key = `${post.author}:${dTag}` - const existingIndex = prev.findIndex(p => { - const pDTag = p.event.tags.find(t => t[0] === 'd')?.[1] || '' - return `${p.author}:${pDTag}` === key - }) - if (existingIndex >= 0) { - const existing = prev[existingIndex] - if (post.event.created_at <= existing.event.created_at) return prev - const next = [...prev] - next[existingIndex] = post - return next.sort((a, b) => (b.published || b.event.created_at) - (a.published || a.event.created_at)) - } - const next = [...prev, post] - return next.sort((a, b) => (b.published || b.event.created_at) - (a.published || a.event.created_at)) - }) - } - ) - - // When each finishes, merge without blocking initial render - postsPromise.then((finalPosts) => { - setBlogPosts(prev => { - const byKey = new Map() - for (const p of [...prev, ...finalPosts]) { - const dTag = p.event.tags.find(t => t[0] === 'd')?.[1] || '' - const key = `${p.author}:${dTag}` - const existing = byKey.get(key) - if (!existing || p.event.created_at > existing.event.created_at) byKey.set(key, p) - } - return Array.from(byKey.values()).sort((a, b) => (b.published || b.event.created_at) - (a.published || a.event.created_at)) - }) - }).catch(() => {}) - highlightPromise.then((nostriverseHighlights) => { - setHighlights(prev => dedupeHighlightsById([...prev, ...nostriverseHighlights]).sort((a, b) => b.created_at - a.created_at)) - }).catch(() => {}) - // drop through; do not early return so post-login path runs seeding too + // Logged out: rely entirely on centralized controllers; do not fetch here + setLoading(false) } // Seed from in-memory cache if available to avoid empty flash