This repository has no description
1<script lang="ts">
2 import { resolve } from "$app/paths";
3 import GitFork from "$icon/git-fork";
4 import Globe from "$icon/globe";
5 import Star from "$icon/star";
6 import Avatar from "$lib/components/ui/Avatar.svelte";
7 import Button from "$lib/components/ui/Button.svelte";
8 import ButtonGroup from "$lib/components/ui/ButtonGroup.svelte";
9 import Tag from "$lib/components/ui/Tag.svelte";
10 import { getAuth } from "$lib/auth.svelte";
11 import StarButton from "./StarButton.svelte";
12 import type { RepoCounts, RepoInfo } from "./types";
13
14 interface Props {
15 repo: RepoInfo;
16 counts: RepoCounts;
17 viewerStarRkey?: string | null;
18 }
19
20 let { repo, counts, viewerStarRkey }: Props = $props();
21
22 const auth = getAuth();
23 const signedIn = $derived(Boolean(auth.currentDid));
24 const base = $derived(`/${repo.ownerHandle}/${repo.name}`);
25 const trimScheme = (url: string) => url.replace(/^https?:\/\//, "").replace(/\/$/, "");
26</script>
27
28<section class="mb-2 px-4 py-2">
29 <div class="mb-2 flex flex-col items-start justify-between gap-4 sm:flex-row">
30 <div class="flex min-w-0 flex-col gap-2">
31 <div class="flex flex-wrap items-center gap-2 text-lg">
32 <a
33 href={resolve(`/${repo.ownerHandle}` as "/")}
34 class="flex items-center gap-2 text-foreground-default no-underline hover:underline"
35 >
36 <Avatar did={repo.ownerDid} handle={repo.ownerHandle} size="size-6" tiny />
37 {repo.ownerHandle}
38 </a>
39 <span class="text-foreground-subtle select-none">/</span>
40 <a
41 href={resolve(`/${repo.ownerHandle}/${repo.name}` as "/")}
42 class="font-bold text-foreground-default no-underline hover:underline"
43 >
44 {repo.name}
45 </a>
46 </div>
47
48 {#if repo.source}
49 <div class="flex flex-wrap items-center gap-1 text-sm text-foreground-muted">
50 <GitFork class="size-3 shrink-0" aria-hidden="true" />
51 <span>forked from</span>
52 <a
53 href={resolve(`/${repo.source.ownerHandle}/${repo.source.name}` as "/")}
54 class="underline"
55 >
56 {repo.source.ownerHandle}/{repo.source.name}
57 </a>
58 </div>
59 {/if}
60 </div>
61
62 <div class="flex shrink-0 items-start gap-2">
63 {#if signedIn}
64 <StarButton
65 repoDid={repo.repoDid ?? ""}
66 repoOwnerHandle={repo.ownerHandle}
67 repoName={repo.name}
68 initialCount={counts.stars}
69 initialRkey={viewerStarRkey}
70 />
71 {:else}
72 <Button
73 href={resolve(`${base}/stars` as "/")}
74 variant="default"
75 size="sm"
76 icon={Star}
77 title="Starred by"
78 >
79 {counts.stars}
80 </Button>
81 {/if}
82
83 <ButtonGroup>
84 <Button href={resolve(`${base}/fork` as "/")} variant="default" size="sm" icon={GitFork}>
85 Fork
86 </Button>
87 <Button
88 href={resolve(`${base}/forks` as "/")}
89 variant="default"
90 size="sm"
91 title="Forked by"
92 >
93 {counts.forks}
94 </Button>
95 </ButtonGroup>
96 </div>
97 </div>
98
99 <div class="flex flex-wrap items-center gap-x-4 gap-y-2 text-sm text-foreground-muted">
100 {#if repo.description}
101 <span>{repo.description}</span>
102 {:else}
103 <span class="italic">This repository has no description</span>
104 {/if}
105
106 {#if repo.website}
107 <span class="flex items-center gap-1">
108 <Globe class="size-4 shrink-0" aria-hidden="true" />
109 <a href={repo.website} rel="external ugc nofollow noopener noreferrer"
110 >{trimScheme(repo.website)}</a
111 >
112 </span>
113 {/if}
114
115 {#if repo.topics?.length}
116 <div class="flex flex-wrap items-center gap-1">
117 {#each repo.topics as topic (topic)}
118 <Tag color="gray">{topic}</Tag>
119 {/each}
120 </div>
121 {/if}
122 </div>
123</section>