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 / EmptyRepo.svelte
3.8 kB 121 lines
1<script lang="ts"> 2 import { resolve } from "$app/paths"; 3 import { getAuth } from "$lib/auth.svelte"; 4 import { createBobbinClient } from "$lib/api/client"; 5 import { count } from "$lib/api/count"; 6 import { createLoad } from "$lib/action.svelte"; 7 import type { RepoInfo } from "./types"; 8 9 interface Props { 10 repo: RepoInfo; 11 /** 12 * Overrides the SSH key lookup, for deterministic stories/tests. 13 * Left unset in real usage, in which case it's figured out from the API. 14 */ 15 hasSshKey?: boolean; 16 } 17 18 let { repo, hasSshKey }: Props = $props(); 19 20 const auth = getAuth(); 21 const isOwner = $derived(auth.currentDid === repo.ownerDid); 22 // same host rewrite as the clone urls 23 const sshHost = $derived( 24 (repo.knot === "knot1.tangled.sh" ? "tangled.org" : repo.knot) 25 .replace(/^[a-z]+:\/\//, "") 26 .split(/[:/]/)[0] 27 ); 28 const remote = $derived(`git@${sshHost}:${repo.repoDid ?? `${repo.ownerHandle}/${repo.name}`}`); 29 30 const keyStatus = createLoad(async (): Promise<boolean | undefined> => { 31 if (hasSshKey !== undefined) { 32 return hasSshKey; 33 } 34 35 const owner = isOwner; 36 const did = auth.currentDid; 37 const serviceUrl = auth.bobbinUrl; 38 if (!owner || !did) return undefined; 39 try { 40 const ctx = createBobbinClient({ serviceUrl }); 41 const result = await count(ctx, "sh.tangled.publicKey.countKeys", did); 42 return result.count > 0; 43 } catch { 44 // safe fallback: guide the owner through generating a key. 45 return false; 46 } 47 }); 48</script> 49 50{#snippet bullet(n: number)} 51 <span 52 class="mr-2 inline-flex size-5 shrink-0 items-center justify-center rounded-full bg-background-inset align-middle typography-monospace-small font-mono" 53 > 54 {n} 55 </span> 56{/snippet} 57 58{#snippet codeBlock(lines: string[])} 59 <pre class="overflow-x-auto rounded-sm bg-background-inset p-3 font-mono text-sm">{lines.join( 60 "\n" 61 )}</pre> 62{/snippet} 63 64{#if isOwner} 65 {#if keyStatus.loading || keyStatus.data === undefined} 66 <div class="py-6" aria-hidden="true"></div> 67 {:else if keyStatus.data} 68 <div class="flex w-full place-content-center"> 69 <div class="flex w-fit flex-col gap-5 py-6 text-sm"> 70 <p>This is an empty repository.</p> 71 <div class="flex flex-col gap-2"> 72 <p class="text-foreground-subtle">…create a new repository on the command line</p> 73 {@render codeBlock([ 74 `echo "# ${repo.name}" >> README.md`, 75 "git init", 76 "git add README.md", 77 'git commit -m "initial commit"', 78 `git branch -M ${repo.defaultBranch}`, 79 `git remote add origin ${remote}`, 80 `git push -u origin ${repo.defaultBranch}` 81 ])} 82 </div> 83 <div class="flex flex-col gap-2"> 84 <p class="text-foreground-subtle"> 85 …or push an existing repository from the command line 86 </p> 87 {@render codeBlock([ 88 `git remote add origin ${remote}`, 89 `git branch -M ${repo.defaultBranch}`, 90 `git push -u origin ${repo.defaultBranch}` 91 ])} 92 </div> 93 </div> 94 </div> 95 {:else} 96 <div class="flex w-full place-content-center"> 97 <div class="flex w-fit flex-col gap-4 py-6 text-sm"> 98 <p>This is an empty repository. To get started:</p> 99 <p> 100 {@render bullet(1)}First, generate a new 101 <a 102 href="https://git-scm.com/book/en/v2/Git-on-the-Server-Generating-Your-SSH-Public-Key" 103 rel="noopener" 104 class="underline">SSH key pair</a 105 >. 106 </p> 107 <p> 108 {@render bullet(2)}Then add the public key from the 109 <a href={resolve("/settings/keys")} class="underline">keys page</a> in your settings. 110 </p> 111 <p> 112 {@render bullet(3)}Configure your remote to 113 <code class="rounded-sm bg-background-inset px-1 font-mono">{remote}</code> 114 </p> 115 <p>{@render bullet(4)}Push!</p> 116 </div> 117 </div> 118 {/if} 119{:else} 120 <p class="py-6 text-center text-foreground-subtle">This is an empty repository.</p> 121{/if}