diff --git a/src/lib/components/EventSearch.svelte b/src/lib/components/EventSearch.svelte index 36f67e3..9fe9cac 100644 --- a/src/lib/components/EventSearch.svelte +++ b/src/lib/components/EventSearch.svelte @@ -6,12 +6,15 @@ import { goto } from '$app/navigation'; import type { NDKEvent } from '$lib/utils/nostrUtils'; import RelayDisplay from './RelayDisplay.svelte'; + import { getActiveRelays } from '$lib/ndk'; - const { loading, error, searchValue, onEventFound, event } = $props<{ + const { loading, error, searchValue, dTagValue, onEventFound, onSearchResults, event } = $props<{ loading: boolean; error: string | null; searchValue: string | null; + dTagValue: string | null; onEventFound: (event: NDKEvent) => void; + onSearchResults: (results: NDKEvent[]) => void; event: NDKEvent | null; }>(); @@ -27,15 +30,70 @@ } }); + $effect(() => { + if (dTagValue) { + searchByDTag(dTagValue); + } + }); + $effect(() => { foundEvent = event; }); + async function searchByDTag(dTag: string) { + localError = null; + searching = true; + + try { + console.log('[Events] Searching for events with d-tag:', dTag); + const ndk = $ndkInstance; + if (!ndk) { + localError = 'NDK not initialized'; + return; + } + + const filter = { '#d': [dTag] }; + const relaySet = getActiveRelays(ndk); + + // Fetch multiple events with the same d-tag + const events = await ndk.fetchEvents(filter, { closeOnEose: true }, relaySet); + const eventArray = Array.from(events); + + if (eventArray.length === 0) { + localError = `No events found with d-tag: ${dTag}`; + onSearchResults([]); + } else if (eventArray.length === 1) { + // If only one event found, treat it as a single event result + handleFoundEvent(eventArray[0]); + } else { + // Multiple events found, show as search results + console.log(`[Events] Found ${eventArray.length} events with d-tag: ${dTag}`); + onSearchResults(eventArray); + } + } catch (err) { + console.error('[Events] Error searching by d-tag:', err); + localError = 'Error searching for events with this d-tag.'; + onSearchResults([]); + } finally { + searching = false; + } + } + async function searchEvent(clearInput: boolean = true, queryOverride?: string) { localError = null; const query = (queryOverride !== undefined ? queryOverride : searchQuery).trim(); if (!query) return; + // Check if this is a d-tag search + if (query.startsWith('d:')) { + const dTag = query.slice(2).trim(); + if (dTag) { + const encoded = encodeURIComponent(dTag); + goto(`?d=${encoded}`, { replaceState: false, keepFocus: true, noScroll: true }); + return; + } + } + // Only update the URL if this is a manual search if (clearInput) { const encoded = encodeURIComponent(query); @@ -162,7 +220,7 @@
e.key === 'Enter' && searchEvent(true)} /> @@ -197,8 +255,5 @@ {#if !foundEvent && Object.values(relayStatuses).some(s => s === 'pending')}
Searching relays...
{/if} - {#if !foundEvent && !searching && Object.values(relayStatuses).every(s => s !== 'pending')} -
Event not found on any relay.
- {/if}
\ No newline at end of file diff --git a/src/lib/utils/markup/MarkupInfo.md b/src/lib/utils/markup/MarkupInfo.md index daa213a..70eb7fe 100644 --- a/src/lib/utils/markup/MarkupInfo.md +++ b/src/lib/utils/markup/MarkupInfo.md @@ -30,7 +30,7 @@ The **advanced markup parser** includes all features of the basic parser, plus: - **Tables:** Pipe-delimited tables with or without headers - **Footnotes:** `[^1]` or `[^Smith]`, which should appear where the footnote shall be placed, and will be displayed as unique, consecutive numbers - **Footnote References:** `[^1]: footnote text` or `[^Smith]: Smith, Adam. 1984 "The Wiggle Mysteries`, which will be listed in order, at the bottom of the event, with back-reference links to the footnote, and text footnote labels appended -- **Wikilinks:** `[[NIP-54]]` will render as a hyperlink and goes to [NIP-54](./wiki?d=nip-54) +- **Wikilinks:** `[[NIP-54]]` will render as a hyperlink and goes to [NIP-54](./events?d=nip-54) ## Publications and Wikis diff --git a/src/lib/utils/markup/basicMarkupParser.ts b/src/lib/utils/markup/basicMarkupParser.ts index d0d6ff1..a79833b 100644 --- a/src/lib/utils/markup/basicMarkupParser.ts +++ b/src/lib/utils/markup/basicMarkupParser.ts @@ -142,7 +142,7 @@ function replaceWikilinks(text: string): string { return text.replace(/\[\[([^\]|]+)(?:\|([^\]]+))?\]\]/g, (_match, target, label) => { const normalized = normalizeDTag(target.trim()); const display = (label || target).trim(); - const url = `./wiki?d=${normalized}`; + const url = `./events?d=${normalized}`; // Output as a clickable with the [[display]] format and matching link colors return `${display}`; }); diff --git a/src/routes/events/+page.svelte b/src/routes/events/+page.svelte index 9b575ca..20f8cf5 100644 --- a/src/routes/events/+page.svelte +++ b/src/routes/events/+page.svelte @@ -7,11 +7,15 @@ import EventDetails from '$lib/components/EventDetails.svelte'; import RelayActions from '$lib/components/RelayActions.svelte'; import CommentBox from '$lib/components/CommentBox.svelte'; + import { userBadge } from '$lib/snippets/UserSnippets.svelte'; + import { getMatchingTags, toNpub } from '$lib/utils/nostrUtils'; let loading = $state(false); let error = $state(null); let searchValue = $state(null); + let dTagValue = $state(null); let event = $state(null); + let searchResults = $state([]); let profile = $state<{ name?: string; display_name?: string; @@ -27,6 +31,7 @@ function handleEventFound(newEvent: NDKEvent) { event = newEvent; + searchResults = []; if (newEvent.kind === 0) { try { profile = JSON.parse(newEvent.content); @@ -38,10 +43,33 @@ } } + function handleSearchResults(results: NDKEvent[]) { + searchResults = results; + event = null; + profile = null; + } + + function getSummary(event: NDKEvent): string | undefined { + return getMatchingTags(event, 'summary')[0]?.[1]; + } + + function getDeferrelNaddr(event: NDKEvent): string | undefined { + // Look for a 'deferrel' tag, e.g. ['deferrel', 'naddr1...'] + return getMatchingTags(event, 'deferrel')[0]?.[1]; + } + $effect(() => { const id = $page.url.searchParams.get('id'); + const dTag = $page.url.searchParams.get('d'); + if (id !== searchValue) { searchValue = id; + dTagValue = null; + } + + if (dTag !== dTagValue) { + dTagValue = dTag; + searchValue = null; } }); @@ -60,9 +88,19 @@

Use this page to view any event (npub, nprofile, nevent, naddr, note, pubkey, or eventID). + You can also search for events by d-tag using the format "d:tag-name".

- + + {#if event} @@ -77,5 +115,57 @@ {/if} {/if} + + {#if searchResults.length > 0} +
+ + Search Results for d-tag: "{dTagValue}" ({searchResults.length} events) + +
+ {#each searchResults as result, index} + + {/each} +
+
+ {/if}