import { useMemo } from 'react'; import { Link } from 'react-router-dom'; import { nip19 } from 'nostr-tools'; import type { NostrEvent } from '@nostrify/nostrify'; import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'; import { Skeleton } from '@/components/ui/skeleton'; import { EmojifiedText } from '@/components/CustomEmoji'; import { genUserName } from '@/lib/genUserName'; import { timeAgo } from '@/lib/timeAgo'; import { isEventMuted } from '@/lib/muteHelpers'; import { useAuthor } from '@/hooks/useAuthor'; import { useOpenPost } from '@/hooks/useOpenPost'; import { useSortedPosts } from '@/hooks/useTrending'; import { useMuteList } from '@/hooks/useMuteList'; /** Hot posts widget for the right sidebar. */ export function HotPostsWidget() { const { data: rawPosts, isLoading } = useSortedPosts('hot', 5); const { muteItems } = useMuteList(); const posts = useMemo(() => { if (!rawPosts || muteItems.length === 0) return rawPosts; return rawPosts.filter((e) => !isEventMuted(e, muteItems)); }, [rawPosts, muteItems]); if (isLoading) { return (
{Array.from({ length: 3 }).map((_, i) => (
))}
); } if (!posts || posts.length === 0) { return

No hot posts right now.

; } return (
{posts.slice(0, 5).map((event) => ( ))}
View all on Trends
); } /** Compact hot post card for the sidebar widget. */ function HotPostCard({ event }: { event: NostrEvent }) { const author = useAuthor(event.pubkey); const metadata = author.data?.metadata; const displayName = metadata?.name || genUserName(event.pubkey); const encodedId = useMemo(() => nip19.neventEncode({ id: event.id, author: event.pubkey }), [event]); const { onClick: openPost, onAuxClick } = useOpenPost(`/${encodedId}`); const snippet = useMemo(() => { const clean = event.content.replace(/https?:\/\/\S+/g, '').trim(); if (clean.length > 100) return clean.slice(0, 100) + '\u2026'; return clean || '(media)'; }, [event.content]); return ( ); }