Merge branch 'pr/feat--add-NIP-34-user-grasp-list-rendering(68a54c52)'

This commit is contained in:
Alejandro Gómez
2025-12-22 22:32:56 +01:00
5 changed files with 95 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
import { NostrEvent } from "@/types/nostr";
import { RelayLink } from "../RelayLink";
/**
* Kind 10317 Detail Renderer - User Grasp List (Detail View)
* Shows full list of grasp service relays
*/
export function Kind10317DetailRenderer({ event }: { event: NostrEvent }) {
// Extract grasp relay URLs from g tags
const graspRelays = event.tags
.filter((tag) => tag[0] === "g" && tag[1])
.map((tag) => tag[1]);
if (graspRelays.length === 0) {
return (
<div className="p-4 text-center text-muted-foreground text-sm">
No grasp relays configured
</div>
);
}
return (
<div className="flex flex-col gap-2 p-4">
{graspRelays.map((url, index) => (
<RelayLink
key={`${url}-${index}`}
url={url}
urlClassname="text-md underline decoration-dotted"
iconClassname="size-4"
/>
))}
</div>
);
}

View File

@@ -0,0 +1,39 @@
import { BaseEventProps, BaseEventContainer } from "./BaseEventRenderer";
import { RelayLink } from "../RelayLink";
/**
* Kind 10317 Renderer - User Grasp List (Feed View)
* Shows list of grasp service relays
*/
export function Kind10317Renderer({ event }: BaseEventProps) {
// Extract grasp relay URLs from g tags
const graspRelays = event.tags
.filter((tag) => tag[0] === "g" && tag[1])
.map((tag) => tag[1]);
if (graspRelays.length === 0) {
return (
<BaseEventContainer event={event}>
<div className="text-xs text-muted-foreground italic">
No grasp relays configured
</div>
</BaseEventContainer>
);
}
return (
<BaseEventContainer event={event}>
<div className="flex flex-col gap-0.5">
{graspRelays.map((url, index) => (
<RelayLink
key={`${url}-${index}`}
url={url}
className="py-0.5 hover:bg-none"
iconClassname="size-4"
urlClassname="underline decoration-dotted"
/>
))}
</div>
</BaseEventContainer>
);
}

View File

@@ -25,6 +25,8 @@ import { Kind9802Renderer } from "./HighlightRenderer";
import { Kind9802DetailRenderer } from "./HighlightDetailRenderer";
import { Kind10002Renderer } from "./RelayListRenderer";
import { Kind10002DetailRenderer } from "./RelayListDetailRenderer";
import { Kind10317Renderer } from "./GraspListRenderer";
import { Kind10317DetailRenderer } from "./GraspListDetailRenderer";
import { Kind30023Renderer } from "./ArticleRenderer";
import { Kind30023DetailRenderer } from "./ArticleDetailRenderer";
import { CommunityNIPRenderer } from "./CommunityNIPRenderer";
@@ -74,6 +76,7 @@ const kindRenderers: Record<number, React.ComponentType<BaseEventProps>> = {
9802: Kind9802Renderer, // Highlight
777: SpellRenderer, // Spell (Grimoire)
10002: Kind10002Renderer, // Relay List Metadata (NIP-65)
10317: Kind10317Renderer, // User Grasp List (NIP-34)
10006: GenericRelayListRenderer, // Blocked Relays (NIP-51)
10007: GenericRelayListRenderer, // Search Relays (NIP-51)
10012: GenericRelayListRenderer, // Favorite Relays (NIP-51)
@@ -137,6 +140,7 @@ const detailRenderers: Record<
1621: IssueDetailRenderer, // Issue Detail (NIP-34)
9802: Kind9802DetailRenderer, // Highlight Detail
10002: Kind10002DetailRenderer, // Relay List Detail (NIP-65)
10317: Kind10317DetailRenderer, // User Grasp List Detail (NIP-34)
777: SpellDetailRenderer, // Spell Detail
30023: Kind30023DetailRenderer, // Long-form Article Detail
30311: LiveActivityDetailRenderer, // Live Streaming Event Detail (NIP-53)

View File

@@ -847,6 +847,13 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
nip: "66",
icon: Activity,
},
10317: {
kind: 10317,
name: "Grasp List",
description: "User grasp list",
nip: "34",
icon: FolderGit2,
},
// 10312: {
// kind: 10312,
// name: "Room Presence",

View File

@@ -1318,6 +1318,17 @@ kinds:
type: empty
tags: []
10317:
description: User grasp list
content:
type: empty
tags:
-
name: g
next:
type: relay
required: true
10377:
description: Proxy Announcement
content: