import { removeUndefined } from "@snort/shared"; import { NostrEvent, NostrLink, TaggedNostrEvent } from "@snort/system"; import classNames from "classnames"; import { useMemo, useState } from "react"; import { ErrorOrOffline } from "@/Components/ErrorOrOffline"; import Note from "@/Components/Event/EventComponent"; import { DisplayAs, DisplayAsSelector } from "@/Components/Feed/DisplayAsSelector"; import ImageGridItem from "@/Components/Feed/ImageGridItem"; import { useLocale } from "@/Components/IntlProvider/useLocale"; import PageSpinner from "@/Components/PageSpinner"; import { SpotlightThreadModal } from "@/Components/Spotlight/SpotlightThreadModal"; import ShortNote from "@/Components/Trending/ShortNote"; import NostrBandApi from "@/External/NostrBand"; import useCachedFetch from "@/Hooks/useCachedFetch"; import useLogin from "@/Hooks/useLogin"; import useModeration from "@/Hooks/useModeration"; import { System } from "@/system"; export default function TrendingNotes({ count = Infinity, small = false }: { count?: number; small?: boolean }) { const api = new NostrBandApi(); const { lang } = useLocale(); const trendingNotesUrl = api.trendingNotesUrl(lang); const storageKey = `nostr-band-${trendingNotesUrl}`; const { data: trendingNotesData, isLoading, error, } = useCachedFetch<{ notes: Array<{ event: NostrEvent }> }, Array>(trendingNotesUrl, storageKey, data => { return removeUndefined( data.notes.map(a => { const ev = a.event; if (!System.optimizer.schnorrVerify(ev)) { console.error(`Event with invalid sig\n\n${ev}\n\nfrom ${trendingNotesUrl}`); return; } System.HandleEvent(ev as TaggedNostrEvent); return ev; }), ); }); const options = useMemo( () => ({ showFooter: !small, showReactionsLink: !small, showMedia: !small, longFormPreview: !small, truncate: small, showContextMenu: !small, }), [small], ); const login = useLogin(); const displayAsInitial = small ? "list" : login.feedDisplayAs ?? "list"; const [displayAs, setDisplayAs] = useState(displayAsInitial); const { isEventMuted } = useModeration(); const [modalThread, setModalThread] = useState(undefined); if (error && !trendingNotesData) return ; if (isLoading) return ; const filteredAndLimitedPosts = trendingNotesData ? trendingNotesData.filter(a => !isEventMuted(a)).slice(0, count) : []; const renderGrid = () => { return (
{filteredAndLimitedPosts.map(e => ( setModalThread(NostrLink.fromEvent(e))} /> ))}
); }; const renderList = () => { return filteredAndLimitedPosts.map((e, index) => small ? ( ) : ( 5} /> ), ); }; return (
{!small && setDisplayAs(a)} />} {displayAs === "grid" ? renderGrid() : renderList()} {modalThread && ( setModalThread(undefined)} onBack={() => setModalThread(undefined)} /> )}
); }