johnandersen777.bsky.social/knotless
git that lives in your Atmosphere account
Forked from chadtmiller.com/knotless
0
0
<script lang="ts">
import type * as createRepo from '#lib/lexicons/dev/knotless/createRepo.ts';
import { goto } from '$app/navigation';
import { call } from '#lib/data.ts';
import { repoHref } from '#lib/format.ts';
import NameCheck from '#lib/molecules/NameCheck.svelte';
/**
* Making a repository in the account `owner`, by handle, as `knotless
* create` does: its name, what it is, the branch its first push
* starts, and whether it is public or private (`--private`); then on to
* it, which says how to push. Private is offered but not yet open when
* `spaces` is false: their PDS has no spaces to hold one.
*/
let { owner, spaces }: { owner: string; spaces?: boolean } = $props();
let name = $state('');
let description = $state('');
let branch = $state('');
let visibility = $state('public');
let problem = $state('');
let busy = $state(false);
let blocked = $state(false);
async function submit(e: SubmitEvent) {
e.preventDefault();
busy = true;
problem = '';
try {
const made = await call<typeof createRepo.main>('dev.knotless.createRepo', {
name,
description,
defaultBranch: branch,
private: visibility === 'private'
});
await goto(repoHref(owner, made.name));
} catch (err) {
problem = (err as Error).message;
}
busy = false;
}
</script>
<form class="form" onsubmit={submit}>
<label for="new-name">Repository name</label>
<div class="owned">
<span class="mute">{owner} /</span><input
id="new-name"
name="name"
maxlength="100"
pattern="[A-Za-z0-9._~\-]+"
autocapitalize="none"
spellcheck="false"
required
bind:value={name}
/>
</div>
<NameCheck {owner} {name} bind:blocked />
<p class="hint">
Letters, digits, and <code>.</code> <code>-</code> <code>_</code> <code>~</code>. It is the
repository's address: <code>knotless://{owner}/{name || 'name'}</code>
</p>
<label for="new-description">Description <span class="mute">(optional)</span></label>
<input id="new-description" name="description" maxlength="300" bind:value={description} />
<label for="new-branch">Default branch</label>
<input
id="new-branch"
name="defaultBranch"
placeholder="main"
maxlength="255"
autocapitalize="none"
spellcheck="false"
bind:value={branch}
/>
<fieldset class="choice" aria-label="Visibility">
<label class="check"
><input type="radio" name="visibility" value="public" bind:group={visibility} /><span
><b>Public</b><span class="hint"
>Anyone on the internet can see it. You choose who can push to it.</span
></span
></label
>
<label class="check"
><input
type="radio"
name="visibility"
value="private"
disabled={spaces === false}
bind:group={visibility}
/><span
><b>Private</b><span class="hint"
>{spaces === false
? 'Not on your PDS yet: a private repository lives in a space, which your PDS does not have.'
: 'Only you, the accounts you share it with, and its runners can see it. It lives in a space on your PDS.'}</span
></span
></label
>
</fieldset>
{#if problem}<p class="problem" role="alert">{problem}</p>{/if}
<div>
<button class="btn primary" type="submit" disabled={busy || blocked} aria-busy={busy}
>{busy ? 'Creating…' : 'Create repository'}</button
>
</div>
</form>