import type { RepositoryRow } from "../../db/index.ts"; import type { SessionUser } from "../../middleware/session.ts"; import type { FileView } from "../../services/highlight.ts"; import { Layout } from "../layout.tsx"; import { RepoHeader } from "../repos/RepoHeader.tsx"; import { BranchSelector } from "./BranchSelector.tsx"; import { RepoNav } from "./RepoNav.tsx"; interface FileBlobProps { user: SessionUser | null; repo: RepositoryRow; ref: string; filePath: string; view: FileView; branches: string[]; tags?: string[]; markdownHtml?: string; error?: string; } export function FileBlob({ user, repo, ref: blobRef, filePath, view, branches, tags, markdownHtml, error, }: FileBlobProps) { const parts = filePath.split("/"); const filename = parts[parts.length - 1] ?? filePath; return (
{!!error && (

{error}

)}
{filename}
Raw {view.type === "inline" && branches.includes(blobRef) && user?.isAdmin && ( Edit )} {branches.includes(blobRef) && user?.isAdmin && (
Delete
Delete {filename}?
)}
{markdownHtml ? (
{markdownHtml as "safe"}
) : view.type === "inline" ? (
{view.html as "safe"}
) : view.type === "media" ? (
{view.mimeType.startsWith("image/") ? ( {filename} ) : view.mimeType.startsWith("audio/") ? ( // biome-ignore lint/a11y/useMediaCaption: captions unavailable for arbitrary repo files
) : view.type === "binary" ? (

Binary file ({formatSize(view.size)})

Download
) : (

File too large to display inline ( {formatSize(view.size)})

Download
)}
); } function formatSize(bytes: number): string { if (bytes < 1024) return `${bytes} B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`; return `${(bytes / 1024 / 1024).toFixed(1)} MB`; }