~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/knotless

git that lives in your Atmosphere account

Forked from chadtmiller.com/knotless

0
0
102 lines · 3.2 KB Raw History
<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>