Something went wrong. Try again.
An atproto AppView for tracking a Magic: The Gathering collection github.com/eth0net/manaweb
appview atproto mtg rust typescript
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162import type { OAuthSession } from "@atproto/oauth-client-browser";import { useCallback, useEffect, useState } from "react";import { oauth, restore } from "./client";
export type State = // Reading the session back on page load, before anything can be shown. | { status: "restoring" } // Leaving for the authorization server, which is a different wait: it was // asked for, and whatever asked has to stay up to say so if it fails. | { status: "signing" } | { status: "out"; error?: string } | { status: "in"; session: OAuthSession };
export type Session = ReturnType<typeof useSession>;
export function useSession() { const [state, setState] = useState<State>({ status: "restoring" });
useEffect(() => { let live = true; restore().then( (result) => { if (!live) return; setState( result ? { status: "in", session: result.session } : { status: "out" }, ); }, (error: unknown) => { if (live) setState({ status: "out", error: reason(error) }); }, ); return () => { live = false; }; }, []);
// Resolves only on failure: success navigates to the authorization server. const signIn = useCallback(async (handle: string) => { setState({ status: "signing" }); try { const client = await oauth(); await client.signIn(handle.trim()); } catch (error) { setState({ status: "out", error: reason(error) }); } }, []);
const signOut = useCallback(async () => { if (state.status !== "in") return; await state.session.signOut(); setState({ status: "out" }); }, [state]);
return { state, signIn, signOut };}
function reason(error: unknown): string { return error instanceof Error ? error.message : String(error);}