diff --git a/src/components/Explore/index.tsx b/src/components/Explore/index.tsx index 0fe218c9..d46bd6ce 100644 --- a/src/components/Explore/index.tsx +++ b/src/components/Explore/index.tsx @@ -6,15 +6,50 @@ import relayInfoService from '@/services/relay-info.service' import { TAwesomeRelayCollection } from '@/types' import { useEffect, useState } from 'react' import RelaySimpleInfo, { RelaySimpleInfoSkeleton } from '../RelaySimpleInfo' +import logger from '@/lib/logger' export default function Explore() { const [collections, setCollections] = useState(null) + const [error, setError] = useState(null) useEffect(() => { - relayInfoService.getAwesomeRelayCollections().then(setCollections) + let cancelled = false + let timeoutId: ReturnType | null = null + + // Add timeout to prevent hanging forever + timeoutId = setTimeout(() => { + if (!cancelled) { + logger.warn('[Explore] Timeout loading relay collections after 10 seconds') + setError('Timeout loading relay collections') + setCollections([]) // Set empty array to stop showing skeletons + } + }, 10000) // 10 second timeout + + logger.debug('[Explore] Fetching awesome relay collections') + relayInfoService.getAwesomeRelayCollections() + .then((data) => { + if (!cancelled) { + if (timeoutId) clearTimeout(timeoutId) + logger.debug('[Explore] Loaded collections', { count: data?.length || 0 }) + setCollections(data || []) + } + }) + .catch((err) => { + if (!cancelled) { + if (timeoutId) clearTimeout(timeoutId) + logger.error('[Explore] Error loading collections', { error: err }) + setError(err instanceof Error ? err.message : 'Failed to load relay collections') + setCollections([]) // Set empty array to stop showing skeletons + } + }) + + return () => { + cancelled = true + if (timeoutId) clearTimeout(timeoutId) + } }, []) - if (!collections) { + if (collections === null) { return (
@@ -27,6 +62,38 @@ export default function Explore() { ) } + if (error) { + return ( +
+
Error: {error}
+ +
+ ) + } + + if (collections.length === 0) { + return ( +
+ No relay collections available +
+ ) + } + return (
{collections.map((collection) => ( diff --git a/src/components/NoteList/index.tsx b/src/components/NoteList/index.tsx index 9b9b6b54..694ada81 100644 --- a/src/components/NoteList/index.tsx +++ b/src/components/NoteList/index.tsx @@ -218,12 +218,6 @@ const NoteList = forwardRef( setHasMore(true) consecutiveEmptyRef.current = 0 // Reset counter on refresh - if (showKinds.length === 0) { - setLoading(false) - setHasMore(false) - return () => {} - } - const { closer, timelineKey } = await client.subscribeTimeline( subRequests.map(({ urls, filter }) => ({ urls, @@ -231,7 +225,8 @@ const NoteList = forwardRef( ? { ...filter, limit: filter.limit ?? (areAlgoRelays ? ALGO_LIMIT : LIMIT) } : { ...filter, - kinds: showKinds, + // If showKinds is empty, default to kind 1 (ShortTextNote) only + kinds: showKinds.length > 0 ? showKinds : [kinds.ShortTextNote], limit: areAlgoRelays ? ALGO_LIMIT : LIMIT } })), diff --git a/src/services/client.service.ts b/src/services/client.service.ts index 335f72af..d7ec2d1c 100644 --- a/src/services/client.service.ts +++ b/src/services/client.service.ts @@ -1211,10 +1211,11 @@ class ClientService extends EventTarget { } } - // CRITICAL FIX: If no cached events (or all were too old), use a recent timestamp - // This prevents the feed from showing 15+ hour old events when relays are slow - if (!since && needSort) { - // Default to last 24 hours if no recent cached events + // CRITICAL FIX: Only set since parameter if caching is enabled + // When useCache is false, we want to stream raw from relays without time restrictions + // This allows relay feeds to show all available events, not just recent ones + if (!since && needSort && useCache) { + // Default to last 24 hours if no recent cached events (only when caching is enabled) // This ensures we get recent content even if relays are slow const oneDayAgo = dayjs().subtract(24, 'hours').unix() since = oneDayAgo