# Avatar System Usage Examples This document provides practical examples of how to use the avatar fetching system in your components. ## Basic Usage ### Simple Avatar Display ```jsx import Avatar from './components/Avatar.jsx' function UserProfile({ user }) { return (

{user.displayName}

) } ``` ### Avatar from Record Data ```jsx function CommentItem({ record }) { return (
{record.value.author.displayName}

{record.value.text}

) } ``` ### Avatar with Hover Card ```jsx import { AvatarWithCard } from './components/Avatar.jsx' function UserList({ users, apiConfig }) { return (
{users.map(user => ( ))}
) } ``` ## Advanced Usage ### Programmatic Avatar Fetching ```jsx import { useEffect, useState } from 'react' import { getAvatar, batchFetchAvatars } from './utils/avatar.js' function useUserAvatars(users) { const [avatars, setAvatars] = useState(new Map()) const [loading, setLoading] = useState(false) useEffect(() => { async function fetchAvatars() { setLoading(true) try { const avatarMap = await batchFetchAvatars(users) setAvatars(avatarMap) } catch (error) { console.error('Failed to fetch avatars:', error) } finally { setLoading(false) } } if (users.length > 0) { fetchAvatars() } }, [users]) return { avatars, loading } } // Usage function TeamDisplay({ team }) { const { avatars, loading } = useUserAvatars(team.members) if (loading) return
Loading team...
return (
{team.members.map(member => ( {member.displayName} ))}
) } ``` ### Force Refresh Avatar ```jsx import { useState } from 'react' import Avatar from './components/Avatar.jsx' import { getAvatar, clearAvatarCache } from './utils/avatar.js' function RefreshableAvatar({ handle, did }) { const [key, setKey] = useState(0) const handleRefresh = async () => { // Clear cache for this user clearAvatarCache(handle) // Force re-render of Avatar component setKey(prev => prev + 1) // Optionally, prefetch fresh avatar try { await getAvatar({ handle, did, forceFresh: true }) } catch (error) { console.error('Failed to refresh avatar:', error) } } return (
) } ``` ### Avatar List with Overflow ```jsx import { AvatarList } from './components/Avatar.jsx' function ParticipantsList({ participants, maxVisible = 5 }) { return (

Participants ({participants.length})

{participants.length > maxVisible && ( and {participants.length - maxVisible} more... )}
) } ``` ## Error Handling ### Custom Error Handling ```jsx import { useState } from 'react' import Avatar from './components/Avatar.jsx' function RobustAvatar({ handle, did, fallbackSrc }) { const [hasError, setHasError] = useState(false) const handleError = (error) => { console.warn(`Avatar failed for ${handle}:`, error) setHasError(true) } if (hasError && fallbackSrc) { return ( Fallback avatar setHasError(false)} // Reset on fallback error /> ) } return ( ) } ``` ### Loading States ```jsx import { useState, useEffect } from 'react' import { getAvatar } from './utils/avatar.js' function AvatarWithCustomLoading({ handle, did }) { const [avatar, setAvatar] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { async function loadAvatar() { try { setLoading(true) setError(null) const avatarUrl = await getAvatar({ handle, did }) setAvatar(avatarUrl) } catch (err) { setError(err.message) } finally { setLoading(false) } } loadAvatar() }, [handle, did]) if (loading) { return
Loading...
} if (error) { return
Failed to load avatar
} if (!avatar) { return
No avatar
} return Avatar } ``` ## Optimization Patterns ### Preloading Strategy ```jsx import { useEffect } from 'react' import { prefetchAvatar } from './utils/avatar.js' function UserCard({ user, isVisible }) { // Preload avatar when component becomes visible useEffect(() => { if (isVisible && user.handle) { prefetchAvatar(user.handle) } }, [isVisible, user.handle]) return (
{isVisible && ( )}

{user.displayName}

) } ``` ### Lazy Loading with Intersection Observer ```jsx import { useState, useEffect, useRef } from 'react' import Avatar from './components/Avatar.jsx' function LazyAvatar({ handle, did, ...props }) { const [isVisible, setIsVisible] = useState(false) const ref = useRef() useEffect(() => { const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) { setIsVisible(true) observer.disconnect() } }, { threshold: 0.1 } ) if (ref.current) { observer.observe(ref.current) } return () => observer.disconnect() }, []) return (
{isVisible ? ( ) : (
)}
) } ``` ## Cache Management ### Cache Statistics Display ```jsx import { useEffect, useState } from 'react' import { getAvatarCacheStats, cleanupExpiredAvatars } from './utils/avatarCache.js' function CacheStatsPanel() { const [stats, setStats] = useState(null) useEffect(() => { const updateStats = () => { setStats(getAvatarCacheStats()) } updateStats() const interval = setInterval(updateStats, 5000) // Update every 5 seconds return () => clearInterval(interval) }, []) const handleCleanup = async () => { const cleaned = cleanupExpiredAvatars() alert(`Cleaned ${cleaned} expired cache entries`) setStats(getAvatarCacheStats()) } if (!stats) return null return (

Avatar Cache Stats

Cached avatars: {stats.totalCached}

Cache hit rate: {stats.hitRate}%

Cache hits: {stats.cacheHits}

Cache misses: {stats.cacheMisses}

) } ``` ## Testing Helpers ### Mock Avatar for Testing ```jsx // For testing environments const MockAvatar = ({ handle, size = 40, showFallback = true }) => { if (!showFallback) return null const initial = (handle || 'U')[0].toUpperCase() return (
{initial}
) } // Use in tests export default process.env.NODE_ENV === 'test' ? MockAvatar : Avatar ``` These examples demonstrate the flexibility and power of the avatar system while maintaining good performance and user experience practices.