mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-04-09 23:16:50 +02:00
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 <commit>" part opens the state event itself
- Repository link opens in new window using addWindow("open")
This commit is contained in:
@@ -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 (
|
||||
<div className="flex flex-col gap-4 p-4 max-w-3xl mx-auto">
|
||||
{/* Repository Header */}
|
||||
<header className="flex flex-col gap-4 border-b border-border pb-4">
|
||||
{/* Name */}
|
||||
<h1 className="text-3xl font-bold">{displayName}</h1>
|
||||
{/* Name with link to repository */}
|
||||
{repoPointer ? (
|
||||
<h1
|
||||
onClick={handleRepoClick}
|
||||
className="text-3xl font-bold cursor-crosshair underline decoration-dotted hover:text-primary inline-flex items-center gap-2"
|
||||
>
|
||||
<FolderGit2 className="size-8" />
|
||||
{displayName}
|
||||
</h1>
|
||||
) : (
|
||||
<h1 className="text-3xl font-bold">{displayName}</h1>
|
||||
)}
|
||||
|
||||
{/* HEAD Info */}
|
||||
{branch && commitHash && (
|
||||
|
||||
@@ -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 <branch> in <repo>"
|
||||
// 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 (
|
||||
<BaseEventContainer event={event}>
|
||||
<div className="flex flex-col gap-2">
|
||||
{/* Push notification */}
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex items-center gap-2 flex-wrap">
|
||||
<GitCommit className="size-4 text-muted-foreground flex-shrink-0" />
|
||||
<ClickableEventTitle
|
||||
event={event}
|
||||
className="text-sm font-medium text-foreground"
|
||||
as="span"
|
||||
>
|
||||
pushed{" "}
|
||||
<code className="px-1.5 py-0.5 rounded bg-muted text-xs font-mono">
|
||||
{shortHash}
|
||||
</code>{" "}
|
||||
<div className="text-sm font-medium text-foreground">
|
||||
<ClickableEventTitle event={event} className="" as="span">
|
||||
pushed{" "}
|
||||
<code className="px-1.5 py-0.5 rounded bg-muted text-xs font-mono">
|
||||
{shortHash}
|
||||
</code>
|
||||
</ClickableEventTitle>{" "}
|
||||
to <span className="font-semibold">{branchName}</span> in{" "}
|
||||
<span className="font-semibold">{repoName}</span>
|
||||
</ClickableEventTitle>
|
||||
{repoPointer ? (
|
||||
<span
|
||||
onClick={handleRepoClick}
|
||||
className="inline-flex items-center gap-1 cursor-crosshair underline decoration-dotted hover:text-primary"
|
||||
>
|
||||
<FolderGit2 className="size-3" />
|
||||
<span className="font-semibold">{repoName}</span>
|
||||
</span>
|
||||
) : (
|
||||
<span className="font-semibold">{repoName}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseEventContainer>
|
||||
|
||||
Reference in New Issue
Block a user