Files
front-hokm/lib/feature/wallet/presentation/screen/lobby_screen.dart
T

196 lines
7.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:random_avatar/random_avatar.dart';
import '../../../../core/theme/app_theme.dart';
import '../../../../core/widgets/game_ui.dart';
import '../../../auth/presentation/bloc/auth_bloc.dart';
import '../../../auth/presentation/bloc/auth_event.dart';
import '../../domain/entities/wallet_entity.dart';
import '../bloc/daily_status.dart';
import '../bloc/wallet_bloc.dart';
import '../bloc/wallet_event.dart';
import '../bloc/wallet_state.dart';
import '../bloc/wallet_status.dart';
import '../widgets/coin_fly.dart';
import '../widgets/streak_dialog.dart';
part 'lobby_screen.parts.dart';
/// لابی اصلی: کیف‌پول، دکمه بازی/دورهمی/فروشگاه/سکه روزانه.
class LobbyScreen extends StatefulWidget {
const LobbyScreen({super.key});
@override
State<LobbyScreen> createState() => _LobbyScreenState();
}
class _LobbyScreenState extends State<LobbyScreen> {
final _coinKey = GlobalKey(); // چیپِ سکه (مقصدِ پروازِ سکه‌ها)
final _dailyKey = GlobalKey(); // کارتِ هدیه‌ی روزانه (مبدأ)
@override
void initState() {
super.initState();
context.read<WalletBloc>().add(LoadWalletEvent());
}
void _reload() => context.read<WalletBloc>().add(LoadWalletEvent());
Offset? _center(GlobalKey k) {
final box = k.currentContext?.findRenderObject() as RenderBox?;
if (box == null || !box.attached) return null;
return box.localToGlobal(box.size.center(Offset.zero));
}
void _flyCoins() {
final from = _center(_dailyKey);
final to = _center(_coinKey);
if (from != null && to != null && mounted) {
CoinFly.play(context, from: from, to: to);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: GameBackground(
child: BlocConsumer<WalletBloc, WalletBlocState>(
listenWhen: (a, b) => a.dailyStatus != b.dailyStatus,
listener: (context, state) {
final d = state.dailyStatus;
if (d is DailySuccess) {
_flyCoins(); // پروازِ سکه‌ها از کارتِ هدیه به چیپِ سکه
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('سکه روزانه دریافت شد: +${d.amount}')),
);
} else if (d is DailyError) {
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text(d.message)));
}
},
builder: (context, state) {
final st = state.walletStatus;
final wallet = st is WalletLoaded ? st.wallet : null;
return SafeArea(
child: Column(
children: [
_TopBar(
wallet: wallet,
coinKey: _coinKey,
onCoinTap: () => _openShop(context)),
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.fromLTRB(16, 6, 16, 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 6),
const _LobbyHeader(),
const SizedBox(height: 18),
// اکشنِ اصلی: بازیِ سریع.
_PrimaryPlay(
onTap: () async {
await context.push('/game/tiers');
if (context.mounted) _reload();
},
),
const SizedBox(height: 14),
// اکشن‌های ثانویه در گریدِ دوستونه.
GridView.count(
crossAxisCount: 2,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
mainAxisSpacing: 12,
crossAxisSpacing: 12,
childAspectRatio: 1.55,
children: [
_ActionTile(
icon: Icons.group_add,
label: 'دورهمی',
sub: 'بازی با دوستان',
accent: AppColors.accent,
onTap: () async {
await context.push('/private');
if (context.mounted) _reload();
},
),
_ActionTile(
icon: Icons.emoji_events,
label: 'تورنومنت',
sub: 'جایزه بگیر',
accent: const Color(0xFF9B7BE0),
onTap: () async {
await context.push('/tournaments');
if (context.mounted) _reload();
},
),
_ActionTile(
icon: Icons.leaderboard,
label: 'رتبه‌بندی',
sub: 'جدول قهرمانان',
accent: AppColors.gold,
onTap: () => context.push('/leaderboard'),
),
_ActionTile(
icon: Icons.storefront,
label: 'فروشگاه',
sub: 'سکه و آیتم',
accent: AppColors.success,
onTap: () => _openShop(context),
),
],
),
const SizedBox(height: 14),
_DailyCard(
key: _dailyKey,
wallet: wallet,
onTap:
() => StreakDialog.show(
context,
streak: wallet?.dailyStreak ?? 0,
best: wallet?.bestStreak ?? 0,
ready: wallet?.dailyReady ?? true,
nextReward: wallet?.nextDaily ?? 200,
onClaim:
() => context.read<WalletBloc>().add(
ClaimDailyEvent(),
),
),
),
],
),
),
),
TextButton.icon(
onPressed: () {
context.read<AuthBloc>().add(LogoutEvent());
context.go('/login');
},
icon: const Icon(
Icons.logout,
color: Colors.white38,
size: 18,
),
label: const Text(
'خروج از حساب',
style: TextStyle(color: Colors.white38, fontSize: 13),
),
),
],
),
);
},
),
),
);
}
Future<void> _openShop(BuildContext context) async {
await context.push('/shop');
if (context.mounted) _reload();
}
}