import { useQuery } from '@tanstack/react-query'; import { useState } from 'react'; import { nsidDomain } from '#/lib/format.js'; import { appProfileOf } from '#/lib/profile.js'; import { cn } from '#/lib/utils.js'; /** * A square tile standing for the app a space belongs to. * * The picture is the app account's own, read from its own PDS, because an NSID * reverses to a domain and these domains are atproto handles. A favicon would * mean asking the app's web server or an icon service, and either is then told * which apps' spaces this browser is reading. * * A domain that is no handle, or an account with no picture, reads as its * initial. The tile keeps its size either way, so a row does not reflow when a * picture arrives. * * @param {Object} props * @param {string} props.nsid - the space type * @param {number} [props.size] * @param {string} [props.className] */ export function AppTile({ nsid, size = 40, className }) { const [broken, setBroken] = useState(false); const { data } = useQuery({ queryKey: ['app-profile', nsid], queryFn: () => appProfileOf(nsid), retry: false, staleTime: Number.POSITIVE_INFINITY, enabled: Boolean(nsid), }); const src = !broken && data?.avatar; return (