From 01a2ecd2b636c5cf4d0fdc743068ba3d2fbee2e3 Mon Sep 17 00:00:00 2001 From: highperfocused Date: Sat, 22 Nov 2025 00:55:20 +0100 Subject: [PATCH] Add MinimalPictureCard component for displaying images from Nostr events --- src/components/feed/MinimalPictureCard.tsx | 61 ++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/components/feed/MinimalPictureCard.tsx diff --git a/src/components/feed/MinimalPictureCard.tsx b/src/components/feed/MinimalPictureCard.tsx new file mode 100644 index 0000000..e67d148 --- /dev/null +++ b/src/components/feed/MinimalPictureCard.tsx @@ -0,0 +1,61 @@ +import type { NostrEvent } from '@nostrify/nostrify'; +import { AspectRatio } from '@/components/ui/aspect-ratio'; + +interface MinimalPictureCardProps { + event: NostrEvent; +} + +interface ImageMeta { + url: string; + alt?: string; +} + +function parseImetaTags(event: NostrEvent): ImageMeta[] { + const images: ImageMeta[] = []; + + for (const tag of event.tags) { + if (tag[0] === 'imeta') { + const imageMeta: ImageMeta = { url: '' }; + + for (let i = 1; i < tag.length; i++) { + const part = tag[i]; + if (part.startsWith('url ')) { + imageMeta.url = part.substring(4); + } else if (part.startsWith('alt ')) { + imageMeta.alt = part.substring(4); + } + } + + if (imageMeta.url) { + images.push(imageMeta); + } + } + } + + return images; +} + +export function MinimalPictureCard({ event }: MinimalPictureCardProps) { + const images = parseImetaTags(event); + const title = event.tags.find(([name]) => name === 'title')?.[1] || ''; + + if (images.length === 0) { + return null; + } + + // Use the first image only + const firstImage = images[0]; + + return ( +
+ + {firstImage.alt + +
+ ); +}