118 lines · 4.4 KB
import { createFileRoute, Link } from "@tanstack/react-router";
import { getBlob } from "~/fns/browse";
import { getNotebook } from "~/fns/code";
import { RichBlob, richKind } from "~/components/rich/RichBlob";
import { CodeFile } from "~/components/CodeFile";
import { Breadcrumbs } from "~/components/RefNavigation";
import { RefSwitcher } from "~/components/RefSwitcher";
import { formatBytes } from "~/lib/format";
import { Markdown } from "~/ui/Markdown";
import { Panel } from "~/ui/Panel";
import { buttonClass } from "~/ui/Button";
import { ExternalLink } from "~/ui/TextLink";

const IMAGE_EXTENSIONS = /\.(png|jpe?g|gif|webp|avif|ico)$/i;

export const Route = createFileRoute("/$owner/$repo/blob/$")({
  loader: async ({ params }) => {
    const input = { owner: params.owner, repo: params.repo, splat: params._splat ?? "" };
    const blob = await getBlob({ data: input });
    const notebook = blob.content !== null && blob.path.endsWith(".ipynb") ? await getNotebook({ data: input }) : null;
    return { ...blob, notebook };
  },
  component: BlobPage,
});

function BlobPage() {
  const blob = Route.useLoaderData();
  const { owner, repo } = Route.useParams();
  const rawUrl = `/${owner}/${repo}/raw/${blob.ref.name}/${blob.path}`;
  const name = blob.path.split("/").pop() ?? blob.path;
  const lineCount = blob.content ? blob.content.split("\n").length : 0;
  const rich = blob.content !== null ? richKind(blob.path, blob.notebook !== null) : null;

  return (
    <div className="space-y-4">
      <div className="flex flex-wrap items-center gap-3">
        <RefSwitcher
          owner={owner}
          repo={repo}
          current={blob.ref.name}