diff --git a/src/components/EventDetailViewer.tsx b/src/components/EventDetailViewer.tsx index fa254d5..43c3a70 100644 --- a/src/components/EventDetailViewer.tsx +++ b/src/components/EventDetailViewer.tsx @@ -28,6 +28,7 @@ import { useReqTimelineEnhanced } from "@/hooks/useReqTimelineEnhanced"; import { applySpellParameters, decodeSpell } from "@/lib/spell-conversion"; import { parseReqCommand } from "@/lib/req-parser"; import { AGGREGATOR_RELAYS } from "@/services/loaders"; +import { KindBadge } from "./KindBadge"; export interface EventDetailViewerProps { pointer: EventPointer | AddressPointer; @@ -372,7 +373,7 @@ export function EventDetailViewer({ pointer }: EventDetailViewerProps) { {/* Rendered Content */} -
+
@@ -385,16 +386,44 @@ export function EventDetailViewer({ pointer }: EventDetailViewerProps) { defaultValue={eventSpells[0]?.id} className="flex flex-col h-full" > - - {eventSpells.map((spell) => ( - - {spell.name || spell.alias || "Untitled Spell"} - - ))} + + {eventSpells.map((spell) => { + // Extract kinds from spell for display + const spellKinds = (() => { + try { + if (spell.event) { + const decoded = decodeSpell(spell.event); + return decoded.filter.kinds?.slice(0, 3) || []; + } + // For local spells, parse command + const commandWithoutPrefix = spell.command + .replace(/^\s*(req|count)\s+/i, "") + .trim(); + const tokens = commandWithoutPrefix.split(/\s+/); + const parsed = parseReqCommand(tokens); + return parsed.filter.kinds?.slice(0, 3) || []; + } catch { + return []; + } + })(); + + return ( + + {spellKinds.length > 0 && ( +
+ {spellKinds.map((kind) => ( + + ))} +
+ )} + {spell.name || spell.alias || "Untitled Spell"} +
+ ); + })}
{/* Spell Tab Contents */} diff --git a/src/components/ProfileViewer.tsx b/src/components/ProfileViewer.tsx index d218a8f..e8f4707 100644 --- a/src/components/ProfileViewer.tsx +++ b/src/components/ProfileViewer.tsx @@ -42,6 +42,7 @@ import { applySpellParameters, decodeSpell } from "@/lib/spell-conversion"; import { parseReqCommand } from "@/lib/req-parser"; import { useOutboxRelays } from "@/hooks/useOutboxRelays"; import { AGGREGATOR_RELAYS } from "@/services/loaders"; +import { KindBadge } from "./KindBadge"; export interface ProfileViewerProps { pubkey: string; @@ -615,7 +616,7 @@ export function ProfileViewer({ pubkey }: ProfileViewerProps) {
{/* Profile Content */} -
+
{!profile && !profileEvent && } {!profile && profileEvent && ( @@ -713,16 +714,44 @@ export function ProfileViewer({ pubkey }: ProfileViewerProps) { defaultValue={pubkeySpells[0]?.id} className="flex flex-col h-full" > - - {pubkeySpells.map((spell) => ( - - {spell.name || spell.alias || "Untitled Spell"} - - ))} + + {pubkeySpells.map((spell) => { + // Extract kinds from spell for display + const spellKinds = (() => { + try { + if (spell.event) { + const decoded = decodeSpell(spell.event); + return decoded.filter.kinds?.slice(0, 3) || []; + } + // For local spells, parse command + const commandWithoutPrefix = spell.command + .replace(/^\s*(req|count)\s+/i, "") + .trim(); + const tokens = commandWithoutPrefix.split(/\s+/); + const parsed = parseReqCommand(tokens); + return parsed.filter.kinds?.slice(0, 3) || []; + } catch { + return []; + } + })(); + + return ( + + {spellKinds.length > 0 && ( +
+ {spellKinds.map((kind) => ( + + ))} +
+ )} + {spell.name || spell.alias || "Untitled Spell"} +
+ ); + })}
{/* Spell Tab Contents */} diff --git a/src/components/RelayViewer.tsx b/src/components/RelayViewer.tsx index 20a6f31..6b2b5e1 100644 --- a/src/components/RelayViewer.tsx +++ b/src/components/RelayViewer.tsx @@ -12,6 +12,7 @@ import { applySpellParameters, decodeSpell } from "@/lib/spell-conversion"; import { parseReqCommand } from "@/lib/req-parser"; import { useMemo } from "react"; import { NIPBadge } from "./NIPBadge"; +import { KindBadge } from "./KindBadge"; import { SpellHeader } from "./timeline/SpellHeader"; export interface RelayViewerProps { @@ -237,7 +238,7 @@ export function RelayViewer({ url }: RelayViewerProps) { return (
{/* Relay Info Content */} -
+
{/* Header */}
@@ -314,16 +315,44 @@ export function RelayViewer({ url }: RelayViewerProps) { defaultValue={relaySpells[0]?.id} className="flex flex-col h-full" > - - {relaySpells.map((spell) => ( - - {spell.name || spell.alias || "Untitled Spell"} - - ))} + + {relaySpells.map((spell) => { + // Extract kinds from spell for display + const spellKinds = (() => { + try { + if (spell.event) { + const decoded = decodeSpell(spell.event); + return decoded.filter.kinds?.slice(0, 3) || []; + } + // For local spells, parse command + const commandWithoutPrefix = spell.command + .replace(/^\s*(req|count)\s+/i, "") + .trim(); + const tokens = commandWithoutPrefix.split(/\s+/); + const parsed = parseReqCommand(tokens); + return parsed.filter.kinds?.slice(0, 3) || []; + } catch { + return []; + } + })(); + + return ( + + {spellKinds.length > 0 && ( +
+ {spellKinds.map((kind) => ( + + ))} +
+ )} + {spell.name || spell.alias || "Untitled Spell"} +
+ ); + })}
{/* Spell Tab Contents */}