Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
2.9 kB · 102 lines
Svelte
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103<script lang="ts"> import Check from "$icon/check"; import { acceptOffer, OfferRefused, permissionsFor } from "$lib/api/accept"; import { errorMessage } from "$lib/api/load"; import { getAuth } from "$lib/auth.svelte"; import { missingPermissions } from "$lib/auth/scopes"; import Button from "$lib/components/ui/Button.svelte"; import type { NotificationOffer } from "$lib/components/notifications/types";
interface Props { offer: NotificationOffer; class?: string; }
let { offer, class: className }: Props = $props();
type Progress = | { kind: "idle" } | { kind: "sending" } | { kind: "accepted" } | { kind: "refused"; message: string };
const auth = getAuth(); const agent = $derived(auth?.agent ?? null); const ungranted = $derived( agent ? missingPermissions(agent.session.token.scope, permissionsFor(offer)) : [] );
let progress = $state<Progress>({ kind: "idle" });
const accept = async () => { if (!agent || progress.kind === "sending") return; progress = { kind: "sending" }; try { await acceptOffer(agent, offer); progress = { kind: "accepted" }; } catch (thrown) { progress = { kind: "refused", message: thrown instanceof OfferRefused ? thrown.sentence(offer.knot) : errorMessage(thrown, "Accepting failed, no reason given.") }; } };
const reauthorize = async () => { const did = auth?.currentDid; if (!did || progress.kind === "sending") return; progress = { kind: "sending" }; try { await auth.signIn(did, location.pathname + location.search + location.hash); } catch (thrown) { progress = { kind: "refused", message: errorMessage(thrown, "Signing in again didn't start.") }; } };</script>
{#if agent} <div class={["relative z-10 flex w-fit max-w-full flex-wrap items-center gap-2", className]}> {#if progress.kind === "accepted"} <span class="flex items-center gap-1.5 typography-paragraph-small text-foreground-success" > <Check class="size-4 shrink-0" aria-hidden="true" />Accepted </span> {:else} {#if ungranted.length > 0} <Button size="small" loading={progress.kind === "sending"} onclick={() => void reauthorize()} > Sign in again to accept </Button> {:else} <Button size="small" variant={progress.kind === "refused" ? "danger" : "primary"} loading={progress.kind === "sending"} insetShadow={true} onclick={() => void accept()} > {progress.kind === "refused" ? "Try again" : "Accept"} </Button> {/if} {#if progress.kind === "refused"} <span class="typography-paragraph-small text-foreground-danger" >{progress.message}</span > {:else if ungranted.length > 0} <span class="typography-paragraph-small text-foreground-muted"> Accepting arrived after you signed in. </span> {/if} {/if} </div>{/if}