fix:profile

This commit is contained in:
2026-07-10 11:21:44 +03:30
parent b008ec6056
commit a7fb3ed8f9
2 changed files with 148 additions and 105 deletions
@@ -144,20 +144,32 @@ class ProfileScreen extends StatelessWidget {
_StatTile('بریدن', '${s?.cuts ?? ''}', Icons.bolt), _StatTile('بریدن', '${s?.cuts ?? ''}', Icons.bolt),
_StatTile('دست حاکم', '${s?.hakemCount ?? ''}', Icons.workspace_premium), _StatTile('دست حاکم', '${s?.hakemCount ?? ''}', Icons.workspace_premium),
]; ];
final grid = GridView.count( final card = Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
gradient: const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [AppColors.lapisMid, AppColors.lapisLo],
),
borderRadius: BorderRadius.circular(16),
border: Border.all(color: AppColors.goldFaint),
),
child: GridView.count(
crossAxisCount: 2, crossAxisCount: 2,
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
mainAxisSpacing: 10, mainAxisSpacing: 8,
crossAxisSpacing: 10, crossAxisSpacing: 8,
childAspectRatio: 2.2, childAspectRatio: 2.5,
children: tiles, children: tiles,
),
); );
if (d.vip) return grid; if (d.vip) return card;
return Stack( return Stack(
children: [ children: [
Opacity(opacity: 0.3, child: IgnorePointer(child: grid)), Opacity(opacity: 0.3, child: IgnorePointer(child: card)),
Positioned.fill( Positioned.fill(
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -1,7 +1,7 @@
// ویجت‌های خصوصیِ صفحه‌ی پروفایل (کارتِ سرآمد، نوارِ برجسته، کاشی‌ها، شیتِ ویرایش). // ویجت‌های خصوصیِ صفحه‌ی پروفایل (کارتِ سرآمد، نوارِ برجسته، کاشی‌ها، شیتِ ویرایش).
part of 'profile_screen.dart'; part of 'profile_screen.dart';
/// کارتِ سرآمدِ پروفایل: آواتار با حلقه‌ی رتبه، نام، رتبه و نوارِ سطح/XP. /// کارتِ سرآمدِ پروفایل (فشرده و افقی): آواتار در کنارِ نام/رتبه، و نوارِ سطح/XP در پایین.
class _HeroCard extends StatelessWidget { class _HeroCard extends StatelessWidget {
final ProfileEntity profile; final ProfileEntity profile;
final VoidCallback onEdit; final VoidCallback onEdit;
@@ -15,87 +15,50 @@ class _HeroCard extends StatelessWidget {
return GamePanel( return GamePanel(
child: Column( child: Column(
children: [ children: [
Stack(
children: [
Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: grad,
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
boxShadow: [
BoxShadow(
color: grad.first.withValues(alpha: 0.5),
blurRadius: 14,
spreadRadius: 1,
),
],
),
child: Container(
padding: const EdgeInsets.all(3),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: AppColors.bgDark,
),
child: PlayerAvatar(
seed: d.avatar,
imageUrl: d.avatarImg,
size: 90,
),
),
),
Positioned(
bottom: 0,
right: 0,
child: GestureDetector(
onTap: onEdit,
child: Container(
padding: const EdgeInsets.all(7),
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: const LinearGradient(
colors: [Color(0xFFFFD54F), AppColors.goldDark],
),
border: Border.all(color: AppColors.bgDark, width: 2),
),
child: const Icon(
Icons.edit,
color: AppColors.bg,
size: 16,
),
),
),
),
],
),
const SizedBox(height: 12),
Row( Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Flexible(child: GlowText(d.name, size: 22)), _avatar(d, grad),
if (d.vip) ...[const SizedBox(width: 8), const _VipBadge()], const SizedBox(width: 14),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Flexible(child: GlowText(d.name, size: 20)),
if (d.vip) ...[
const SizedBox(width: 8),
const _VipBadge(),
],
], ],
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
RankBadge(tier: d.rankTier, points: d.rankPoints), Align(
alignment: Alignment.centerRight,
child: RankBadge(tier: d.rankTier, points: d.rankPoints),
),
if (d.mobile.isNotEmpty) ...[ if (d.mobile.isNotEmpty) ...[
const SizedBox(height: 6), const SizedBox(height: 6),
Text( Text(
d.mobile, d.mobile,
style: const TextStyle(color: Colors.white38, fontSize: 12), style: const TextStyle(
color: Colors.white38, fontSize: 12),
), ),
], ],
const SizedBox(height: 16), ],
),
),
],
),
const SizedBox(height: 14),
Row( Row(
children: [ children: [
Text( Text(
'سطح ${d.level}', 'سطح ${d.level}',
style: const TextStyle( style: const TextStyle(
color: AppColors.gold, color: AppColors.gold,
fontSize: 13, fontSize: 12,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
@@ -106,12 +69,12 @@ class _HeroCard extends StatelessWidget {
), ),
], ],
), ),
const SizedBox(height: 6), const SizedBox(height: 5),
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular(6), borderRadius: BorderRadius.circular(6),
child: LinearProgressIndicator( child: LinearProgressIndicator(
value: pct.toDouble(), value: pct.toDouble(),
minHeight: 9, minHeight: 8,
backgroundColor: Colors.white10, backgroundColor: Colors.white10,
valueColor: const AlwaysStoppedAnimation(AppColors.gold), valueColor: const AlwaysStoppedAnimation(AppColors.gold),
), ),
@@ -120,6 +83,62 @@ class _HeroCard extends StatelessWidget {
), ),
); );
} }
Widget _avatar(ProfileEntity d, List<Color> grad) {
return Stack(
clipBehavior: Clip.none,
children: [
Container(
padding: const EdgeInsets.all(3),
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: grad,
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
boxShadow: [
BoxShadow(
color: grad.first.withValues(alpha: 0.5),
blurRadius: 12,
spreadRadius: 1,
),
],
),
child: Container(
padding: const EdgeInsets.all(2.5),
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: AppColors.bgDark,
),
child: PlayerAvatar(
seed: d.avatar,
imageUrl: d.avatarImg,
size: 64,
),
),
),
Positioned(
bottom: -2,
right: -2,
child: GestureDetector(
onTap: onEdit,
child: Container(
padding: const EdgeInsets.all(6),
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: const LinearGradient(
colors: [Color(0xFFFFD54F), AppColors.goldDark],
),
border: Border.all(color: AppColors.bgDark, width: 2),
),
child: const Icon(Icons.edit, color: AppColors.bg, size: 14),
),
),
),
],
);
}
} }
/// نوارِ سه‌گانه‌ی برجسته: سطح، جام، امتیازِ رتبه. /// نوارِ سه‌گانه‌ی برجسته: سطح، جام، امتیازِ رتبه.
@@ -199,7 +218,7 @@ class _Highlight extends StatelessWidget {
} }
} }
/// عنوانِ بخش با آیکون (راست‌چین). /// عنوانِ بخش: برچسبِ کوچک و رسمی + خطِ جداکننده‌ی کم‌رنگ (بدونِ درخشش).
class _SectionHeader extends StatelessWidget { class _SectionHeader extends StatelessWidget {
final IconData icon; final IconData icon;
final String title; final String title;
@@ -208,15 +227,28 @@ class _SectionHeader extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return Row(
children: [ children: [
Icon(icon, color: AppColors.gold, size: 18), Icon(icon, color: AppColors.goldDark, size: 15),
const SizedBox(width: 8), const SizedBox(width: 6),
GlowText(title, size: 18), Text(
title,
style: const TextStyle(
color: AppColors.gold,
fontSize: 13,
fontWeight: FontWeight.w600,
letterSpacing: 0.2,
),
),
const SizedBox(width: 10),
Expanded(
child: Container(height: 1, color: AppColors.goldFaint),
),
], ],
); );
} }
} }
/// کاشیِ آماری (آیکون + مقدار + برچسب). accent ⇒ برجسته با قابِ طلایی. /// سلولِ آماری (آیکون + مقدار + برچسب) بدونِ قاب — داخلِ کارتِ واحدِ آمار قرار می‌گیرد.
/// accent ⇒ سلولِ برجسته‌ی «نرخ برد» با تهِ‌رنگِ طلایی.
class _StatTile extends StatelessWidget { class _StatTile extends StatelessWidget {
final String label; final String label;
final String value; final String value;
@@ -226,22 +258,24 @@ class _StatTile extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 7),
decoration: BoxDecoration( decoration: BoxDecoration(
color: color: accent
accent ? AppColors.gold.withValues(alpha: 0.13)
? AppColors.gold.withValues(alpha: 0.14) : Colors.white.withValues(alpha: 0.035),
: AppColors.panel.withValues(alpha: 0.5), borderRadius: BorderRadius.circular(11),
borderRadius: BorderRadius.circular(14), border: accent
border: Border.all( ? Border.all(color: AppColors.gold.withValues(alpha: 0.55))
color: accent ? AppColors.gold : AppColors.goldFaint, : null,
width: accent ? 1.4 : 1,
),
), ),
child: Row( child: Row(
children: [ children: [
Icon(icon, color: AppColors.gold, size: 22), Icon(
const SizedBox(width: 10), icon,
color: accent ? AppColors.gold : AppColors.goldDark,
size: 19,
),
const SizedBox(width: 9),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@@ -249,18 +283,15 @@ class _StatTile extends StatelessWidget {
children: [ children: [
Text( Text(
value, value,
style: const TextStyle( style: TextStyle(
color: Colors.white, color: accent ? AppColors.gold : Colors.white,
fontSize: 17, fontSize: 16,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
Text( Text(
label, label,
style: const TextStyle( style: const TextStyle(color: Colors.white54, fontSize: 11),
color: Colors.white54,
fontSize: 11,
),
), ),
], ],
), ),