import { useQueries } from '@tanstack/react-query'; import { Copyable } from '#/components/molecules/copyable.jsx'; import { identityOf } from '#/lib/identity.js'; import { cn } from '#/lib/utils.js'; /** * An AT-URI with the DIDs in it read as handles. * * A space URI names its authority by DID, and a record URI in a space names the * authority and the author, so the part a reader can act on is bracketed by two * opaque strings. Each is shown as its handle instead. * * Two rules keep the substitution honest. Only a handle that resolves back to * the DID is used, because a URI reads as a fact and an unconfirmed handle in * one would be somebody else's name on an address. And the copy is always the * canonical URI, DIDs and all, since that is the thing that works when pasted * anywhere else. * * @param {Object} props * @param {string} props.uri * @param {string} [props.className] */ export function AtUri({ uri, className }) { const segments = uri.startsWith('at://') ? uri.slice('at://'.length).split('/') : uri.split('/'); const dids = [...new Set(segments.filter((s) => s.startsWith('did:')))]; // useQueries rather than a hook per DID: the number of DIDs is a property of // the URI, and a URI that changes would otherwise change the hook count. const results = useQueries({ queries: dids.map((did) => ({ queryKey: ['identity', did], queryFn: () => identityOf(did), retry: false, staleTime: Number.POSITIVE_INFINITY, })), }); /** @type {Map} */ const handles = new Map(); dids.forEach((did, index) => { const found = results[index]?.data; if (found?.handle && found.verified) handles.set(did, found.handle); }); // Keyed by where each segment starts in the URI. A URI may name the same DID // twice, as one does when its authority is also the author, so the text is // not unique but the offset always is. let offset = 0; const parts = segments.map((segment) => { const at = offset; offset += segment.length + 1; return { at, segment, handle: handles.get(segment) }; }); return ( {uri.startsWith('at://') && 'at://'} {parts.map(({ at, segment, handle }) => ( {at > 0 && '/'} {handle ? ( {handle} ) : ( segment )} ))} ); }