diff --git a/src/components/KindBadge.tsx b/src/components/KindBadge.tsx
index 7890a9c..6e71c0d 100644
--- a/src/components/KindBadge.tsx
+++ b/src/components/KindBadge.tsx
@@ -1,5 +1,6 @@
import { getKindInfo } from "@/constants/kinds";
import { cn } from "@/lib/utils";
+import { useGrimoire } from "@/core/state";
interface KindBadgeProps {
kind: number;
@@ -9,6 +10,7 @@ interface KindBadgeProps {
variant?: "default" | "compact" | "full";
className?: string;
iconClassname?: string;
+ clickable?: boolean;
}
export function KindBadge({
@@ -19,11 +21,20 @@ export function KindBadge({
variant = "default",
className = "",
iconClassname = "text-muted-foreground",
+ clickable = false,
}: KindBadgeProps) {
+ const { addWindow } = useGrimoire();
const kindInfo = getKindInfo(kind);
const Icon = kindInfo?.icon;
const style = "inline-flex items-center gap-2 text-foreground";
+ const interactiveStyle = clickable ? "cursor-pointer" : "";
+
+ const handleClick = () => {
+ if (clickable) {
+ addWindow("kind", { number: String(kind) }, `Kind ${kind}`);
+ }
+ };
// Apply variant presets or use props
let showIcon = propShowIcon ?? true;
@@ -42,7 +53,10 @@ export function KindBadge({
if (!kindInfo) {
return (
-
+
Kind {kind}
);
@@ -50,11 +64,22 @@ export function KindBadge({
return (
{showIcon && Icon && }
- {showName && {kindInfo.name}}
+ {showName && (
+
+ {kindInfo.name}
+
+ )}
{showKindNumber && ({kind})}
);
diff --git a/src/components/NipRenderer.tsx b/src/components/NipRenderer.tsx
index 0d2efc9..0ac0220 100644
--- a/src/components/NipRenderer.tsx
+++ b/src/components/NipRenderer.tsx
@@ -47,7 +47,7 @@ export function NipRenderer({ nipId, className = "" }: NipRendererProps) {
{kinds.map((kind) => (
-
+
))}
diff --git a/src/components/nostr/kinds/Kind3Renderer.tsx b/src/components/nostr/kinds/Kind3Renderer.tsx
index b97298e..9c787e5 100644
--- a/src/components/nostr/kinds/Kind3Renderer.tsx
+++ b/src/components/nostr/kinds/Kind3Renderer.tsx
@@ -50,7 +50,7 @@ export function Kind3DetailView({ event }: { event: any }) {
const { state } = useGrimoire();
const followedPubkeys = getTagValues(event, "p").filter(
- (pk) => pk.length === 64
+ (pk) => pk.length === 64,
);
const topics = getTagValues(event, "t");
diff --git a/src/components/nostr/kinds/index.tsx b/src/components/nostr/kinds/index.tsx
index de4a313..55bd849 100644
--- a/src/components/nostr/kinds/index.tsx
+++ b/src/components/nostr/kinds/index.tsx
@@ -90,7 +90,11 @@ export {
} from "./BaseEventRenderer";
export type { BaseEventProps } from "./BaseEventRenderer";
export { Kind1Renderer } from "./Kind1Renderer";
-export { RepostRenderer, Kind6Renderer, Kind16Renderer } from "./RepostRenderer";
+export {
+ RepostRenderer,
+ Kind6Renderer,
+ Kind16Renderer,
+} from "./RepostRenderer";
export { Kind7Renderer } from "./Kind7Renderer";
export { Kind20Renderer } from "./Kind20Renderer";
export { Kind21Renderer } from "./Kind21Renderer";
diff --git a/src/components/ui/visually-hidden.tsx b/src/components/ui/visually-hidden.tsx
index 7ffbc7d..fee1bbd 100644
--- a/src/components/ui/visually-hidden.tsx
+++ b/src/components/ui/visually-hidden.tsx
@@ -9,11 +9,7 @@ export const VisuallyHidden = React.forwardRef<
HTMLSpanElement,
React.HTMLAttributes
>(({ className, ...props }, ref) => (
-
+
));
VisuallyHidden.displayName = "VisuallyHidden";
diff --git a/src/lib/req-parser.test.ts b/src/lib/req-parser.test.ts
index 7f6f313..86787d2 100644
--- a/src/lib/req-parser.test.ts
+++ b/src/lib/req-parser.test.ts
@@ -64,7 +64,10 @@ describe("parseReqCommand", () => {
"-a",
"user@domain.com,alice@example.com",
]);
- expect(result.nip05Authors).toEqual(["user@domain.com", "alice@example.com"]);
+ expect(result.nip05Authors).toEqual([
+ "user@domain.com",
+ "alice@example.com",
+ ]);
expect(result.filter.authors).toBeUndefined();
});
@@ -76,10 +79,7 @@ describe("parseReqCommand", () => {
});
it("should deduplicate NIP-05 identifiers", () => {
- const result = parseReqCommand([
- "-a",
- "user@domain.com,user@domain.com",
- ]);
+ const result = parseReqCommand(["-a", "user@domain.com,user@domain.com"]);
expect(result.nip05Authors).toEqual(["user@domain.com"]);
});
});
@@ -120,8 +120,14 @@ describe("parseReqCommand", () => {
});
it("should accumulate NIP-05 identifiers for #p tags", () => {
- const result = parseReqCommand(["-p", "user@domain.com,alice@example.com"]);
- expect(result.nip05PTags).toEqual(["user@domain.com", "alice@example.com"]);
+ const result = parseReqCommand([
+ "-p",
+ "user@domain.com,alice@example.com",
+ ]);
+ expect(result.nip05PTags).toEqual([
+ "user@domain.com",
+ "alice@example.com",
+ ]);
expect(result.filter["#p"]).toBeUndefined();
});
diff --git a/src/lib/req-parser.ts b/src/lib/req-parser.ts
index c1dc9d6..2478de4 100644
--- a/src/lib/req-parser.ts
+++ b/src/lib/req-parser.ts
@@ -22,9 +22,9 @@ export interface ParsedReqCommand {
function parseCommaSeparated(
value: string,
parser: (v: string) => T | null,
- target: Set
+ target: Set,
): boolean {
- const values = value.split(',').map(v => v.trim());
+ const values = value.split(",").map((v) => v.trim());
let addedAny = false;
for (const val of values) {
@@ -102,7 +102,7 @@ export function parseReqCommand(args: string[]): ParsedReqCommand {
const kind = parseInt(v, 10);
return isNaN(kind) ? null : kind;
},
- kinds
+ kinds,
);
i += addedAny ? 2 : 1;
break;
@@ -116,7 +116,7 @@ export function parseReqCommand(args: string[]): ParsedReqCommand {
break;
}
let addedAny = false;
- const values = nextArg.split(',').map(a => a.trim());
+ const values = nextArg.split(",").map((a) => a.trim());
for (const authorStr of values) {
if (!authorStr) continue;
// Check if it's a NIP-05 identifier
@@ -156,7 +156,7 @@ export function parseReqCommand(args: string[]): ParsedReqCommand {
const addedAny = parseCommaSeparated(
nextArg,
parseNoteOrHex,
- eventIds
+ eventIds,
);
i += addedAny ? 2 : 1;
break;
@@ -169,7 +169,7 @@ export function parseReqCommand(args: string[]): ParsedReqCommand {
break;
}
let addedAny = false;
- const values = nextArg.split(',').map(p => p.trim());
+ const values = nextArg.split(",").map((p) => p.trim());
for (const pubkeyStr of values) {
if (!pubkeyStr) continue;
// Check if it's a NIP-05 identifier
@@ -194,7 +194,7 @@ export function parseReqCommand(args: string[]): ParsedReqCommand {
const addedAny = parseCommaSeparated(
nextArg,
(v) => v, // hashtags are already strings
- tTags
+ tTags,
);
i += addedAny ? 2 : 1;
} else {
@@ -209,7 +209,7 @@ export function parseReqCommand(args: string[]): ParsedReqCommand {
const addedAny = parseCommaSeparated(
nextArg,
(v) => v, // d-tags are already strings
- dTags
+ dTags,
);
i += addedAny ? 2 : 1;
} else {
diff --git a/src/types/man.ts b/src/types/man.ts
index 4a6a63c..8815955 100644
--- a/src/types/man.ts
+++ b/src/types/man.ts
@@ -157,7 +157,8 @@ export const manPages: Record = {
},
{
flag: "-e ",
- description: "Filter by referenced event ID (#e tag). Supports comma-separated values: -e id1,id2,id3",
+ description:
+ "Filter by referenced event ID (#e tag). Supports comma-separated values: -e id1,id2,id3",
},
{
flag: "-p ",
@@ -166,11 +167,13 @@ export const manPages: Record = {
},
{
flag: "-t ",
- description: "Filter by hashtag (#t tag). Supports comma-separated values: -t nostr,bitcoin,lightning",
+ description:
+ "Filter by hashtag (#t tag). Supports comma-separated values: -t nostr,bitcoin,lightning",
},
{
flag: "-d ",
- description: "Filter by d-tag identifier (replaceable events). Supports comma-separated values: -d article1,article2",
+ description:
+ "Filter by d-tag identifier (replaceable events). Supports comma-separated values: -d article1,article2",
},
{
flag: "--since