This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

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