- {#if eventsInView.length === 0}
+
+ {#each Object.entries(relayStatuses) as [relay, status]}
+ {relay}: {status}
+ {/each}
+
+ {#if loading && eventsInView.length === 0}
{#each getSkeletonIds() as id}
{/each}
diff --git a/src/lib/components/PublicationHeader.svelte b/src/lib/components/PublicationHeader.svelte
index dc29d47..9e71f4e 100644
--- a/src/lib/components/PublicationHeader.svelte
+++ b/src/lib/components/PublicationHeader.svelte
@@ -24,7 +24,7 @@
);
let title: string = $derived(event.getMatchingTags('title')[0]?.[1]);
- let author: string = $derived(event.getMatchingTags('author')[0]?.[1] ?? 'unknown');
+ let author: string = $derived(getMatchingTags(event, 'author')[0]?.[1] ?? 'unknown');
let version: string = $derived(event.getMatchingTags('version')[0]?.[1] ?? '1');
let image: string = $derived(event.getMatchingTags('image')[0]?.[1] ?? null);
let authorPubkey: string = $derived(event.getMatchingTags('p')[0]?.[1] ?? null);
diff --git a/src/lib/components/PublicationSection.svelte b/src/lib/components/PublicationSection.svelte
index de23463..6c2586a 100644
--- a/src/lib/components/PublicationSection.svelte
+++ b/src/lib/components/PublicationSection.svelte
@@ -5,6 +5,7 @@
import { TextPlaceholder } from "flowbite-svelte";
import { getContext } from "svelte";
import type { Asciidoctor, Document } from "asciidoctor";
+ import { getMatchingTags } from '$lib/utils/nostrUtils';
let {
address,
@@ -109,7 +110,7 @@
{:then [leafTitle, leafContent, leafHierarchy, publicationType, divergingBranches]}
{#each divergingBranches as [branch, depth]}
- {@render sectionHeading(branch.getMatchingTags('title')[0]?.[1] ?? '', depth)}
+ {@render sectionHeading(getMatchingTags(branch, 'title')[0]?.[1] ?? '', depth)}
{/each}
{#if leafTitle}
{@const leafDepth = leafHierarchy.length - 1}
diff --git a/src/lib/components/RelayActions.svelte b/src/lib/components/RelayActions.svelte
new file mode 100644
index 0000000..666b872
--- /dev/null
+++ b/src/lib/components/RelayActions.svelte
@@ -0,0 +1,243 @@
+
+
+
+
+ {@html searchIcon}
+ Where can I find this event?
+
+
+ {#if $ndkInstance?.activeUser}
+
+ {@html broadcastIcon}
+ {broadcasting ? 'Broadcasting...' : 'Broadcast'}
+
+ {/if}
+
+
+{#if foundRelays.length > 0}
+
+
Found on {foundRelays.length} relay(s):
+
+ {#each foundRelays as relay}
+
+ {/each}
+
+
+{/if}
+
+{#if broadcastSuccess}
+
+ Event broadcast successfully to:
+
+ {#each getConnectedRelays() as relay}
+
+ {/each}
+
+
+{/if}
+
+{#if broadcastError}
+
+ {broadcastError}
+
+{/if}
+
+
+
Found on:
+
+ {#each getEventRelays(event) as relay}
+
+ {/each}
+
+
+
+{#if showRelayModal}
+
+
+
×
+
Relay Search Results
+
+ {#each Object.entries({
+ 'Standard Relays': standardRelays,
+ 'User Relays': Array.from($ndkInstance?.pool?.relays.values() || []).map(r => r.url),
+ 'Fallback Relays': fallbackRelays
+ }) as [groupName, groupRelays]}
+ {#if groupRelays.length > 0}
+
+
+ {groupName}
+
+ {#each groupRelays as relay}
+
+ {/each}
+
+ {/if}
+ {/each}
+
+
+ Close
+
+
+
+{/if}
\ No newline at end of file
diff --git a/src/lib/components/RelayDisplay.svelte b/src/lib/components/RelayDisplay.svelte
new file mode 100644
index 0000000..1161f7c
--- /dev/null
+++ b/src/lib/components/RelayDisplay.svelte
@@ -0,0 +1,59 @@
+
+
+
+
+
+
{ (e.target as HTMLImageElement).src = '/favicon.png'; }}
+ />
+
{relay}
+ {#if showStatus && status}
+ {#if status === 'pending'}
+
+
+
+
+ {:else if status === 'found'}
+
✓
+ {:else}
+
✗
+ {/if}
+ {/if}
+
\ No newline at end of file
diff --git a/src/lib/components/blog/BlogHeader.svelte b/src/lib/components/blog/BlogHeader.svelte
index e264a3e..a91d0a4 100644
--- a/src/lib/components/blog/BlogHeader.svelte
+++ b/src/lib/components/blog/BlogHeader.svelte
@@ -10,7 +10,7 @@
const { rootId, event, onBlogUpdate, active = true } = $props<{ rootId: string, event: NDKEvent, onBlogUpdate?: any, active: boolean }>();
let title: string = $derived(event.getMatchingTags('title')[0]?.[1]);
- let author: string = $derived(event.getMatchingTags('author')[0]?.[1] ?? 'unknown');
+ let author: string = $derived(getMatchingTags(event, 'author')[0]?.[1] ?? 'unknown');
let image: string = $derived(event.getMatchingTags('image')[0]?.[1] ?? null);
let authorPubkey: string = $derived(event.getMatchingTags('p')[0]?.[1] ?? null);
let hashtags: string = $derived(event.getMatchingTags('t') ?? null);
diff --git a/src/lib/components/util/ArticleNav.svelte b/src/lib/components/util/ArticleNav.svelte
index 8d1ee40..b6ac5d7 100644
--- a/src/lib/components/util/ArticleNav.svelte
+++ b/src/lib/components/util/ArticleNav.svelte
@@ -17,7 +17,7 @@
}>();
let title: string = $derived(indexEvent.getMatchingTags('title')[0]?.[1]);
- let author: string = $derived(indexEvent.getMatchingTags('author')[0]?.[1] ?? 'unknown');
+ let author: string = $derived(indexgetMatchingTags(event, 'author')[0]?.[1] ?? 'unknown');
let pubkey: string = $derived(indexEvent.getMatchingTags('p')[0]?.[1] ?? null);
let isLeaf: boolean = $derived(indexEvent.kind === 30041);
diff --git a/src/lib/components/util/Details.svelte b/src/lib/components/util/Details.svelte
index f228e2e..e776e9d 100644
--- a/src/lib/components/util/Details.svelte
+++ b/src/lib/components/util/Details.svelte
@@ -3,25 +3,26 @@
import CardActions from "$components/util/CardActions.svelte";
import Interactions from "$components/util/Interactions.svelte";
import { P } from "flowbite-svelte";
+ import { getMatchingTags } from '$lib/utils/nostrUtils';
// isModal
// - don't show interactions in modal view
// - don't show all the details when _not_ in modal view
let { event, isModal = false } = $props();
- let title: string = $derived(event.getMatchingTags('title')[0]?.[1]);
- let author: string = $derived(event.getMatchingTags('author')[0]?.[1] ?? 'unknown');
- let version: string = $derived(event.getMatchingTags('version')[0]?.[1] ?? '1');
- let image: string = $derived(event.getMatchingTags('image')[0]?.[1] ?? null);
- let originalAuthor: string = $derived(event.getMatchingTags('p')[0]?.[1] ?? null);
- let summary: string = $derived(event.getMatchingTags('summary')[0]?.[1] ?? null);
- let type: string = $derived(event.getMatchingTags('type')[0]?.[1] ?? null);
- let language: string = $derived(event.getMatchingTags('l')[0]?.[1] ?? null);
- let source: string = $derived(event.getMatchingTags('source')[0]?.[1] ?? null);
- let publisher: string = $derived(event.getMatchingTags('published_by')[0]?.[1] ?? null);
- let identifier: string = $derived(event.getMatchingTags('i')[0]?.[1] ?? null);
- let hashtags: [] = $derived(event.getMatchingTags('t') ?? []);
- let rootId: string = $derived(event.getMatchingTags('d')[0]?.[1] ?? null);
+ let title: string = $derived(getMatchingTags(event, 'title')[0]?.[1]);
+ let author: string = $derived(getMatchingTags(event, 'author')[0]?.[1] ?? 'unknown');
+ let version: string = $derived(getMatchingTags(event, 'version')[0]?.[1] ?? '1');
+ let image: string = $derived(getMatchingTags(event, 'image')[0]?.[1] ?? null);
+ let originalAuthor: string = $derived(getMatchingTags(event, 'p')[0]?.[1] ?? null);
+ let summary: string = $derived(getMatchingTags(event, 'summary')[0]?.[1] ?? null);
+ let type: string = $derived(getMatchingTags(event, 'type')[0]?.[1] ?? null);
+ let language: string = $derived(getMatchingTags(event, 'l')[0]?.[1] ?? null);
+ let source: string = $derived(getMatchingTags(event, 'source')[0]?.[1] ?? null);
+ let publisher: string = $derived(getMatchingTags(event, 'published_by')[0]?.[1] ?? null);
+ let identifier: string = $derived(getMatchingTags(event, 'i')[0]?.[1] ?? null);
+ let hashtags: string[] = $derived(getMatchingTags(event, 't').map(tag => tag[1]));
+ let rootId: string = $derived(getMatchingTags(event, 'd')[0]?.[1] ?? null);
let kind = $derived(event.kind);
@@ -67,7 +68,7 @@
{#if hashtags.length}
{#each hashtags as tag}
- #{tag[1]}
+ #{tag}
{/each}
{/if}
diff --git a/src/lib/navigator/EventNetwork/NodeTooltip.svelte b/src/lib/navigator/EventNetwork/NodeTooltip.svelte
index 4aedc8e..2f8d577 100644
--- a/src/lib/navigator/EventNetwork/NodeTooltip.svelte
+++ b/src/lib/navigator/EventNetwork/NodeTooltip.svelte
@@ -7,6 +7,7 @@
@@ -264,190 +53,10 @@
Use this page to view any event (npub, nprofile, nevent, naddr, note, pubkey, or eventID).
-
- e.key === 'Enter' && searchEvent()}
- />
-
- {loading ? 'Searching...' : 'Search'}
-
-
-
- {#if error}
-
- {error}
- {#if searchQuery.trim()}
-
- You can also try viewing this event on
-
Njump .
-
- {/if}
-
- {/if}
-
- {#if event && typeof event.getMatchingTags === 'function'}
-
-
-
- {neventEncode(event, standardRelays)}
-
-
-
-
- {#if event.kind !== 0 && getEventTitle(event)}
-
{getEventTitle(event)}
- {:else if event.kind === 0 && profile && profile.name}
-
{profile.name}
- {/if}
-
- {#if toNpub(event.pubkey)}
- Author: {@render userBadge(toNpub(event.pubkey) as string, profile?.display_name || event.pubkey)}
- {:else}
- Author: {profile?.display_name || event.pubkey}
- {/if}
-
-
- Kind:
- {event.kind}
- ({getEventTypeDisplay(event)})
-
- {#if getEventSummary(event)}
-
-
Summary:
-
{getEventSummary(event)}
-
- {/if}
- {#if getEventHashtags(event).length}
-
-
Tags:
-
- {#each getEventHashtags(event) as tag}
- #{tag}
- {/each}
-
-
- {/if}
-
-
-
-
Content:
- {#if event.kind === 0}
- {#if profile}
-
-
- {#if profile.name}
-
-
Name:
- {profile.name}
-
- {/if}
- {#if profile.display_name}
-
-
Display Name:
- {profile.display_name}
-
- {/if}
- {#if profile.about}
-
-
About:
- {profile.about}
-
- {/if}
- {#if profile.picture}
-
-
Picture:
-
-
-
-
- {/if}
- {#if profile.banner}
-
-
Banner:
-
-
-
-
- {/if}
- {#if profile.website}
-
- {/if}
- {#if profile.lud16}
-
-
Lightning Address:
- {profile.lud16}
-
- {/if}
- {#if profile.nip05}
-
-
NIP-05:
- {profile.nip05}
-
- {/if}
-
-
- {:else}
-
{event.content}
- {/if}
- {:else}
-
- {@html showFullContent ? parsedContent : contentPreview}
- {#if !showFullContent && parsedContent.length > 250}
- showFullContent = true}>Show more
- {/if}
-
- {/if}
-
-
-
- {#if event.tags && event.tags.length}
-
-
Event Tags:
-
- {#each event.tags as tag}
- {@html renderTag(tag)}
- {/each}
-
-
- {/if}
-
-
-
-
- Show Raw Event JSON
-
-
-{JSON.stringify(event.rawEvent(), null, 2)}
-
-
-
-
- {#if !getEventTitle(event) && !event.content}
-
- No title or content available for this event.
-
- {JSON.stringify(event.rawEvent(), null, 2)}
-
-
- {/if}
- {:else if event}
-
Fetched event is not a valid NDKEvent. See console for details.
+
+ {#if event}
+
+
{/if}
diff --git a/src/routes/publication/+page.ts b/src/routes/publication/+page.ts
index e3d6bf5..b100f70 100644
--- a/src/routes/publication/+page.ts
+++ b/src/routes/publication/+page.ts
@@ -3,6 +3,7 @@ import type { Load } from '@sveltejs/kit';
import type { NDKEvent } from '@nostr-dev-kit/ndk';
import { nip19 } from 'nostr-tools';
import { getActiveRelays } from '$lib/ndk';
+import { getMatchingTags } from '$lib/utils/nostrUtils';
/**
* Decodes an naddr identifier and returns a filter object
@@ -96,7 +97,7 @@ export const load: Load = async ({ url, parent }: { url: URL; parent: () => Prom
? await fetchEventById(ndk, id)
: await fetchEventByDTag(ndk, dTag!);
- const publicationType = indexEvent?.getMatchingTags('type')[0]?.[1];
+ const publicationType = getMatchingTags(indexEvent, 'type')[0]?.[1];
const fetchPromise = parser.fetch(indexEvent);
return {