import { useState, useEffect } from 'react' import { usersApi } from '@/api' // Глобальный кэш для blob URL аватарок const avatarCache = new Map() // Пользователи, для которых нужно сбросить HTTP-кэш при следующем запросе const needsCacheBust = new Set() interface UserAvatarProps { userId: number hasAvatar: boolean // Есть ли у пользователя avatar_url nickname: string size?: 'sm' | 'md' | 'lg' className?: string version?: number // Для принудительного обновления при смене аватара } 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 = '', version = 0 }: UserAvatarProps) { const [blobUrl, setBlobUrl] = useState(null) const [failed, setFailed] = useState(false) useEffect(() => { if (!hasAvatar) { setBlobUrl(null) return } // Если version > 0, значит аватар обновился - сбрасываем кэш const shouldBustCache = version > 0 || needsCacheBust.has(userId) // Проверяем кэш только если не нужен bust if (!shouldBustCache) { const cached = avatarCache.get(userId) if (cached) { setBlobUrl(cached) return } } // Очищаем старый кэш если bust if (shouldBustCache) { const cached = avatarCache.get(userId) if (cached) { URL.revokeObjectURL(cached) avatarCache.delete(userId) } needsCacheBust.delete(userId) } // Загружаем аватарку let cancelled = false usersApi.getAvatarUrl(userId, shouldBustCache) .then(url => { if (!cancelled) { avatarCache.set(userId, url) setBlobUrl(url) } }) .catch(() => { if (!cancelled) { setFailed(true) } }) return () => { cancelled = true } }, [userId, hasAvatar, version]) 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) } // Помечаем, что при следующем запросе нужно сбросить HTTP-кэш браузера needsCacheBust.add(userId) }