import { useParams } from "@solidjs/router"; import { createMemo, createResource, createSignal, For, Match, onMount, Show, Suspense, Switch, } from "solid-js"; import type { Commit, DID, DiffTextFragment } from "../../../util/types"; import { useDid } from "../context"; import { Header } from "../main"; import { getRepoCommit } from "../main.data"; import { buildTree, type TreeNode } from "./commit.data"; function RenderTree(props: { tree: TreeNode; skip?: boolean }) { if (props.skip) return ( {(node) => } ); const [displayChildren, setDisplayChildren] = createSignal(true); return (
{props.tree.name}
setDisplayChildren(!displayChildren())} >
{props.tree.name}
{(node) => }
); } function Fragment(props: { file: string; data: DiffTextFragment; index: number; numberSize: number; }) { let lineNumber = props.data.NewPosition; let iOld = props.data.OldPosition; let iNew = props.data.NewPosition; return ( binary data
}>
···
{(line) => { const lineNumberOld = line.Op === 2 ? "" : (iOld++).toString(); const lineNumberNew = line.Op === 1 ? "" : (iNew++).toString(); const fillerOld = " ".repeat( props.numberSize - lineNumberOld.length, ); const fillerNew = " ".repeat( props.numberSize - lineNumberNew.length, ); return ( ); }}
); } function Line(props: { file: string; index: number; line: { Op: number; Line: string }; lineNumber: number; lineNumberOld: string; lineNumberNew: string; fillerOld: string; fillerNew: string; }) { const id = `line-${props.file}-${props.index}-${props.lineNumber.toString()}`; return (
{props.fillerOld} {props.lineNumberOld} {props.fillerNew} {props.lineNumberNew}
{"   "}
{props.line.Line}
{" + "}
{props.line.Line}
{" - "}
{props.line.Line}
); } function DiffView(props: { commit: Commit }) { return ( {(diff) => { const [show, setShow] = createSignal(true); const [addedLines, removedLines] = diff.text_fragments.reduce( (acc, v) => [acc[0] + v.NewLines, acc[1] + v.LinesDeleted], [0, 0], ); const lastFrag = diff.text_fragments[diff.text_fragments.length - 1]; const numberSize = Math.max( 2, ( Math.max(lastFrag.NewPosition, lastFrag.OldPosition) + lastFrag.Lines.length ).toString().length, ); return (
setShow(!show())} >
0}>
{`+${addedLines}`}
0}>
{`-${removedLines}`}
{diff.name.old}
{diff.name.new}
{(frag, i) => ( )}
); }} ); } function CommitHeader(props: { user: string; repo: string; message: { title: string; content: string }; commit: Commit; }) { return (
{props.message.title}
{props.message.content}
{`${new Date(props.commit.diff.commit.author.When).toLocaleDateString(undefined, { dateStyle: "long" })} at ${new Date(props.commit.diff.commit.author.When).toLocaleTimeString()}`} {`${props.commit.diff.commit.author.Name} <${props.commit.diff.commit.author.Email}>`} {props.commit.ref.slice(0, 8)}
); } export default function RepoCommit() { const params = useParams(); const did = useDid(); const [commit] = createResource( () => { const d = did(); if (!d) return; return [d, params.repo, params.ref]; }, async ([did, repo, ref]) => { const res = await getRepoCommit(did as DID, repo, ref); if (!res.ok) return; return res.data as Commit; }, ); const [sidebar] = createResource(commit, async (commit) => { if (!commit.diff.diff) return { name: "", fullPath: "", type: "directory" } as TreeNode; return buildTree(commit.diff.diff.map((v) => v.name.new)); }); const allData = createMemo(() => { const s = sidebar(); const c = commit(); if (!(s && c)) return; return [s, c] as const; }); const headerData = createMemo(() => { const c = commit(); if (!c) return; const titleEnd = c.diff.commit.message.indexOf("\n"); const message = { title: c.diff.commit.message.slice(0, titleEnd), content: c.diff.commit.message.slice(titleEnd + 1), }; return [c, message] as const; }); onMount(() => { if (window.location.hash) { const element = document.getElementById(window.location.hash.slice(1)); if (element) element.scrollIntoView({ behavior: "instant", block: "start" }); } }); return (
{([commit, message]) => ( )} {([sidebar, commit]) => ( <>
CHANGED FILES
0}>
{`+${commit.diff.stat.insertions}`}
0}>
{`-${commit.diff.stat.deletions}`}
)}
); }