From 9665347eb94272217fd641ea0dac306bf6cfd659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20G=C3=B3mez?= Date: Fri, 12 Dec 2025 16:33:05 +0100 Subject: [PATCH] feat: support topics in kind 3 --- src/components/nostr/kinds/Kind3Renderer.tsx | 69 +++++++++++++------- src/lib/nostr-utils.ts | 7 ++ 2 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/components/nostr/kinds/Kind3Renderer.tsx b/src/components/nostr/kinds/Kind3Renderer.tsx index fbe1302..b97298e 100644 --- a/src/components/nostr/kinds/Kind3Renderer.tsx +++ b/src/components/nostr/kinds/Kind3Renderer.tsx @@ -1,7 +1,8 @@ import { useGrimoire } from "@/core/state"; import { BaseEventContainer, type BaseEventProps } from "./BaseEventRenderer"; import { UserName } from "../UserName"; -import { Users, Sparkles } from "lucide-react"; +import { Users, Sparkles, Hash } from "lucide-react"; +import { getTagValues } from "@/lib/nostr-utils"; /** * Kind 3 Renderer - Contact/Follow List @@ -10,10 +11,8 @@ import { Users, Sparkles } from "lucide-react"; export function Kind3Renderer({ event }: BaseEventProps) { const { state } = useGrimoire(); - // Extract followed pubkeys from p tags - const followedPubkeys = event.tags - .filter((tag) => tag[0] === "p") - .map((tag) => tag[1]); + const followedPubkeys = getTagValues(event, "p"); + const topics = getTagValues(event, "t"); const followsYou = state.activeAccount?.pubkey ? followedPubkeys.includes(state.activeAccount.pubkey) @@ -22,15 +21,21 @@ export function Kind3Renderer({ event }: BaseEventProps) { return (
- - - Following {followedPubkeys.length} people - +
+ + {followedPubkeys.length} people +
{followsYou && ( - - +
+ Follows you - +
+ )} + {topics.length > 0 && ( +
+ + {topics.length} topics +
)}
@@ -44,10 +49,10 @@ export function Kind3Renderer({ event }: BaseEventProps) { export function Kind3DetailView({ event }: { event: any }) { const { state } = useGrimoire(); - // Extract followed pubkeys from p tags - const followedPubkeys = event.tags - .filter((tag: string[]) => tag[0] === "p" && tag[1].length === 64) - .map((tag: string[]) => tag[1]); + const followedPubkeys = getTagValues(event, "p").filter( + (pk) => pk.length === 64 + ); + const topics = getTagValues(event, "t"); const followsYou = state.activeAccount?.pubkey ? followedPubkeys.includes(state.activeAccount.pubkey) @@ -62,26 +67,46 @@ export function Kind3DetailView({ event }: { event: any }) {
- Following {followedPubkeys.length} people + + + {followedPubkeys.length} people + {followsYou && ( Follows you )} + {topics.length > 0 && ( + + + {topics.length} topics + + )}
-
+
+

People

+ {followedPubkeys.map((pubkey: string) => ( +
+ + +
+ ))} +
+ + {topics.length > 0 && (
- {followedPubkeys.map((pubkey: string) => ( -
+

Topics

+ {topics.map((topic: string) => ( +
- + #{topic}
))}
-
+ )}
); } diff --git a/src/lib/nostr-utils.ts b/src/lib/nostr-utils.ts index 7ae2cfb..715ca0b 100644 --- a/src/lib/nostr-utils.ts +++ b/src/lib/nostr-utils.ts @@ -1,9 +1,16 @@ import type { ProfileContent } from "applesauce-core/helpers"; +import type { NostrEvent } from "nostr-tools"; export function derivePlaceholderName(pubkey: string): string { return `${pubkey.slice(0, 4)}:${pubkey.slice(-4)}`; } +export function getTagValues(event: NostrEvent, tagName: string): string[] { + return event.tags + .filter((tag) => tag[0] === tagName && tag[1]) + .map((tag) => tag[1]); +} + export function getDisplayName( pubkey: string, metadata?: ProfileContent,