diff --git a/CLAUDE.md b/CLAUDE.md index f5c49f8..1a97086 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -375,6 +375,11 @@ This allows `applyTheme()` to switch themes at runtime. - Provides diagnostic UI with retry capability and error details - Error boundaries auto-reset when event changes +**Shared Badge Components**: +- **`KindBadge`** (`src/components/KindBadge.tsx`): Displays a Nostr event kind with icon, name, and kind number. Uses `getKindInfo()` from `src/constants/kinds.ts`. Variants: `"default"` (icon + name), `"compact"` (icon only), `"full"` (icon + name + kind number). Supports `clickable` prop to open kind detail window. +- **`NIPBadge`** (`src/components/NIPBadge.tsx`): Displays a NIP reference with number and optional name. Clickable to open the NIP document in a new window. Shows deprecation state. Props: `nipNumber`, `showName`, `showNIPPrefix`. +- Use these components whenever displaying kind numbers or NIP references in the UI — they provide consistent styling, tooltips, and navigation. + ## Chat System **Current Status**: Only NIP-29 (relay-based groups) is supported. Other protocols are planned for future releases. diff --git a/src/components/settings/RelayListsSettings.tsx b/src/components/settings/RelayListsSettings.tsx index b03734b..ceac87b 100644 --- a/src/components/settings/RelayListsSettings.tsx +++ b/src/components/settings/RelayListsSettings.tsx @@ -2,19 +2,7 @@ import { useState, useCallback, useEffect, useMemo } from "react"; import { use$, useEventStore } from "applesauce-react/hooks"; import { EventFactory } from "applesauce-core/event-factory"; import { toast } from "sonner"; -import { - Radio, - ShieldBan, - Search, - Mail, - X, - Plus, - Loader2, - Save, - Undo2, - CircleDot, -} from "lucide-react"; -import type { LucideIcon } from "lucide-react"; +import { X, Plus, Loader2, Save, Undo2, CircleDot } from "lucide-react"; import type { NostrEvent } from "nostr-tools"; import { Accordion, @@ -31,6 +19,8 @@ import { } from "@/components/ui/select"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; +import { KindBadge } from "@/components/KindBadge"; +import { NIPBadge } from "@/components/NIPBadge"; import { useAccount } from "@/hooks/useAccount"; import { useRelayInfo } from "@/hooks/useRelayInfo"; import { publishEvent } from "@/services/hub"; @@ -51,7 +41,7 @@ import { // --- Config --- interface RelayListKindUIConfig extends RelayListKindConfig { - icon: LucideIcon; + nip: string; } const RELAY_LIST_KINDS: RelayListKindUIConfig[] = [ @@ -60,7 +50,7 @@ const RELAY_LIST_KINDS: RelayListKindUIConfig[] = [ name: "Relay List", description: "Your primary read and write relays. Other clients use this to find your posts and deliver mentions to you.", - icon: Radio, + nip: "65", tagName: "r", hasMarkers: true, }, @@ -69,7 +59,7 @@ const RELAY_LIST_KINDS: RelayListKindUIConfig[] = [ name: "Blocked Relays", description: "Relays your client should never connect to. Useful for avoiding spam or untrusted servers.", - icon: ShieldBan, + nip: "51", tagName: "relay", hasMarkers: false, }, @@ -78,7 +68,7 @@ const RELAY_LIST_KINDS: RelayListKindUIConfig[] = [ name: "Search Relays", description: "Relays used for search queries. These should support NIP-50 full-text search.", - icon: Search, + nip: "51", tagName: "relay", hasMarkers: false, }, @@ -87,7 +77,7 @@ const RELAY_LIST_KINDS: RelayListKindUIConfig[] = [ name: "DM Relays", description: "Relays where you receive direct messages. Senders look up this list to deliver encrypted DMs to you.", - icon: Mail, + nip: "17", tagName: "relay", hasMarkers: false, }, @@ -260,7 +250,6 @@ function RelayListAccordion({ isDirty: boolean; onChange: (entries: RelayEntry[]) => void; }) { - const Icon = config.icon; const existingUrls = useMemo( () => new Set(entries.map((e) => e.url)), [entries], @@ -294,25 +283,34 @@ function RelayListAccordion({ return ( -
- -
- {config.name} - {entries.length > 0 && ( - - {entries.length} - - )} - {isDirty && ( - - )} -
+
+ + {entries.length > 0 && ( + + {entries.length} + + )} + {isDirty && ( + + )}
-

- {config.description} -

+
+

+ {config.description} +

+ +
{entries.length === 0 ? (

No relays configured