From 91d801cbafedae576813779aed681205f68f1e79 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 5 Jan 2026 09:45:59 +0000 Subject: [PATCH] feat: add website display and filter non-platform tags NIP-89 renderer improvements: - Add getAppWebsite() helper to extract website from content JSON - Display website URL in both feed and detail renderers with external link - Filter out non-platform tags (r, t, client, alt, e, p, a) to prevent garbage display - Remove relay hint display from HandlerRecommendationDetailRenderer - Clean up unused relayHint parameter Fixes the 'r r' tag appearing as a platform by properly excluding common non-platform tags when detecting platform URLs. --- .../ApplicationHandlerDetailRenderer.tsx | 16 ++++++++++++ .../kinds/ApplicationHandlerRenderer.tsx | 15 +++++++++++ .../HandlerRecommendationDetailRenderer.tsx | 22 ++++++---------- src/lib/nip89-helpers.ts | 25 +++++++++++++++++-- 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/src/components/nostr/kinds/ApplicationHandlerDetailRenderer.tsx b/src/components/nostr/kinds/ApplicationHandlerDetailRenderer.tsx index d3473b2..a5fc905 100644 --- a/src/components/nostr/kinds/ApplicationHandlerDetailRenderer.tsx +++ b/src/components/nostr/kinds/ApplicationHandlerDetailRenderer.tsx @@ -5,6 +5,7 @@ import { getSupportedKinds, getPlatformUrls, getHandlerIdentifier, + getAppWebsite, } from "@/lib/nip89-helpers"; import { KindBadge } from "@/components/KindBadge"; import { Badge } from "@/components/ui/badge"; @@ -16,6 +17,7 @@ import { Globe, Smartphone, TabletSmartphone, + ExternalLink, } from "lucide-react"; interface ApplicationHandlerDetailRendererProps { @@ -76,6 +78,7 @@ export function ApplicationHandlerDetailRenderer({ const supportedKinds = getSupportedKinds(event); const platformUrls = getPlatformUrls(event); const identifier = getHandlerIdentifier(event); + const website = getAppWebsite(event); return (
@@ -89,6 +92,19 @@ export function ApplicationHandlerDetailRenderer({

{description}

)} + {/* Website */} + {website && ( + + {website} + + + )} + {/* Metadata Grid */}
{/* Publisher */} diff --git a/src/components/nostr/kinds/ApplicationHandlerRenderer.tsx b/src/components/nostr/kinds/ApplicationHandlerRenderer.tsx index c5bf3a5..987c676 100644 --- a/src/components/nostr/kinds/ApplicationHandlerRenderer.tsx +++ b/src/components/nostr/kinds/ApplicationHandlerRenderer.tsx @@ -7,6 +7,7 @@ import { getAppName, getSupportedKinds, getAvailablePlatforms, + getAppWebsite, } from "@/lib/nip89-helpers"; import { KindBadge } from "@/components/KindBadge"; import { Badge } from "@/components/ui/badge"; @@ -40,6 +41,7 @@ export function ApplicationHandlerRenderer({ event }: BaseEventProps) { const appName = getAppName(event); const supportedKinds = getSupportedKinds(event); const platforms = getAvailablePlatforms(event); + const website = getAppWebsite(event); // Show max 8 kinds in feed view const MAX_KINDS_IN_FEED = 8; @@ -57,6 +59,19 @@ export function ApplicationHandlerRenderer({ event }: BaseEventProps) { {appName} + {/* Website */} + {website && ( + e.stopPropagation()} + > + {website} + + )} + {/* Supported Kinds */} {displayKinds.length > 0 && (
diff --git a/src/components/nostr/kinds/HandlerRecommendationDetailRenderer.tsx b/src/components/nostr/kinds/HandlerRecommendationDetailRenderer.tsx index f20df89..fd6d673 100644 --- a/src/components/nostr/kinds/HandlerRecommendationDetailRenderer.tsx +++ b/src/components/nostr/kinds/HandlerRecommendationDetailRenderer.tsx @@ -45,11 +45,9 @@ function PlatformIcon({ platform }: { platform: string }) { function HandlerCard({ address, platform, - relayHint, }: { address: { kind: number; pubkey: string; identifier: string }; platform?: string; - relayHint?: string; }) { const { addWindow } = useGrimoire(); const handlerEvent = useNostrEvent(address); @@ -142,19 +140,14 @@ function HandlerCard({ )} {/* Recommendation Context */} - {(platform || relayHint) && ( + {platform && (
- {platform && ( -
- Recommended for:{" "} - - {platform} - -
- )} - {relayHint && ( -
Relay hint: {relayHint}
- )} +
+ Recommended for:{" "} + + {platform} + +
)}
@@ -260,7 +253,6 @@ export function HandlerRecommendationDetailRenderer({ key={idx} address={ref.address} platform={ref.platform} - relayHint={ref.relayHint} /> ))}
diff --git a/src/lib/nip89-helpers.ts b/src/lib/nip89-helpers.ts index deb017f..0df2124 100644 --- a/src/lib/nip89-helpers.ts +++ b/src/lib/nip89-helpers.ts @@ -123,14 +123,15 @@ export function getPlatformUrls(event: NostrEvent): Record { } // Also check for any other platform tags + // Exclude common non-platform tags: d, k, r, t, client, etc. + const excludedTags = ["d", "k", "r", "t", "client", "alt", "e", "p", "a"]; for (const tag of event.tags) { const tagName = tag[0]; const tagValue = tag[1]; if ( tagValue && !knownPlatforms.includes(tagName) && - tagName !== "d" && - tagName !== "k" + !excludedTags.includes(tagName) ) { // Could be a custom platform tag if (tagValue.includes("://") || tagValue.includes("")) { @@ -149,6 +150,26 @@ export function getAvailablePlatforms(event: NostrEvent): string[] { return Object.keys(getPlatformUrls(event)); } +/** + * Extract website URL from kind 31990 event content JSON + */ +export function getAppWebsite(event: NostrEvent): string | undefined { + if (event.kind !== 31990 || !event.content) return undefined; + + try { + const metadata = JSON.parse(event.content); + if (metadata && typeof metadata === "object") { + const website = metadata.website; + if (website && typeof website === "string") { + return website; + } + } + } catch { + // Invalid JSON + } + return undefined; +} + /** * Get the d tag identifier from kind 31990 event */