johnandersen777.bsky.social/knotless
git that lives in your Atmosphere account
Forked from chadtmiller.com/knotless
0
0
<script lang="ts">
import type { ViewerState } from '#lib/lexicons/dev/knotless/getThread.ts';
import type * as putSubscription from '#lib/lexicons/dev/knotless/putSubscription.ts';
import type { AtUriString } from '@atproto/lex';
import { call } from '#lib/data.ts';
import Icon from '#lib/atoms/Icon.svelte';
/**
* Whether whoever is logged in hears of new comments on the pull or
* issue `subject`, and the way to change it, as `viewer` says: one they
* hear of for their part in it is muted by unsubscribing, and one they
* hear nothing of is subscribed to.
*/
let { subject, viewer, noun }: { subject: AtUriString; viewer?: ViewerState; noun: string } =
$props();
let chosen = $state<string | null | undefined>(undefined);
const subscription = $derived(
chosen === undefined ? viewer?.subscription : (chosen ?? undefined)
);
const reason = $derived(viewer?.notifiedFor);
const hearing = $derived(subscription === 'subscribed' || (subscription !== 'muted' && !!reason));
const why = $derived(
subscription === 'muted'
? `You muted this ${noun}.`
: subscription === 'subscribed'
? `You subscribed to this ${noun}.`
: reason === 'author'
? `You hear of this ${noun} as its author.`
: reason === 'commented'
? `You hear of this ${noun} since you commented.`
: reason === 'watching'
? 'You hear of this as you watch the repository.'
: `You hear of this ${noun} only when mentioned.`
);
let busy = $state(false);
async function toggle() {
busy = true;
// Off: muted if a part in it would still be heard of; on: back to
// that part, or subscribed when there is none.
const level = hearing
? reason
? 'muted'
: 'participating'
: reason
? 'participating'
: 'subscribed';
const now = await call<typeof putSubscription.main>('dev.knotless.putSubscription', {
subject,
level
}).catch(() => null);
if (now) chosen = now.level === 'participating' ? null : now.level;
busy = false;
}
</script>
<button
class="btn"
type="button"
title={why}
aria-pressed={hearing}
disabled={busy}
aria-busy={busy}
onclick={toggle}
><Icon name="bell" /><span class="word">{hearing ? 'Unsubscribe' : 'Subscribe'}</span></button
>