diff --git a/src/lib/components/content/EmbeddedEvent.svelte b/src/lib/components/content/EmbeddedEvent.svelte index 013f50c..98a9e63 100644 --- a/src/lib/components/content/EmbeddedEvent.svelte +++ b/src/lib/components/content/EmbeddedEvent.svelte @@ -5,7 +5,7 @@ import { nip19 } from 'nostr-tools'; import type { NostrEvent } from '../../types/nostr.js'; import { stripMarkdown } from '../../services/text-utils.js'; - import { goto } from '$app/navigation'; + import ProfileBadge from '../layout/ProfileBadge.svelte'; interface Props { eventId: string; // Can be hex, note, nevent, naddr @@ -40,11 +40,37 @@ } else if (decoded.type === 'nevent' && decoded.data && typeof decoded.data === 'object' && 'id' in decoded.data) { hexId = String(decoded.data.id); } else if (decoded.type === 'naddr' && decoded.data && typeof decoded.data === 'object') { - // For naddr, we need to fetch by kind+pubkey+d - // This is more complex, for now just try to get the identifier - console.warn('naddr fetching not fully implemented'); - error = true; - return; + // For naddr, fetch by kind+pubkey+d tag + const naddrData = decoded.data as { kind: number; pubkey: string; identifier?: string; relays?: string[] }; + if (naddrData.kind && naddrData.pubkey) { + const dTag = naddrData.identifier || ''; + const threadRelays = relayManager.getThreadReadRelays(); + const feedRelays = relayManager.getFeedReadRelays(); + const allRelays = [...new Set([...threadRelays, ...feedRelays, ...(naddrData.relays || [])])]; + + // Fetch parameterized replaceable event + const filter: any = { + kinds: [naddrData.kind], + authors: [naddrData.pubkey], + '#d': [dTag], + limit: 1 + }; + + const events = await nostrClient.fetchEvents([filter], allRelays, { useCache: true, cacheResults: true }); + if (events.length > 0) { + event = events[0]; + loading = false; + return; + } else { + error = true; + loading = false; + return; + } + } else { + error = true; + loading = false; + return; + } } } catch (e) { console.error('Failed to decode event ID:', e); @@ -103,14 +129,19 @@ return preview.length < event.content.length ? preview + '...' : preview; } - function getThreadUrl(): string { - if (!event) return '#'; - return `/thread/${event.id}`; - } - function handleClick(e: MouseEvent) { e.preventDefault(); - goto(getThreadUrl()); + if (!event) return; + + // Dispatch custom event on window to open in side-panel + // Parent components (like FeedPage, ThreadList) listen for this event on window + const openEvent = new CustomEvent('openEventInDrawer', { + detail: { event }, + bubbles: true, + cancelable: true + }); + + window.dispatchEvent(openEvent); } @@ -130,12 +161,16 @@ {/if}
{/if} @@ -184,6 +219,14 @@ gap: 0.5rem; } + .embedded-event-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 1rem; + flex-wrap: wrap; + } + .embedded-event-title { font-weight: 600; font-size: 1.125rem; @@ -216,16 +259,6 @@ color: var(--fog-dark-text, #cbd5e1); } - .embedded-event-link { - font-size: 0.875rem; - color: var(--fog-accent, #64748b); - text-decoration: none; - margin-top: 0.25rem; - } - - .embedded-event-link:hover { - text-decoration: underline; - } .embedded-event.loading, .embedded-event.error { diff --git a/src/lib/components/content/MarkdownRenderer.svelte b/src/lib/components/content/MarkdownRenderer.svelte index 8b82fda..60c5aed 100644 --- a/src/lib/components/content/MarkdownRenderer.svelte +++ b/src/lib/components/content/MarkdownRenderer.svelte @@ -4,6 +4,7 @@ import { findNIP21Links, parseNIP21 } from '../../services/nostr/nip21-parser.js'; import { nip19 } from 'nostr-tools'; import ProfileBadge from '../layout/ProfileBadge.svelte'; + import EmbeddedEvent from './EmbeddedEvent.svelte'; import { mountComponent } from './mount-component-action.js'; interface Props { @@ -41,6 +42,19 @@ return null; } + // Extract event identifier from note, nevent, or naddr + // Returns the bech32 string (note1..., nevent1..., naddr1...) which EmbeddedEvent can decode + function getEventIdFromNIP21(parsed: ReturnType