From 2792cab04dc0da8a08ed426dd2868c2fb01fd22f Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 21 Dec 2025 12:50:08 +0000 Subject: [PATCH] feat: link repository names in repository state renderers - Repository name in both feed and detail views now links to the repository (kind 30617) - Uses same link styling as issues: cursor-crosshair, underline decoration-dotted - Fetches repository event to display proper name instead of identifier - Only "pushed " part opens the state event itself - Repository link opens in new window using addWindow("open") --- .../kinds/RepositoryStateDetailRenderer.tsx | 47 ++++++++++++-- .../nostr/kinds/RepositoryStateRenderer.tsx | 63 ++++++++++++++----- 2 files changed, 91 insertions(+), 19 deletions(-) diff --git a/src/components/nostr/kinds/RepositoryStateDetailRenderer.tsx b/src/components/nostr/kinds/RepositoryStateDetailRenderer.tsx index a3e17dc..6393f2d 100644 --- a/src/components/nostr/kinds/RepositoryStateDetailRenderer.tsx +++ b/src/components/nostr/kinds/RepositoryStateDetailRenderer.tsx @@ -1,6 +1,8 @@ import { useMemo } from "react"; -import { GitBranch, GitCommit, Tag, Copy, CopyCheck } from "lucide-react"; +import { GitBranch, GitCommit, Tag, Copy, CopyCheck, FolderGit2 } from "lucide-react"; import { useCopy } from "@/hooks/useCopy"; +import { useGrimoire } from "@/core/state"; +import { useNostrEvent } from "@/hooks/useNostrEvent"; import type { NostrEvent } from "@/types/nostr"; import { getRepositoryIdentifier, @@ -9,6 +11,7 @@ import { getRepositoryStateHeadCommit, getRepositoryStateBranches, getRepositoryStateTags, + getRepositoryName, } from "@/lib/nip34-helpers"; /** @@ -16,6 +19,7 @@ import { * Displays full repository state with all refs, branches, and tags */ export function RepositoryStateDetailRenderer({ event }: { event: NostrEvent }) { + const { addWindow } = useGrimoire(); const repoId = useMemo(() => getRepositoryIdentifier(event), [event]); const headRef = useMemo(() => getRepositoryStateHead(event), [event]); const branch = useMemo(() => parseHeadBranch(headRef), [event, headRef]); @@ -23,14 +27,49 @@ export function RepositoryStateDetailRenderer({ event }: { event: NostrEvent }) const branches = useMemo(() => getRepositoryStateBranches(event), [event]); const tags = useMemo(() => getRepositoryStateTags(event), [event]); - const displayName = repoId || "Repository"; + // Create repository pointer (kind 30617) + const repoPointer = useMemo( + () => + repoId + ? { + kind: 30617, + pubkey: event.pubkey, + identifier: repoId, + } + : null, + [repoId, event.pubkey], + ); + + // Fetch the repository event to get its name + const repoEvent = useNostrEvent(repoPointer || undefined); + + // Get repository display name + const displayName = repoEvent + ? getRepositoryName(repoEvent) || repoId || "Repository" + : repoId || "Repository"; + + const handleRepoClick = () => { + if (repoPointer) { + addWindow("open", { pointer: repoPointer }); + } + }; return (
{/* Repository Header */}
- {/* Name */} -

{displayName}

+ {/* Name with link to repository */} + {repoPointer ? ( +

+ + {displayName} +

+ ) : ( +

{displayName}

+ )} {/* HEAD Info */} {branch && commitHash && ( diff --git a/src/components/nostr/kinds/RepositoryStateRenderer.tsx b/src/components/nostr/kinds/RepositoryStateRenderer.tsx index 71cf5f1..1cc21d6 100644 --- a/src/components/nostr/kinds/RepositoryStateRenderer.tsx +++ b/src/components/nostr/kinds/RepositoryStateRenderer.tsx @@ -3,12 +3,15 @@ import { type BaseEventProps, ClickableEventTitle, } from "./BaseEventRenderer"; -import { GitCommit } from "lucide-react"; +import { GitCommit, FolderGit2 } from "lucide-react"; +import { useGrimoire } from "@/core/state"; +import { useNostrEvent } from "@/hooks/useNostrEvent"; import { getRepositoryIdentifier, getRepositoryStateHeadCommit, parseHeadBranch, getRepositoryStateHead, + getRepositoryName, } from "@/lib/nip34-helpers"; /** @@ -16,34 +19,64 @@ import { * Displays as a compact git push notification in feed view */ export function RepositoryStateRenderer({ event }: BaseEventProps) { + const { addWindow } = useGrimoire(); const repoId = getRepositoryIdentifier(event); const headRef = getRepositoryStateHead(event); const branch = parseHeadBranch(headRef); const commitHash = getRepositoryStateHeadCommit(event); - // Format: "pushed <8 chars of HEAD commit> to in " + // Create repository pointer (kind 30617) + const repoPointer = repoId + ? { + kind: 30617, + pubkey: event.pubkey, + identifier: repoId, + } + : null; + + // Fetch the repository event to get its name + const repoEvent = useNostrEvent(repoPointer || undefined); + + // Get repository display name + const repoName = repoEvent + ? getRepositoryName(repoEvent) || repoId || "Repository" + : repoId || "repository"; + const shortHash = commitHash?.substring(0, 8) || "unknown"; const branchName = branch || "unknown"; - const repoName = repoId || "repository"; + + const handleRepoClick = () => { + if (repoPointer) { + addWindow("open", { pointer: repoPointer }); + } + }; return (
{/* Push notification */} -
+
- - pushed{" "} - - {shortHash} - {" "} +
+ + pushed{" "} + + {shortHash} + + {" "} to {branchName} in{" "} - {repoName} - + {repoPointer ? ( + + + {repoName} + + ) : ( + {repoName} + )} +