mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-04-09 15:07:10 +02:00
Render NIP-29 group metadata as links (#63)
* feat: add GroupMetadataRenderer for NIP-29 group metadata (kind 39000) Render kind 39000 events with group name, picture, description, and an "Open Chat" link that opens the NIP-29 group in the chat viewer. * feat: add kind names for NIP-29 group events and simplify renderer - Add kind 39000 (Group), 39001 (Group Admins), 39002 (Group Members) to EVENT_KINDS so kind badge displays proper names - Simplify GroupMetadataRenderer to show only title, description, and Open Chat CTA (remove group picture) --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
66
src/components/nostr/kinds/GroupMetadataRenderer.tsx
Normal file
66
src/components/nostr/kinds/GroupMetadataRenderer.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
import type { NostrEvent } from "@/types/nostr";
|
||||
import { getTagValue } from "applesauce-core/helpers";
|
||||
import { getSeenRelays } from "applesauce-core/helpers/relays";
|
||||
import { BaseEventContainer, ClickableEventTitle } from "./BaseEventRenderer";
|
||||
import { useGrimoire } from "@/core/state";
|
||||
import { MessageSquare } from "lucide-react";
|
||||
|
||||
interface GroupMetadataRendererProps {
|
||||
event: NostrEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderer for NIP-29 Group Metadata events (kind 39000)
|
||||
* Displays group info and links to chat
|
||||
*/
|
||||
export function GroupMetadataRenderer({ event }: GroupMetadataRendererProps) {
|
||||
const { addWindow } = useGrimoire();
|
||||
|
||||
// Extract group metadata
|
||||
const groupId = getTagValue(event, "d") || "";
|
||||
const name = getTagValue(event, "name") || groupId;
|
||||
const about = getTagValue(event, "about");
|
||||
|
||||
// Get relay URL from where we saw this event
|
||||
const seenRelaysSet = getSeenRelays(event);
|
||||
const relayUrl = seenRelaysSet?.values().next().value;
|
||||
|
||||
const handleOpenChat = () => {
|
||||
if (!relayUrl) return;
|
||||
|
||||
addWindow("chat", {
|
||||
protocol: "nip-29",
|
||||
identifier: {
|
||||
type: "group",
|
||||
value: groupId,
|
||||
relays: [relayUrl],
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const canOpenChat = !!relayUrl && !!groupId;
|
||||
|
||||
return (
|
||||
<BaseEventContainer event={event}>
|
||||
<div className="flex flex-col gap-1">
|
||||
<ClickableEventTitle event={event} className="font-semibold">
|
||||
{name}
|
||||
</ClickableEventTitle>
|
||||
|
||||
{about && (
|
||||
<p className="text-xs text-muted-foreground line-clamp-2">{about}</p>
|
||||
)}
|
||||
|
||||
{canOpenChat && (
|
||||
<button
|
||||
onClick={handleOpenChat}
|
||||
className="text-xs text-primary hover:underline flex items-center gap-1 w-fit mt-1"
|
||||
>
|
||||
<MessageSquare className="size-3" />
|
||||
Open Chat
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</BaseEventContainer>
|
||||
);
|
||||
}
|
||||
@@ -61,6 +61,7 @@ import { ZapstoreAppSetRenderer } from "./ZapstoreAppSetRenderer";
|
||||
import { ZapstoreAppSetDetailRenderer } from "./ZapstoreAppSetDetailRenderer";
|
||||
import { ZapstoreReleaseRenderer } from "./ZapstoreReleaseRenderer";
|
||||
import { ZapstoreReleaseDetailRenderer } from "./ZapstoreReleaseDetailRenderer";
|
||||
import { GroupMetadataRenderer } from "./GroupMetadataRenderer";
|
||||
import { NostrEvent } from "@/types/nostr";
|
||||
import { BaseEventContainer, type BaseEventProps } from "./BaseEventRenderer";
|
||||
|
||||
@@ -116,6 +117,7 @@ const kindRenderers: Record<number, React.ComponentType<BaseEventProps>> = {
|
||||
31989: HandlerRecommendationRenderer, // Handler Recommendation (NIP-89)
|
||||
31990: ApplicationHandlerRenderer, // Application Handler (NIP-89)
|
||||
32267: ZapstoreAppRenderer, // Zapstore App
|
||||
39000: GroupMetadataRenderer, // Group Metadata (NIP-29)
|
||||
39701: Kind39701Renderer, // Web Bookmarks (NIP-B0)
|
||||
};
|
||||
|
||||
|
||||
@@ -1415,6 +1415,27 @@ export const EVENT_KINDS: Record<number | string, EventKind> = {
|
||||
nip: "51",
|
||||
icon: Play,
|
||||
},
|
||||
39000: {
|
||||
kind: 39000,
|
||||
name: "Group",
|
||||
description: "Group Metadata",
|
||||
nip: "29",
|
||||
icon: Users,
|
||||
},
|
||||
39001: {
|
||||
kind: 39001,
|
||||
name: "Group Admins",
|
||||
description: "Group Admins List",
|
||||
nip: "29",
|
||||
icon: UserCheck,
|
||||
},
|
||||
39002: {
|
||||
kind: 39002,
|
||||
name: "Group Members",
|
||||
description: "Group Members List",
|
||||
nip: "29",
|
||||
icon: Users,
|
||||
},
|
||||
39701: {
|
||||
kind: 39701,
|
||||
name: "Web Bookmark",
|
||||
|
||||
Reference in New Issue
Block a user