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

johnandersen777.bsky.social/knotless

git that lives in your Atmosphere account

Forked from chadtmiller.com/knotless

0
0
61 lines · 2.1 KB Raw History
<script lang="ts">
	import type { RepoViewDetailed } from '#lib/lexicons/dev/knotless/defs.ts';
	import type * as putSubscription from '#lib/lexicons/dev/knotless/putSubscription.ts';
	import { call } from '#lib/data.ts';
	import Icon from '#lib/atoms/Icon.svelte';
	/** What whoever is logged in hears of `repo`: only what they take part in, all it does, its releases, or nothing; chosen here, as `knotless notification watch` does. */
	let { repo }: { repo: RepoViewDetailed } = $props();
	const LEVELS = [
		['participating', 'Participating', 'Only what you take part in, and mentions.'],
		['all', 'All activity', 'Pulls, issues, comments and releases.'],
		['releases', 'Releases', 'Only new releases.'],
		['ignore', 'Ignore', 'Nothing, but reviews asked of you.']
	] as const;
	let chosen = $state<string | undefined>(undefined);
	const level = $derived(chosen ?? repo.viewer?.subscription ?? 'participating');
	let open = $state(false);
	let busy = $state('');
	let problem = $state('');
	async function choose(next: string) {
		busy = next;
		problem = '';
		try {
			const now = await call<typeof putSubscription.main>('dev.knotless.putSubscription', {
				subject: repo.uri,
				level: next
			});
			chosen = now.level;
			open = false;
		} catch (err) {
			problem = (err as Error).message;
		}
		busy = '';
	}
</script>

<details class="popover watch-menu" data-held={busy || undefined} bind:open>
	<summary class="btn"
		><Icon name={level === 'ignore' ? 'eyeClosed' : 'eye'} />{level === 'participating'
			? 'Watch'
			: level === 'ignore'
				? 'Ignoring'
				: 'Watching'}</summary
	>
	<div class="menu">
		<div class="menu-head">Notifications</div>
		{#each LEVELS as [value, name, said] (value)}
			<button
				class="menu-item"
				type="button"
				aria-pressed={level === value}
				disabled={!!busy}
				aria-busy={busy === value}
				onclick={() => choose(value)}
				><span class="tick"
					>{#if level === value}<Icon name="check" />{/if}</span
				><span><b>{name}</b><small>{said}</small></span></button
			>
		{/each}
		{#if problem}<p class="problem" role="alert">{problem}</p>{/if}
	</div>
</details>