feat: phase 1 of improve

This commit is contained in:
2026-07-08 00:17:46 +03:30
parent 0bd2b4a18a
commit ffd2646eea
6 changed files with 461 additions and 135 deletions
@@ -2,6 +2,7 @@ import 'dart:async';
import 'package:flame/game.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show HapticFeedback;
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:random_avatar/random_avatar.dart';
@@ -20,6 +21,7 @@ import '../../domain/entities/game_entities.dart';
import '../bloc/game_bloc.dart';
import '../bloc/game_state.dart';
import '../../../chat/presentation/widgets/chat_panel.dart';
import '../widgets/confetti.dart';
import '../widgets/flame/hokm_game.dart';
import '../widgets/table_hud.dart';
@@ -94,7 +96,10 @@ class _GameScreenState extends State<GameScreen> {
final won =
state.gameOver!.winnerTeam ==
(state.state?.yourSeat ?? 0) % 2;
if (won) AppSounds.win();
if (won) {
AppSounds.win();
HapticFeedback.mediumImpact();
}
}
if (state.notice != null) {
ScaffoldMessenger.of(context).showSnackBar(
@@ -619,60 +624,114 @@ class _GameScreenState extends State<GameScreen> {
final g = s.gameOver!;
final mySeat = s.state?.yourSeat ?? 0;
final won = g.winnerTeam == mySeat % 2;
return Container(
color: Colors.black87,
alignment: Alignment.center,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
won ? 'بردید! 🎉' : 'باختید',
style: TextStyle(
color: won ? AppColors.gold : Colors.redAccent,
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 12),
Text(
'نتیجه نهایی: ${g.scores.isNotEmpty ? g.scores[0] : 0} - ${g.scores.length > 1 ? g.scores[1] : 0}',
style: const TextStyle(color: Colors.white70, fontSize: 18),
),
// امتیازِ کسب‌شده‌ی تورنومنت (برد ۱۰۰، شرکت ۲۵ — قانونِ ثابتِ سرور).
if (_tournament != null) ...[
const SizedBox(height: 16),
Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
decoration: BoxDecoration(
color: AppColors.gold.withValues(alpha: 0.12),
borderRadius: BorderRadius.circular(14),
border: Border.all(color: AppColors.gold),
),
child: Row(mainAxisSize: MainAxisSize.min, children: [
const Icon(Icons.emoji_events, color: AppColors.gold, size: 20),
const SizedBox(width: 8),
Text(
'+${won ? 100 : 25} امتیاز تورنومنت «${_tournament!.title}»',
style: const TextStyle(
color: AppColors.gold,
fontSize: 14,
fontWeight: FontWeight.bold),
return Stack(
children: [
const Positioned.fill(child: ColoredBox(color: Colors.black87)),
if (won) const Positioned.fill(child: Confetti()),
Center(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// مدالِ متحرک (تاجِ طلایی برای برد، نشانِ ملایم برای باخت).
TweenAnimationBuilder<double>(
tween: Tween(begin: 0, end: 1),
duration: const Duration(milliseconds: 650),
curve: Curves.easeOutBack,
builder: (_, v, __) => Transform.scale(
scale: v.clamp(0.0, 1.2),
child: Container(
width: 100,
height: 100,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: won
? const [AppColors.gold, AppColors.goldDark]
: [Colors.grey.shade700, Colors.grey.shade900],
),
border: Border.all(
color: won ? Colors.white70 : Colors.white24,
width: 2),
boxShadow: won
? [
BoxShadow(
color: AppColors.gold
.withValues(alpha: 0.55),
blurRadius: 28),
]
: null,
),
child: Icon(
won
? Icons.emoji_events
: Icons.sentiment_dissatisfied_outlined,
color: won ? AppColors.lapisInk : Colors.white54,
size: 54,
),
),
),
),
]),
),
],
const SizedBox(height: 28),
SizedBox(
width: 220,
child: ElevatedButton(
onPressed: () => _exitToLobby(context),
child: const Text('بازگشت به لابی'),
const SizedBox(height: 16),
Text(
won ? 'بردید! 🎉' : 'باختید',
style: TextStyle(
color: won ? AppColors.gold : Colors.redAccent,
fontSize: 34,
fontWeight: FontWeight.bold,
shadows: const [Shadow(color: Colors.black, blurRadius: 8)],
),
),
const SizedBox(height: 10),
Text(
'نتیجه نهایی: ${g.scores.isNotEmpty ? g.scores[0] : 0} - ${g.scores.length > 1 ? g.scores[1] : 0}',
style: const TextStyle(color: Colors.white70, fontSize: 18),
),
// پاداشِ سکه‌ی برد (جایزه‌ی میز).
if (won && widget.prize > 0) ...[
const SizedBox(height: 16),
_rewardChip(
Icons.monetization_on, '+${widget.prize} سکه'),
],
// امتیازِ کسب‌شده‌ی تورنومنت (برد ۱۰۰، شرکت ۲۵).
if (_tournament != null) ...[
const SizedBox(height: 12),
_rewardChip(Icons.emoji_events,
'+${won ? 100 : 25} امتیاز تورنومنت «${_tournament!.title}»'),
],
const SizedBox(height: 30),
SizedBox(
width: 220,
child: ElevatedButton(
onPressed: () => _exitToLobby(context),
child: const Text('بازگشت به لابی'),
),
),
],
),
),
],
),
),
],
);
}
Widget _rewardChip(IconData icon, String text) => Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
decoration: BoxDecoration(
color: AppColors.gold.withValues(alpha: 0.12),
borderRadius: BorderRadius.circular(14),
border: Border.all(color: AppColors.gold),
),
child: Row(mainAxisSize: MainAxisSize.min, children: [
Icon(icon, color: AppColors.gold, size: 20),
const SizedBox(width: 8),
Text(text,
style: const TextStyle(
color: AppColors.gold,
fontSize: 14,
fontWeight: FontWeight.bold)),
]),
);
}
/// آواتارِ در حالِ تغییر برای جایگاه‌های خالیِ پنل جستجو (حسِ «در حال یافتن»).