This repository has no description
1<script lang="ts">
2 import ChevronDown from "$icon/chevron-down";
3 import ArrowRight from "$icon/arrow-right";
4 import User from "$lib/components/ui/User.svelte";
5 import PullStatePill, { type PullStatePillVariants } from "./PullStatePill.svelte";
6
7 interface PullVersion {
8 base: string;
9 head: string;
10 comments: unknown[];
11 }
12
13 interface Props {
14 state: PullStatePillVariants["state"];
15 versions: PullVersion[];
16 authorHandle: string;
17 authorDid: string;
18 }
19
20 let { state, versions, authorHandle, authorDid }: Props = $props();
21
22 // the appview rings the whole history panel in the pull's state colour
23 const accents = {
24 open: "border-border-success",
25 merged: "border-background-info-emphasis",
26 closed: "border-border-strong",
27 abandoned: "border-border-strong"
28 };
29 const accent = $derived(accents[state ?? "open"]);
30
31 const comments = $derived(versions.reduce((total, v) => total + v.comments.length, 0));
32 const plural = (n: number, noun: string) => `${n} ${noun}${n === 1 ? "" : "s"}`;
33 const short = (hash: string) => hash.slice(0, 7);
34</script>
35
36<details open class="group/history flex flex-col">
37 <summary
38 class="flex list-none items-center justify-between gap-2 rounded-t-sm border-t-2 px-1 py-2 {accent}"
39 >
40 <div class="flex items-center gap-2">
41 <span class="lg:hidden"><PullStatePill {state} /></span>
42 <h2 class="typography-heading-4">History</h2>
43 </div>
44 <div class="flex items-center gap-2 typography-paragraph-small text-foreground-subtle">
45 <span>{plural(versions.length, "version")}</span>
46 <span class="before:content-['·']"></span>
47 <span>{plural(comments, "comment")}</span>
48 <ChevronDown class="size-4 shrink-0 group-open/history:rotate-180" aria-hidden="true" />
49 </div>
50 </summary>
51
52 <div class="flex flex-col gap-4 overflow-y-auto pb-4 lg:max-h-[calc(100vh-3rem)]">
53 {#each versions as version, index (index)}
54 {@const active = index === versions.length - 1}
55 <div class="overflow-clip rounded-sm border border-border-default">
56 <header
57 class="flex gap-2 px-3 py-2 {active ? 'bg-background-inset' : 'bg-background-default'}"
58 >
59 <div class="flex min-w-0 flex-1 flex-col gap-1">
60 <div
61 class="flex flex-wrap items-center gap-1 typography-paragraph-small text-foreground-subtle"
62 >
63 <User handle={authorHandle} did={authorDid} size="small" />
64 submitted
65 <span class="rounded-sm bg-background-muted px-1 typography-monospace-small"
66 >#{index}</span
67 >
68 </div>
69 <div
70 class="flex items-center gap-1 typography-monospace-small text-foreground-muted"
71 title="{version.base} → {version.head}"
72 >
73 {short(version.base)}
74 <ArrowRight class="size-3 shrink-0" aria-hidden="true" />
75 {short(version.head)}
76 </div>
77 </div>
78 </header>
79
80 <!-- todo: this version's comments, then the merge check and the
81 merge/close/resubmit actions on the latest one -->
82 <div class="border-t border-border-default px-3 py-2 typography-paragraph-small">
83 {#if version.comments.length === 0}
84 <span class="text-foreground-subtle italic">No comments</span>
85 {/if}
86 </div>
87 </div>
88 {/each}
89 </div>
90</details>