import { useState, useEffect } from 'react' import { usersApi } from '@/api' // Глобальный кэш для blob URL аватарок const avatarCache = new Map() interface UserAvatarProps { userId: number hasAvatar: boolean // Есть ли у пользователя avatar_url nickname: string size?: 'sm' | 'md' | 'lg' className?: string } const sizeClasses = { sm: 'w-8 h-8 text-xs', md: 'w-12 h-12 text-sm', lg: 'w-24 h-24 text-xl', } export function UserAvatar({ userId, hasAvatar, nickname, size = 'md', className = '' }: UserAvatarProps) { const [blobUrl, setBlobUrl] = useState(null) const [failed, setFailed] = useState(false) useEffect(() => { if (!hasAvatar) { setBlobUrl(null) return } // Проверяем кэш const cached = avatarCache.get(userId) if (cached) { setBlobUrl(cached) return } // Загружаем аватарку let cancelled = false usersApi.getAvatarUrl(userId) .then(url => { if (!cancelled) { avatarCache.set(userId, url) setBlobUrl(url) } }) .catch(() => { if (!cancelled) { setFailed(true) } }) return () => { cancelled = true } }, [userId, hasAvatar]) const sizeClass = sizeClasses[size] if (blobUrl && !failed) { return ( {nickname} ) } // Fallback - первая буква никнейма return (
{nickname.charAt(0).toUpperCase()}
) } // Функция для очистки кэша конкретного пользователя (после загрузки нового аватара) export function clearAvatarCache(userId: number) { const cached = avatarCache.get(userId) if (cached) { URL.revokeObjectURL(cached) avatarCache.delete(userId) } }