StarButton
uses useState
A library's stars, and the visitor's, as a toggle (React Aria's ToggleButton): starring writes a codes.tcm.star
record to their own repository (one per library, across its versions), and taking it back deletes it; the registry checks
it there at once. Signed out, or if it doesn't work, a toast says so.
import { STAR_COLLECTION, starKey, starRecord } from "#codebase/tcmts/records"; import { restar } from "#codebase/tcmts/registry"; import { registrySession } from "#codebase/tcmts/registry/session"; import { toasts } from "#codebase/tcmts/share"; import { useState } from "react"; import { ToggleButton } from "react-aria-components"; export function StarButton({ author, pkg, count, starred, }: { author: string; pkg: string; count: number; starred: boolean; }) { const [shown, setShown] = useState({ count, starred }); const [busy, setBusy] = useState(false); const press = async () => { const s = await registrySession(); if (!s) return void toasts.add( { title: "Sign in to star it", description: "A star is a record in your own repository: sign in with your handle first.", }, { timeout: 6000 }, ); setBusy(true); try { const rkey = starKey(author, pkg); const res = await s.fetch( `/xrpc/com.atproto.repo.${shown.starred ? "deleteRecord" : "putRecord"}`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ repo: s.did, collection: STAR_COLLECTION, rkey, ...(shown.starred ? {} : { record: starRecord(author, pkg), }), }), }, ); if (!res.ok) throw new Error(`your server said ${res.status}`); setShown(await restar(s.did, author, pkg)); } catch (e) { toasts.add( { title: shown.starred ? "Couldn't take the star back" : "Couldn't star it", description: (e as Error).message, tone: "bad", }, { timeout: 8000 }, ); } finally { setBusy(false); } }; return ( <span className="star"> <ToggleButton className="btn small" isSelected={shown.starred} isDisabled={busy} onChange={() => void press()} > {shown.starred ? "★ Starred" : "☆ Star"} <span className="count">{shown.count}</span> </ToggleButton> </span> ); }
uses
- tcmts.records.STAR_COLLECTION
- tcmts.records.starKey
- tcmts.records.starRecord
- tcmts.registry.restar
- tcmts.registry.session.registrySession
- tcmts.share.toasts