import Link from "next/link"; import { commitCount, lastCommit, listTree, type Commit, type TreeEntry } from "@/lib/git"; import { encodePath, shortSha, timeAgo } from "@/lib/format"; import type { Repo } from "@/lib/repo"; import { ClockIcon, CommitIcon, DirIcon, FileIcon, SubmoduleIcon } from "./icons"; import { liftRowClass } from "./repo-rows"; import { Avatar, Box } from "./ui"; // Looking up the last commit is one git call per entry; skip it for huge directories. const MAX_ENTRIES_WITH_COMMITS = 200; /** A short sha on a small raised key: the commit glyph and the mono hash. */ export function ShaChip({ sha, href, className = "" }: { sha: string; href: string; className?: string }) { return ( {shortSha(sha)} ); } /** The last commit to touch a path, sunk into the head of its plate: who, what, which and when, and the way to the history. */ export function LatestCommitBar({ repo, commit, count, gitRef, path }: { repo: Repo; commit: Commit; count?: number; gitRef: string; path?: string; }) { const historyHref = `${repo.base}/commits/${encodePath(gitRef)}${path ? `/${encodePath(path)}` : ""}`; return (
{commit.authorName} {commit.subject} {count !== undefined ? ( <> {count} commit{count === 1 ? "" : "s"} ) : ( "History" )}
); } function entryIcon(entry: TreeEntry) { if (entry.type === "tree") return ; if (entry.type === "commit") return ; return ; } // One row of the listing: the name, the last commit to touch it (md and up) and when. const ROW = `${liftRowClass} grid h-9 grid-cols-[minmax(0,1fr)_8.5rem] items-center gap-4 px-3 type-ui md:grid-cols-[minmax(0,1fr)_minmax(0,2fr)_8.5rem]`; export async function FileTable({ repo, gitRef, path }: { repo: Repo; gitRef: string; path: string }) { const entries = await listTree(repo.dir, gitRef, path); const withCommits = entries.length <= MAX_ENTRIES_WITH_COMMITS; const [latest, count, commits] = await Promise.all([ lastCommit(repo.dir, gitRef, path || undefined), path ? undefined : commitCount(repo.dir, gitRef), withCommits ? Promise.all(entries.map((e) => lastCommit(repo.dir, gitRef, e.path))) : [], ]); const parent = path.split("/").slice(0, -1).join("/"); return ( {latest && }
    {path && (
  • ..
  • )} {entries.map((entry, i) => { const commit = commits[i]; const kind = entry.type === "tree" ? "tree" : "blob"; return (
  • {entryIcon(entry)} {entry.type === "commit" ? ( {entry.name} @ {shortSha(entry.sha)} ) : ( {entry.name} )} {commit && ( {commit.subject} )} {commit && }
  • ); })}
); }