diff --git a/app/src/lib/components/ExternalClientLinks.svelte b/app/src/lib/components/ExternalClientLinks.svelte
new file mode 100644
index 0000000..c8b6af4
--- /dev/null
+++ b/app/src/lib/components/ExternalClientLinks.svelte
@@ -0,0 +1,56 @@
+
+
+
+ In Nostr-Client öffnen (für Threads, Reactions, Teilen):
+
+
+
+
diff --git a/app/src/lib/components/PostView.svelte b/app/src/lib/components/PostView.svelte
index f838d01..b28918b 100644
--- a/app/src/lib/components/PostView.svelte
+++ b/app/src/lib/components/PostView.svelte
@@ -5,6 +5,7 @@
import Reactions from './Reactions.svelte';
import ReplyList from './ReplyList.svelte';
import ReplyComposer from './ReplyComposer.svelte';
+ import ExternalClientLinks from './ExternalClientLinks.svelte';
interface Props {
event: NostrEvent;
@@ -71,6 +72,7 @@
{#if dtag}
+
{/if}
diff --git a/app/src/lib/components/ReplyItem.svelte b/app/src/lib/components/ReplyItem.svelte
index c94a5df..8b8fb27 100644
--- a/app/src/lib/components/ReplyItem.svelte
+++ b/app/src/lib/components/ReplyItem.svelte
@@ -2,6 +2,7 @@
import { onMount } from 'svelte';
import type { NostrEvent, Profile } from '$lib/nostr/loaders';
import { getProfile } from '$lib/nostr/profileCache';
+ import { buildNjumpProfileUrl } from '$lib/nostr/naddr';
interface Props {
event: NostrEvent;
@@ -10,6 +11,7 @@
const date = $derived(new Date(event.created_at * 1000).toLocaleString('de-DE'));
const npubPrefix = $derived(event.pubkey.slice(0, 12) + '…');
+ const profileUrl = $derived(buildNjumpProfileUrl(event.pubkey));
let profile = $state(null);
@@ -25,7 +27,7 @@
-
-
+
{event.content}
@@ -50,6 +52,17 @@
gap: 0.6rem;
align-items: center;
margin-bottom: 0.4rem;
+ color: inherit;
+ text-decoration: none;
+ border-radius: 4px;
+ padding: 2px;
+ margin-left: -2px;
+ }
+ .header:hover {
+ background: var(--code-bg);
+ }
+ .header:hover .name {
+ color: var(--accent);
}
.avatar {
flex: 0 0 32px;
diff --git a/app/src/lib/nostr/naddr.ts b/app/src/lib/nostr/naddr.ts
index f14b874..ce49d38 100644
--- a/app/src/lib/nostr/naddr.ts
+++ b/app/src/lib/nostr/naddr.ts
@@ -32,3 +32,34 @@ export function buildNaddr(args: NaddrArgs): string {
export function buildHablaLink(args: NaddrArgs): string {
return `${HABLA_BASE}${buildNaddr(args)}`;
}
+
+/**
+ * `npub1…`-Bech32-String für einen Pubkey — für Profil-Links außerhalb
+ * der SPA (z. B. njump.me).
+ */
+export function buildNpub(pubkeyHex: string): string {
+ return nip19.npubEncode(pubkeyHex);
+}
+
+/**
+ * njump.me-Profil-URL. Öffnet das Nostr-native Profil-Browser mit
+ * vollständiger Event-Historie.
+ */
+export function buildNjumpProfileUrl(pubkeyHex: string): string {
+ return `https://njump.me/${buildNpub(pubkeyHex)}`;
+}
+
+/**
+ * Liste externer Nostr-Clients für „Post öffnen in …"-Links.
+ * Nutzt naddr, damit jeder Client das addressable Event adressieren kann.
+ */
+export function externalClientLinks(
+ args: NaddrArgs
+): { label: string; url: string }[] {
+ const naddr = buildNaddr(args);
+ return [
+ { label: 'Habla', url: `https://habla.news/a/${naddr}` },
+ { label: 'Yakihonne', url: `https://yakihonne.com/article/${naddr}` },
+ { label: 'njump', url: `https://njump.me/${naddr}` }
+ ];
+}