Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
Svelte
at icy/tmrrpn
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899<script lang="ts"> import { resolve } from "$app/paths"; import Button from "$lib/components/ui/Button.svelte"; import UserRoundPlus from "$icon/user-round-plus"; import UserRoundMinus from "$icon/user-round-minus"; import { getAuth } from "$lib/auth.svelte"; import { createFollow, deleteFollow } from "$lib/api/graph"; import { getProfileCounts } from "./counts.svelte"; import type { FollowChange } from "./types"; import { createOptimisticRelation } from "$lib/optimistic.svelte";
interface Props { profileDid: string; initialRkey?: string | null; onCommit?: (change: FollowChange) => void; }
let { profileDid, initialRkey, onCommit }: Props = $props();
const auth = getAuth(); const profileCounts = getProfileCounts(); const signedIn = $derived(Boolean(auth.currentDid)); const isSelf = $derived(auth.currentDid === profileDid); const relation = createOptimisticRelation({ key: () => `${auth.currentDid ?? ""}:${profileDid}`, loadedRkey: () => initialRkey });
const following = $derived(relation.active);
const commit = (change: FollowChange) => { profileCounts?.adjust(change.subjectDid, "followers", change.delta); profileCounts?.adjust(change.viewerDid, "following", change.delta); onCommit?.(change); };
const toggle = async () => { const agent = auth.agent; if (!agent || !relation.known || relation.loading) return; relation.begin(); try { if (relation.active && relation.rkey) { await deleteFollow(agent, relation.rkey); relation.deleted(); commit({ viewerDid: agent.sub, subjectDid: profileDid, following: false, rkey: null, delta: -1 }); } else { const rkey = await createFollow(agent, profileDid); relation.created(rkey); commit({ viewerDid: agent.sub, subjectDid: profileDid, following: true, rkey, delta: 1 }); } } catch { relation.fail(); } };</script>
{#if !isSelf} {#if !signedIn} <Button href={resolve("/login")} variant="default" class="w-full gap-2" insetShadow={true}> <UserRoundPlus class="size-4" aria-hidden="true" /><span>Follow</span> </Button> {:else} <div class="flex w-full flex-col"> <Button variant="default" class="w-full gap-2" insetShadow={true} loading={relation.loading} disabled={!relation.known} onclick={toggle} > {#if following} <UserRoundMinus class="size-4" aria-hidden="true" /> {:else} <UserRoundPlus class="size-4" aria-hidden="true" /> {/if} <span>{following ? "Unfollow" : "Follow"}</span> </Button> {#if relation.failed} <p class="mt-1 typography-paragraph-small text-foreground-danger"> Something went wrong. Try again. </p> {/if} </div> {/if}{/if}