chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
import { useState } from 'react';
import { cn } from '#/lib/utils.js';
/**
* A square app tile. A borderless rounded frame keeps every app icon the same
* shape while the favicon, of whatever shape or transparency, sits centered
* within it. The source is asked to 404 rather than serve a placeholder when it
* has no icon (`fallback=false`), so a genuinely iconless domain falls through
* to a clean initial instead of a generic glyph. Resolved client-side, so it
* needs no endpoint. `domain` is a registrable host like `bsky.app`; `label`
* seeds the fallback letter when there is no domain.
*/
export function AppTile({ domain, label, size = 40, className }) {
const [broken, setBroken] = useState(false);
const letter = (label || domain || '?').slice(0, 1).toUpperCase();
const showIcon = domain && !broken;
return (
<div
className={cn(
'flex shrink-0 items-center justify-center overflow-hidden rounded-xl bg-muted font-extrabold text-muted-foreground',
className,
)}
style={{ width: size, height: size, fontSize: Math.round(size * 0.42) }}
>
{showIcon ? (
<img
src={`https://unavatar.io/${encodeURIComponent(domain)}?fallback=false`}
alt=""
width={Math.round(size * 0.62)}
height={Math.round(size * 0.62)}
className="object-contain"
onError={() => setBroken(true)}
/>
) : (
letter
)}
</div>
);
}