From 89bc522ff7889a6551c0fe4a684bf178f114f41b Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sun, 22 Mar 2026 23:21:51 -0500 Subject: [PATCH] feat: render quoted badge definitions as compact showcase instead of link preview Kind 30009 badge definition embeds now show a smaller version of the badge showcase (centered image with rotating light rays, name, and description) instead of the generic link-preview card with cover image. --- src/components/EmbeddedNaddr.tsx | 101 ++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-) diff --git a/src/components/EmbeddedNaddr.tsx b/src/components/EmbeddedNaddr.tsx index 52b1e1f8..ee1d2cd4 100644 --- a/src/components/EmbeddedNaddr.tsx +++ b/src/components/EmbeddedNaddr.tsx @@ -1,12 +1,13 @@ import { useMemo } from 'react'; import { Link, useNavigate } from 'react-router-dom'; import { nip19 } from 'nostr-tools'; +import { Award, MessageSquareOff } from 'lucide-react'; import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'; import { getAvatarShape } from '@/lib/avatarShape'; import { Skeleton } from '@/components/ui/skeleton'; import { EmojifiedText } from '@/components/CustomEmoji'; import { NoteCard } from '@/components/NoteCard'; -import { MessageSquareOff } from 'lucide-react'; +import { parseBadgeDefinition } from '@/components/BadgeContent'; import { useAddrEvent, type AddrCoords } from '@/hooks/useEvent'; import { useAuthor } from '@/hooks/useAuthor'; import { genUserName } from '@/lib/genUserName'; @@ -80,9 +81,107 @@ export function EmbeddedNaddr({ addr, className }: EmbeddedNaddrProps) { ); } + // Badge definitions get a compact showcase instead of a link-preview card + if (event.kind === 30009) { + return ; + } + return ; } +/** Compact badge showcase for kind 30009 embeds — smaller version of the feed BadgeContent. */ +function EmbeddedBadgeCard({ event, className }: { event: NostrEvent; className?: string }) { + const navigate = useNavigate(); + const badge = useMemo(() => parseBadgeDefinition(event), [event]); + + const naddrId = useMemo(() => { + const dTag = event.tags.find(([n]) => n === 'd')?.[1] ?? ''; + return nip19.naddrEncode({ kind: event.kind, pubkey: event.pubkey, identifier: dTag }); + }, [event]); + + if (!badge) return ; + + const heroImage = badge.image + ?? badge.thumbs.find((t) => t.dimensions === '512x512')?.url + ?? badge.thumbs[0]?.url; + + return ( +
{ + e.stopPropagation(); + navigate(`/${naddrId}`); + }} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + e.stopPropagation(); + navigate(`/${naddrId}`); + } + }} + > + {/* Compact badge showcase */} +
+ {/* Rotating light rays — scaled down from the feed version */} + +
+ ); +} + function EmbeddedNaddrCard({ event, className }: { event: NostrEvent; className?: string }) { const navigate = useNavigate(); const author = useAuthor(event.pubkey);