import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:random_avatar/random_avatar.dart'; /// آواتارِ یک بازیکن در کلِ بازی: اگر شخصیتِ آواتاری خریده و انتخاب کرده باشد /// ([imageUrl] یک URL کاملِ svg/png از سرور) همان را نشان می‌دهد؛ وگرنه به آواتارِ /// تصادفیِ پیش‌فرض بر اساسِ [seed] برمی‌گردد. /// /// URLِ تصویر همیشه از backend می‌آید (URL-safe)؛ کلاینت آن را نمی‌سازد. یک منبعِ /// واحد برای رندرِ آواتار در سرِ میز، پروفایل، لابی و فروشگاه (svg با flutter_svg، /// png/jpg با Image.network). class PlayerAvatar extends StatelessWidget { final String seed; // seed آواتارِ تصادفی (fallback) final String imageUrl; // URL کاملِ تصویرِ شخصیت (از سرور) — خالی ⇒ تصادفی final double? size; // اگر null، فضای موجود را پر می‌کند const PlayerAvatar({ super.key, required this.seed, this.imageUrl = '', this.size, }); bool get _hasCharacter => imageUrl.isNotEmpty; @override Widget build(BuildContext context) { final Widget child; if (_hasCharacter) { child = imageUrl.toLowerCase().endsWith('.svg') ? SvgPicture.network( imageUrl, fit: BoxFit.cover, placeholderBuilder: (_) => _fallback(), ) : Image.network( imageUrl, fit: BoxFit.scaleDown, errorBuilder: (_, __, ___) => _fallback(), ); } else { child = _fallback(); } final clipped = ClipOval(child: SizedBox.expand(child: child)); if (size == null) return clipped; return SizedBox(width: size, height: size, child: clipped); } Widget _fallback() => RandomAvatar(seed.isEmpty ? 'hakem-1' : seed); }