diff --git a/src/components/TrendingNotes/index.tsx b/src/components/TrendingNotes/index.tsx index acea639c..f1206a8b 100644 --- a/src/components/TrendingNotes/index.tsx +++ b/src/components/TrendingNotes/index.tsx @@ -1,92 +1,27 @@ -import NoteCard, { NoteCardLoadingSkeleton } from '@/components/NoteCard' -import { getReplaceableCoordinateFromEvent, isReplaceableEvent } from '@/lib/event' -import { useDeletedEvent } from '@/providers/DeletedEventProvider' -import { useUserTrust } from '@/providers/UserTrustProvider' -import client from '@/services/client.service' -import { NostrEvent } from 'nostr-tools' -import { useEffect, useMemo, useRef, useState } from 'react' +import { TRENDING_NOTES_RELAY_URLS } from '@/constants' +import { simplifyUrl } from '@/lib/url' import { useTranslation } from 'react-i18next' +import NormalFeed from '../NormalFeed' -const SHOW_COUNT = 10 +const RESOURCE_DESCRIPTION = TRENDING_NOTES_RELAY_URLS.map((url) => simplifyUrl(url)).join(', ') export default function TrendingNotes() { const { t } = useTranslation() - const { isEventDeleted } = useDeletedEvent() - const { hideUntrustedNotes, isUserTrusted } = useUserTrust() - const [trendingNotes, setTrendingNotes] = useState([]) - const [showCount, setShowCount] = useState(10) - const [loading, setLoading] = useState(true) - const bottomRef = useRef(null) - const filteredEvents = useMemo(() => { - const idSet = new Set() - - return trendingNotes.slice(0, showCount).filter((evt) => { - if (isEventDeleted(evt)) return false - if (hideUntrustedNotes && !isUserTrusted(evt.pubkey)) return false - - const id = isReplaceableEvent(evt.kind) ? getReplaceableCoordinateFromEvent(evt) : evt.id - if (idSet.has(id)) { - return false - } - idSet.add(id) - return true - }) - }, [trendingNotes, hideUntrustedNotes, showCount, isEventDeleted]) - - useEffect(() => { - const fetchTrendingPosts = async () => { - setLoading(true) - const events = await client.fetchTrendingNotes() - setTrendingNotes(events) - setLoading(false) - } - - fetchTrendingPosts() - }, []) - - useEffect(() => { - if (showCount >= trendingNotes.length) return - - const options = { - root: null, - rootMargin: '10px', - threshold: 0.1 - } - - const observerInstance = new IntersectionObserver((entries) => { - if (entries[0].isIntersecting) { - setShowCount((prev) => prev + SHOW_COUNT) - } - }, options) - - const currentBottomRef = bottomRef.current - - if (currentBottomRef) { - observerInstance.observe(currentBottomRef) - } - - return () => { - if (observerInstance && currentBottomRef) { - observerInstance.unobserve(currentBottomRef) - } - } - }, [loading, trendingNotes, showCount]) return ( -
-
- {t('Trending Notes')} -
- {filteredEvents.map((event) => ( - - ))} - {showCount < trendingNotes.length || loading ? ( -
- +
+
+
+ {t('Trending Notes')} + + ({RESOURCE_DESCRIPTION}) +
- ) : ( -
{t('no more notes')}
- )} +
+
) } diff --git a/src/constants.ts b/src/constants.ts index 6067094a..e12111b7 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -65,6 +65,8 @@ export const BIG_RELAY_URLS = [ export const SEARCHABLE_RELAY_URLS = ['wss://relay.nostr.band/', 'wss://search.nos.today/'] +export const TRENDING_NOTES_RELAY_URLS = ['wss://trending.relays.land/'] + export const GROUP_METADATA_EVENT_KIND = 39000 export const ExtendedKind = { diff --git a/src/services/client.service.ts b/src/services/client.service.ts index 442a0e1e..01af08ed 100644 --- a/src/services/client.service.ts +++ b/src/services/client.service.ts @@ -24,9 +24,7 @@ import { matchFilters, Event as NEvent, nip19, - Relay, SimplePool, - validateEvent, VerifiedEvent } from 'nostr-tools' import { AbstractRelay } from 'nostr-tools/abstract-relay' @@ -799,39 +797,6 @@ class ClientService extends EventTarget { return this.eventDataLoader.load(id) } - async fetchTrendingNotes() { - if (this.trendingNotesCache) { - return this.trendingNotesCache - } - - try { - const response = await fetch('https://api.nostr.band/v0/trending/notes') - const data = await response.json() - const events: NEvent[] = [] - for (const note of data.notes ?? []) { - if (validateEvent(note.event)) { - events.push(note.event) - this.addEventToCache(note.event) - if (note.relays?.length) { - note.relays.map((r: string) => { - try { - const relay = new Relay(r) - this.trackEventSeenOn(note.event.id, relay) - } catch { - return null - } - }) - } - } - } - this.trendingNotesCache = events - return this.trendingNotesCache - } catch (error) { - console.error('fetchTrendingNotes error', error) - return [] - } - } - addEventToCache(event: NEvent) { this.eventDataLoader.prime(event.id, Promise.resolve(event)) if (isReplaceableEvent(event.kind)) {