Show kind label with icon in compact embed cards for non-text kinds

Embed cards for non-text kinds (nsites, follow packs, etc.) now show a kind
label line with icon below the title/description, giving context about what
the event is. Previously a quoted nsite just showed 'ditto' with no indication
it was an nsite deployment.
This commit is contained in:
Alex Gleason
2026-03-24 20:53:13 -05:00
parent ae236718e3
commit d94ff90bc7
2 changed files with 38 additions and 4 deletions
+18
View File
@@ -12,6 +12,7 @@ import { useAuthor } from '@/hooks/useAuthor';
import { genUserName } from '@/lib/genUserName';
import { timeAgo } from '@/lib/timeAgo';
import { cn } from '@/lib/utils';
import { EXTRA_KINDS, getKindIcon } from '@/lib/extraKinds';
import type { NostrEvent } from '@nostrify/nostrify';
interface EmbeddedNaddrProps {
@@ -190,6 +191,16 @@ function EmbeddedNaddrCard({ event, className }: { event: NostrEvent; className?
return description.slice(0, MAX_CONTENT_LENGTH).trimEnd() + '…';
}, [description]);
// Kind label for context (e.g. "development" with icon)
const kindMeta = useMemo(() => {
const kindDef = EXTRA_KINDS.find((def) =>
def.subKinds?.some((sub) => sub.kind === event.kind) || def.kind === event.kind
|| def.extraFeedKinds?.includes(event.kind),
);
if (!kindDef) return undefined;
return { label: kindDef.label.toLowerCase(), Icon: getKindIcon(event.kind) };
}, [event.kind]);
return (
<div
className={cn(
@@ -281,6 +292,13 @@ function EmbeddedNaddrCard({ event, className }: { event: NostrEvent; className?
</p>
)}
{/* Kind label for context */}
{kindMeta && (
<p className="flex items-center gap-1 text-xs text-muted-foreground">
{kindMeta.Icon && <kindMeta.Icon className="size-3 shrink-0" />}
{kindMeta.label}
</p>
)}
</div>
</div>
);
+20 -4
View File
@@ -16,6 +16,7 @@ import { timeAgo } from '@/lib/timeAgo';
import { cn } from '@/lib/utils';
import { useAppContext } from '@/hooks/useAppContext';
import { IMAGE_URL_REGEX, IMETA_MEDIA_URL_REGEX, extractVideoUrls, extractAudioUrls } from '@/lib/mediaUrls';
import { EXTRA_KINDS, getKindIcon } from '@/lib/extraKinds';
/** NIP-62 Request to Vanish. */
const VANISH_KIND = 62;
@@ -105,7 +106,7 @@ function EmbeddedNoteCard({
className,
disableHoverCards,
}: {
event: { id: string; pubkey: string; content: string; created_at: number; tags: string[][] };
event: { id: string; kind: number; pubkey: string; content: string; created_at: number; tags: string[][] };
className?: string;
disableHoverCards?: boolean;
}) {
@@ -142,9 +143,18 @@ function EmbeddedNoteCard({
const getTag = (name: string) => event.tags.find(([n]) => n === name)?.[1];
const title = getTag('title') || getTag('name') || getTag('d');
const description = getTag('summary') || getTag('description');
if (!title && !description) return undefined;
return { title, description };
}, [truncatedContent, event.tags]);
// Build a kind label line for context (e.g. "nsite · 31 files")
const kindDef = EXTRA_KINDS.find((def) =>
def.subKinds?.some((sub) => sub.kind === event.kind) || def.kind === event.kind
|| def.extraFeedKinds?.includes(event.kind),
);
const kindLabel = kindDef?.label.toLowerCase();
const KindIcon = getKindIcon(event.kind);
if (!title && !description && !kindLabel) return undefined;
return { title, description, kindLabel, KindIcon };
}, [truncatedContent, event.tags, event.kind]);
// Extract first image for a small thumbnail
const firstImage = useMemo(() => {
@@ -267,6 +277,12 @@ function EmbeddedNoteCard({
{tagMeta.description && (
<p className="text-xs text-muted-foreground leading-relaxed line-clamp-3">{tagMeta.description}</p>
)}
{tagMeta.kindLabel && (
<p className="flex items-center gap-1 text-xs text-muted-foreground">
{tagMeta.KindIcon && <tagMeta.KindIcon className="size-3 shrink-0" />}
{tagMeta.kindLabel}
</p>
)}
</>
) : null}