<script lang="ts"> import Nav from '../../Nav.svelte'; import Atom from './Atom.svelte'; import Pos from './Pos.svelte'; import Edge from './Edge.svelte'; import Contents from './Contents.svelte'; import Meta from './Meta.svelte'; import type { Deps, Hunk } from './Types'; export let data: { deps: Deps; authors: { login?: string; key: string }[]; hash: string; repo: string; owner: string; header: { message: string; timestamp: string; description: string | null; }; hunks: Hunk[]; }; let date = new Intl.DateTimeFormat('en-US', { dateStyle: 'medium', timeStyle: 'short' }).format(new Date(data.header.timestamp)); </script> <svelte:head> <title>{data.owner} / {data.repo} - {data.hash}</title> </svelte:head> <div class="p-3"> <Nav user={data.owner} repo={data.repo} link={true} /> <h1 class="mt-5">{data.header.message}</h1> <div class="flex items-center py-3 gap-5"> {#if data.authors?.length} {#if data.authors[0]?.login} <img class="profile-picture" src="/identicon/{data.authors[0].login}" alt="Profile picture of {data.authors[0].login}" /> {:else} <img alt="" class="profile-picture" src="/identicon/question/small" /> {/if} {:else} <img class="profile-picture" src="/identicon/question/small" alt="unknown author" /> {/if} <div class="flex flex-col"> <div> {#each data.authors as a, i}{#if i > 0}, {/if}{#if a.login}<a href="/{a.login}">{a.login}</a>{:else} <span class="font-mono">{a.key}</span> {/if}{/each} </div> <div> {date} </div> <div> <code class="hash">{data.hash}</code> </div> </div> </div> <h2 class="mt-8">Dependencies</h2> <ul class="list my-3"> {#if data.deps?.hashes?.length} {#each data.deps.hashes.slice(2) as d, i} {#if i >= data.deps?.deps.length + (data.deps?.known?.length || 0)}<li class="list-row"> [*] <a class="link" href={d}><code class="hash">{d}</code></a> </li> {:else} <li>[{i + 2}] <a class="link" href={d}><code class="hash">{d}</code></a></li> {/if} {/each} {/if} </ul> <h2 class="mt-8">Change contents</h2> <ul class="py-3"> {#if data.hunks} {#each data.hunks as l} <li class=""> {#if l.FileAdd} <h3>File addition: <Meta m={l.FileAdd.meta} /></h3> <div class="context"> <div class="change-newvertex-up"> {#each l.FileAdd.context as cc}<Pos deps={data.deps} c={cc} />{/each} </div> </div> <div class="p-3"> <Contents contents={l.FileAdd.contents} /> </div> {:else if l.FileMove} <h6> File move:{#each l.FileMove.old as m} <Meta {m} />{/each} → <Meta m={l.FileMove.meta} /> </h6> <div class="px-3"> <div class="context"> <div class="change-newvertex-up"> {#each l.FileMove.up as cc}<Pos deps={data.deps} c={cc} />{/each} </div> </div> <div class="context"> <div class="change-newvertex-down"> {#each l.FileMove.down as cc}<Pos deps={data.deps} c={cc} />{/each} </div> </div> </div> {:else if l.FileDel} <h6> File deletion:{#each l.FileDel.deleted_names as m} <Meta {m} />{/each} </h6> <div class="px-3"> <Atom deps={data.deps} atom={l.FileDel.del} /> {#if l.FileDel.content_edges.length} <div class="context"> {#each l.FileDel.content_edges as e, n}{#if n > 0}, {/if}<Edge edge={e} deps={data.deps} />{/each} </div> {/if} </div> <div class="p-3"> <Contents contents={l.FileDel.content} /> </div> {:else if l.FileUndel} <h6> File un-deletion:{#each l.FileUndel.undel_names as m} <Meta {m} />{/each} </h6> <div class="px-3"> <Atom deps={data.deps} atom={l.FileUndel.undel} /> <div class="context"> {#each l.FileUndel.content_edges as e, n}{#if n > 0}, {/if}<Edge edge={e} deps={data.deps} />{/each} </div> </div> <div class="p-3"> <Contents contents={l.FileUndel.content} /> </div> {:else if l.SolveNameConflict} <h6> Solving a name conflict:{#each l.SolveNameConflict.old as m} <Meta {m} />{/each} </h6> <div class="px-3"> <Atom deps={data.deps} atom={l.SolveNameConflict.name} /> </div> {:else if l.UnsolveNameConflict} <h6> Unsolving a name conflict:{#each l.UnsolveNameConflict.old as m} <Meta {m} />{/each} </h6> <div class="px-3"> <Atom deps={data.deps} atom={l.UnsolveNameConflict.name} /> </div> {:else if l.Edit} <h6>Edit in {l.Edit.path} at line {l.Edit.line}</h6> <div class="px-3"> <Atom deps={data.deps} atom={l.Edit.atom} /> </div> <div class="px-3 pb-0"> <Contents contents={l.Edit.contents} /> </div> {:else if l.Replacement} <h6>Replacement in {l.Replacement.path} at line {l.Replacement.line}</h6> <div class="px-3"> <Atom deps={data.deps} atom={{ EdgeMap: l.Replacement.del }} /> <Contents contents={l.Replacement.del_contents} /> </div> <div class="px-3 py-2 m-0"> <Atom deps={data.deps} atom={{ NewVertex: l.Replacement.ins }} /> <Contents contents={l.Replacement.ins_contents} /> </div> {:else if l.SolveOrderConflict} <h6> Solving an order conflict in {l.SolveOrderConflict.path} at line {l.SolveOrderConflict .line} </h6> <div class="px-3"> <Atom deps={data.deps} atom={l.SolveOrderConflict.atom} /> </div> <div class="p-3 pb-0"> <Contents contents={l.SolveOrderConflict.contents} /> </div> {:else if l.UnsolveOrderConflict} <h6> Unsolving an order conflict in {l.UnsolveOrderConflict.path} at line {l .UnsolveOrderConflict.line} </h6> <div class="px-3"> <Atom deps={data.deps} atom={l.UnsolveOrderConflict.atom} /> </div> <div class="p-3 pb-0"> <Contents contents={l.UnsolveOrderConflict.contents} /> </div> {:else if l.ResurrectZombie} <h6> Resurrecting zombies in {l.ResurrectZombie.path} at line {l.ResurrectZombie.line} </h6> <div class="px-3"> <Atom deps={data.deps} atom={l.ResurrectZombie.atom} /> </div> <div class="p-3 pb-0"> <Contents contents={l.ResurrectZombie.contents} /> </div> {:else if l.AddRoot} <h6>Add root</h6> <div class="px-3"> <Atom deps={data.deps} atom={l.AddRoot.name} /> <Atom deps={data.deps} atom={l.AddRoot.atom} /> </div> {:else if l.DelRoot} <h6>Del root</h6> <div class="px-3"> <Atom deps={data.deps} atom={l.DelRoot.name} /> <Atom deps={data.deps} atom={l.DelRoot.atom} /> </div> {/if} </li> {/each} {:else} This change cannot be displayed, possibly because it contains binary files. {/if} </ul> </div> <style global> img.profile-picture { width: 50px; height: 50px; border-radius: 50%; padding: 0; background-color: white; } :global { .hash { color: var(--color-neutral-500); } .change-context, .permissions { font-size: 90%; } .change-newvertex-up::before { content: '↑'; } .change-newvertex-down::before { content: '↓'; } div.change_addition::before { content: '+'; } div.change_deletion::before { content: '-'; } div.change_addition::before, div.change_deletion::before { position: relative; margin: -5px; display: inline-block; padding: 5px 15px 5px 5px; } pre.change_deletion, pre.change_addition { overflow: inherit; } .change_deletion code, .change_addition code { padding: 4px 5px !important; margin: -4px 0 !important; display: inline-block !important; } .change_deletion code { color: #721c24; background-color: #f8d7da; } .change_addition code { color: #155724; background-color: #d4edda; } .change-context div { display: inline-block; } .change-context div.context:first-child::before { content: ''; } .change-context div.context::before { content: ', '; } } </style>