// Reusable avatar that prefers an uploaded image and falls back to a coloured // letter circle. Use this everywhere the app needs to render a profile. import { useCachedAvatarUrl } from '../lib/avatarCache'; interface Props { url?: string | null | undefined; displayName?: string | null | undefined; className?: string; // Background gradient classes used when no image is set. Defaults to a // brand-tinted fallback; callers can override (e.g. to colour-by-id). fallbackClass?: string; alt?: string; // Browser loading hint. Use 'eager' for above-the-fold avatars (e.g. the // active conversation header, call tiles). Defaults to 'lazy' so off-screen // avatars (chat list rows, friends list, popovers) don't hammer Supabase // Storage on initial render. loading?: 'eager' | 'lazy'; } export function Avatar({ url, displayName, className = 'h-10 w-10', fallbackClass = 'bg-accent/20 text-accent', alt, loading = 'lazy', }: Props) { const effectiveUrl = useCachedAvatarUrl(url); if (effectiveUrl) { return ( {alt ); } const letter = (displayName ?? '?').trim().charAt(0).toUpperCase() || '?'; return (
{letter}
); }