1import { type Accessor, createMemo, createResource, Show } from "solid-js";
2import { getUserRepoByRkey } from "../../../util/get_repo";
3import { figureOutHandle } from "../../../util/handle";
4import type { DID } from "../../../util/types";
5import { useRepoInfo } from "../context";
6
7function HeaderItem(props: {
8 path: string;
9 title: string;
10 icon: string;
11 windowPath: Accessor<string>;
12}) {
13 return (
14 <a
15 class={`flex h-full w-min flex-row content-center items-center gap-2 rounded-t px-4 py-1 ${props.windowPath() === props.title ? "bg-white dark:bg-gray-800" : "hover:dark:bg-gray-700/25"}`}
16 href={props.path}
17 >
18 <div class={`iconify ${props.icon}`} />
19 {props.title}
20 </a>
21 );
22}
23
24export function Header(props: { user: string; repo: string }) {
25 const repoInfo = useRepoInfo();
26 const path = createMemo(() => {
27 const path = window.location.pathname.split("/")[3];
28 return ["issues", "pulls", "pipelines"].includes(path) ? path : "overview";
29 });
30
31 const [forkedInfo] = createResource(
32 () => repoInfo()?.repo,
33 (repo) =>
34 (async () => {
35 if (!repo.source) return;
36 const [, , did, , rkey] = repo.source.split("/");
37 if (rkey === repo.rkey) return;
38 return {
39 did: did as DID,
40 repo: await getUserRepoByRkey(did as DID, rkey),
41 };
42 })(),
43 );
44
45 const [forkedHandle] = createResource(forkedInfo, (forkedInfo) =>
46 (async () => await figureOutHandle(forkedInfo.did))(),
47 );
48
49 return (
50 <Show when={repoInfo()} keyed>
51 {(repoInfo) => (
52 <div class="flex flex-col">
53 <div class="m-5 mt-0 flex flex-row items-center justify-between gap-0.5">
54 <div class="flex flex-col gap-1 text-xs">
55 <Show when={forkedInfo()?.repo && forkedHandle()} keyed>
56 <div class="flex flex-row items-center gap-1">
57 <div class="iconify gravity-ui--code-fork" />
58 <span>
59 forked from{" "}
60 <a
61 href={`/${forkedHandle()}/${forkedInfo()!.repo!.name}`}
62 class="underline hover:text-gray-700 dark:hover:text-gray-200"
63 >{`@${forkedHandle()}/${forkedInfo()!.repo!.name}`}</a>
64 </span>
65 </div>
66 </Show>
67 <div class="flex flex-row items-center gap-1 text-base">
68 <a
69 class="hover:text-gray-700 hover:underline dark:hover:text-gray-200"
70 href={`/${props.user}`}
71 >
72 @{props.user}
73 </a>
74 <span class="select-none text-xl">/</span>
75 <a
76 class="font-bold hover:text-gray-700 hover:underline dark:hover:text-gray-200"
77 href={`/${props.user}/${props.repo}`}
78 >
79 {props.repo}
80 </a>
81 </div>
82 <Show when={repoInfo.repo} keyed>
83 {(repo) => <div class="text-xs">{repo.description}</div>}
84 </Show>
85 </div>
86 <div class="flex flex-row gap-2">
87 <button
88 type="button"
89 class="btn flex flex-row items-center gap-1"
90 >
91 <div class="iconify gravity-ui--star" />
92 {repoInfo.stars.toString() || "0"}
93 </button>
94 <button
95 type="button"
96 class="btn flex flex-row items-center gap-1"
97 >
98 <div class="iconify gravity-ui--code-fork" />
99 {repoInfo.forks.toString() || "0"}
100 </button>
101 </div>
102 </div>
103 <div class="mx-4 flex flex-row gap-1">
104 <HeaderItem
105 title="overview"
106 path={`/${props.user}/${props.repo}`}
107 icon="gravity-ui--square-list-ul"
108 windowPath={path}
109 />
110 {/*<HeaderItem
111 title="issues"
112 path={`/${props.user}/${props.repo}/issues`}
113 icon="gravity-ui--circle-minus"
114 windowPath={path}
115 />*/}
116 </div>
117 </div>
118 )}
119 </Show>
120 );
121}