- gen-l10n setup (flutter_localizations, intl, l10n.yaml, ARB en/fr) - localeProvider (persisted) wired into MaterialApp - language selector in the System page (alongside the color palette) - all user-facing strings across screens moved to AppLocalizations Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
102 lines
3.8 KiB
Dart
102 lines
3.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import '../../core/config/app_constants.dart';
|
|
import '../../l10n/app_localizations.dart';
|
|
import '../providers/repository_provider.dart';
|
|
import '../widgets/game_over/game_over_header.dart';
|
|
import '../widgets/game_over/game_over_stats.dart';
|
|
import '../widgets/game_over/game_over_actions.dart';
|
|
import '../widgets/game_over/hinge_divider.dart';
|
|
|
|
/// Écran de fin de partie. Affiche le Pokémon manqué, les stats, et propose de rejouer.
|
|
class GameOverPage extends ConsumerStatefulWidget {
|
|
const GameOverPage({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
ConsumerState<GameOverPage> createState() => _GameOverPageState();
|
|
}
|
|
|
|
class _GameOverPageState extends ConsumerState<GameOverPage> {
|
|
int _seenCount = 0;
|
|
bool _isLoading = true;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_loadSeenCount();
|
|
}
|
|
|
|
Future<void> _loadSeenCount() async {
|
|
final count = await ref.read(pokemonRepositoryProvider).seenCount();
|
|
if (mounted) {
|
|
setState(() {
|
|
_seenCount = count;
|
|
_isLoading = false;
|
|
});
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final args = ModalRoute.of(context)!.settings.arguments as Map<String, dynamic>?;
|
|
final pokemonImage = args?['pokemonImage'] ?? '';
|
|
final pokemonName = args?['pokemonName'] ?? 'Unknown';
|
|
final int streak = args?['streak'] ?? 0;
|
|
final int score = args?['score'] ?? 0;
|
|
|
|
const darkRed = Color(0xFF9E1B1B);
|
|
const silverBg = Color(0xFFC8D1D8);
|
|
const messageBoxBg = Color(0xFF1B2333);
|
|
|
|
return Scaffold(
|
|
backgroundColor: const Color(0xFFD32F2F),
|
|
body: _isLoading
|
|
? const Center(child: CircularProgressIndicator(color: Colors.white))
|
|
: SingleChildScrollView(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Column(
|
|
children: [
|
|
GameOverHeader(pokemonImage: pokemonImage, pokemonName: pokemonName),
|
|
const HingeDivider(),
|
|
Container(
|
|
decoration: BoxDecoration(color: darkRed, border: Border.all(color: darkRed, width: 4)),
|
|
child: Container(
|
|
width: double.infinity,
|
|
padding: const EdgeInsets.all(16),
|
|
color: silverBg,
|
|
child: Column(
|
|
children: [
|
|
Container(
|
|
width: double.infinity,
|
|
color: messageBoxBg,
|
|
padding: const EdgeInsets.all(24),
|
|
child: Text(
|
|
AppLocalizations.of(context)!.gameOverMessage,
|
|
textAlign: TextAlign.center,
|
|
style: const TextStyle(color: Colors.white, fontSize: 18, height: 1.5),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
GameOverStats(
|
|
streak: streak.toString().padLeft(3, '0'),
|
|
seen: "$_seenCount/${AppConstants.totalPokemon}",
|
|
score: "$score",
|
|
),
|
|
const SizedBox(height: 16),
|
|
GameOverActions(
|
|
onTryAgain: () => Navigator.pop(context, true),
|
|
onBack: () => Navigator.pop(context, false),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|