Commit f4004953 by Diego Pérez Peña

Merge finalizado con éxito

parents e0afdbe0 0ce0c8c5
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:
synthetic-package: false
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
\ No newline at end of file
{
"yes": "Yes",
"no": "No",
"@yes": {
"description": "Expression of affirmation"
},
"@no": {
"description": "Expression of negation"
},
"highScores": "Hi-Scores",
"highest20Scores": "The 20 all-of-time highest scores ever registered in Peponator!",
"noRecordsYet": "There are currently no registered records.",
"playToRegister": "Play the game, register the first one!",
"deleteHighScores": "Delete Hi-Scores",
"noUndo": "This action cannot be undone.",
"reallyDeleteHiScores": "Do you really want to delete all Hi-Scores?",
"@highScores": {
"description": "Name of the 'High Scores' page"
},
"@highest20Scores": {
"description": "A text describing that the following page contains the 20 highest scores obtained in the game"
},
"@noRecordsYet": {
"description": "Text that informs that there are no registered high scores yet"
},
"@playToRegister": {
"description": "Text that invites the user to play the game in order to register the first high score"
},
"@deleteHighScores": {
"description": "Action of deleting all high scores"
},
"@noUndo": {
"description": "Text that indicates that the action the user is about to do cannot be undone"
},
"@reallyDeleteHiScores": {
"description": "Interrogates the user whether they are sure that they want to delete all of their Hi-Scores"
},
"yourGuess": "Your guess...",
"attempts": "Attempts",
"maximum": "Maximum",
"minimum": "Minimum",
"@yourGuess": {
"description": "Text that awaits user input for its guessed number"
},
"@attempts": {
"description": "Expression for the maximum number of mistakes that the user can make to guess the number"
},
"@maximum": {
"description": "Mathematical expression for the biggest possible number"
},
"@minimum": {
"description": "Mathematical expression for the smallest possible number"
},
"specialHints": "Special Hints",
"hintsWarning": "Watch out! Unlocking them is penalized",
"lockedHint": "Locked Hint",
"tapToUnlock": "Tap to Unlock",
"unlockConfirm": "Are you sure? Tap again to Confirm",
"evenOddHint": "Is it even or odd?",
"divisibleHint": "By which number is it divisible?",
"digitsSumHint": "What do its digits add up to?",
"digitsCountHint": "How many digits does it have?",
"evenNumber": "The number is Even",
"oddNumber": "The number is Odd",
"divisibleBy": "The number is Divisible by {number}",
"primeLessMax": "The number is a Prime Less than {maximum}",
"notDivisibleByPrimes": "The number is NOT Divisible by primes less than {maximum}",
"digitsSum": "The number's digits add up to {total}",
"digitsCount": "The number has {count, plural, =1{1 digit} other{{count} digits}}",
"@specialHints": {
"description": "The title of the page where you can unlock extra hints"
},
"@hintsWarning": {
"description": "A text indicating the user that unlocking hints reduces the total score"
},
"@lockedHint": {
"description": "Expression that indicates that a hint cannot be unlocked"
},
"@tapToUnlock": {
"description": "Expression that invites the user to tap in order to unlock the hint"
},
"@unlockConfirm": {
"description": "Expression that asks the user to tap again if they really want to unlock the hint"
},
"@evenOddHint": {
"description": "Interrogation that asks whether the secret number is even or odd"
},
"@divisibleHint": {
"description": "Interrogation that asks by which number the secret number is divisible"
},
"@digitsSumHint": {
"description": "Interrogation that asks for the total sum of the secret number's digits"
},
"@digitsCountHint": {
"description": "Interrogation that asks how many digits the secret number has"
},
"@evenNumber": {
"description": "Expression that indicates that the secret number is even (divisible by 2)"
},
"@oddNumber": {
"description": "Expression that indicates that the secret number is odd (not divisible by 2)"
},
"@divisibleBy": {
"description": "Expression that indicates that the secret number is divisible by a certain number",
"placeholders": {
"number": {
"type": "num",
"format": "compact"
}
}
},
"@primeLessMax": {
"description": "Expression that indicates that the secret number is a prime less than a certain maximum",
"placeholders": {
"maximum": {
"type": "num",
"format": "compact"
}
}
},
"@notDivisibleByPrimes": {
"description": "Expression that indicates that the secret number is not divisible by any prime numbers less than a certain maximum",
"placeholders": {
"maximum": {
"type": "num",
"format": "compact"
}
}
},
"@digitsSum": {
"description": "Expression that indicates that the secret number's digits' sum is equal to a certain number",
"placeholders": {
"total": {
"type": "num",
"format": "compact"
}
}
},
"@digitsCount": {
"description": "Expression that indicates that the secret number has a certain number of digits",
"placeholders": {
"count": {
"type": "num",
"format": "compact"
}
}
},
"pause": "Pause",
"resume": "Resume",
"changeHand": "Change hand",
"newGame": "New game",
"changeDifficulty": "Change difficulty",
"exitGame": "Exit game",
"@pause": {
"description": "Expression of the frozen state of a game"
},
"@resume": {
"description": "Text that refers to continuing the game from frozen state"
},
"@changeHand": {
"description": "Text that indicates the possibility of changing the dominant hand"
},
"@newGame": {
"description": "Text that refers to starting a new game"
},
"@changeDifficulty": {
"description": "Text that refers to choosing new configurations to make the game easier or harder"
},
"@exitGame": {
"description": "Text that refers to quitting the current game and returning to the main menu"
},
"highestScore": "New hi-score!",
"nthHiScore": "This is your {nth, select, 2{2nd} 3{3rd} other{{nth}th}} highest score",
"enterYourName": "Enter your name:",
"yourName": "Your name...",
"saveHiScore": "Save hi-score",
"dontSaveHiScore": "Exit without saving",
"congratulations": "Congratulations!",
"score": "Score: {score}",
"playAgain": "Play again",
"exitToMainMenu": "Exit to main menu",
"noMoreAttempts": "No more attempts!",
"betterLuck": "Better luck next time...",
"@highestScore": {
"description": "Expression that refers to a new Hi-Score being achieved"
},
"@nthHiScore": {
"description": "Text that refers to achieving the nth highest score",
"placeholders": {
"nth": {
"type": "String"
}
}
},
"@enterYourName": {
"description": "Text that invites the user to enter their first name"
},
"@yourName": {
"description": "Text that refers to the user's first name"
},
"@saveHiScore": {
"description": "Text that indicates the action of saving the hi-score for future reference"
},
"@dontSaveHiScore": {
"description": "Text that indicates the rejection of saving the hi-score for future reference"
},
"@congratulations": {
"description": "Expression of congratulation"
},
"@score": {
"description": "Text that shows the obtained score in the game",
"placeholders": {
"score": {
"type": "num"
}
}
},
"@playAgain": {
"description": "Text that refers to playing a new game"
},
"@exitToMainMenu": {
"description": "Text that refers to returning to the game's main menu"
},
"@noMoreAttempts": {
"description": "Text that indicates that the user used up all of its attempts"
},
"@betterLuck": {
"description": "Expression that wishes better luck for the next time playing"
}
}
\ No newline at end of file
{
"yes": "Sí",
"no": "No",
"highScores": "Récords",
"highest20Scores": "¡Las 20 mejores puntuaciones registradas en Peponator!",
"noRecordsYet": "No hay ningún récord registrado de momento.",
"playToRegister": "¡Juega y registra el primero!",
"deleteHighScores": "Borrar récords",
"noUndo": "Esta acción no se puede deshacer.",
"reallyDeleteHiScores": "¿Seguro que quieres borrar todos los récords?",
"yourGuess": "Tu respuesta...",
"attempts": "Intentos",
"maximum": "Máximo",
"minimum": "Mínimo",
"specialHints": "Pistas Especiales",
"hintsWarning": "¡Atención! Usarlas quita puntos",
"lockedHint": "Pista Bloqueada",
"tapToUnlock": "Toca para Desbloquear",
"unlockConfirm": "¿Seguro? Toca de nuevo para Confirmar",
"evenOddHint": "¿Es par o impar?",
"divisibleHint": "¿Entre qué número es divisible?",
"digitsSumHint": "¿Cuál es la suma de sus cifras?",
"digitsCountHint": "¿Cuántas cifras tiene?",
"evenNumber": "El número es Par",
"oddNumber": "El número es Impar",
"divisibleBy": "El número es divisible entre {number}",
"primeLessMax": "El número es primo inferior a {maximum}",
"notDivisibleByPrimes": "El número NO es divisible entre primos inferiores a {maximum}",
"digitsSum": "La suma de las cifras del número da {total}",
"digitsCount": "El número tiene {count, plural, =1{1 cifra} other{{count} cifras}}",
"pause": "Pausa",
"resume": "Reanudar",
"changeHand": "Cambiar de mano",
"newGame": "Nueva partida",
"changeDifficulty": "Cambiar dificultad",
"exitGame": "Terminar partida",
"highestScore": "¡Esta es tu mejor puntuación!",
"nthHiScore": "Esta es tu {nth}ª mejor puntuación",
"enterYourName": "Introduce aquí tu nombre::",
"yourName": "Tu nombre...",
"saveHiScore": "Guardar récord",
"dontSaveHiScore": "Salir sin guardar",
"congratulations": "¡Enhorabuena!",
"score": "Puntuación: {score}",
"playAgain": "Jugar otra vez",
"exitToMainMenu": "Volver al inicio",
"noMoreAttempts": "¡Sin intentos!",
"betterLuck": "Más suerte la próxima vez..."
}
\ No newline at end of file
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for English (`en`).
class AppLocalizationsEn extends AppLocalizations {
AppLocalizationsEn([String locale = 'en']) : super(locale);
@override
String get yes => 'Yes';
@override
String get no => 'No';
@override
String get highScores => 'Hi-Scores';
@override
String get highest20Scores => 'The 20 all-of-time highest scores ever registered in Peponator!';
@override
String get noRecordsYet => 'There are currently no registered records.';
@override
String get playToRegister => 'Play the game, register the first one!';
@override
String get deleteHighScores => 'Delete Hi-Scores';
@override
String get noUndo => 'This action cannot be undone.';
@override
String get reallyDeleteHiScores => 'Do you really want to delete all Hi-Scores?';
@override
String get yourGuess => 'Your guess...';
@override
String get attempts => 'Attempts';
@override
String get maximum => 'Maximum';
@override
String get minimum => 'Minimum';
@override
String get specialHints => 'Special Hints';
@override
String get hintsWarning => 'Watch out! Unlocking them is penalized';
@override
String get lockedHint => 'Locked Hint';
@override
String get tapToUnlock => 'Tap to Unlock';
@override
String get unlockConfirm => 'Are you sure? Tap again to Confirm';
@override
String get evenOddHint => 'Is it even or odd?';
@override
String get divisibleHint => 'By which number is it divisible?';
@override
String get digitsSumHint => 'What do its digits add up to?';
@override
String get digitsCountHint => 'How many digits does it have?';
@override
String get evenNumber => 'The number is Even';
@override
String get oddNumber => 'The number is Odd';
@override
String divisibleBy(num number) {
final intl.NumberFormat numberNumberFormat = intl.NumberFormat.compact(
locale: localeName,
);
final String numberString = numberNumberFormat.format(number);
return 'The number is Divisible by $numberString';
}
@override
String primeLessMax(num maximum) {
final intl.NumberFormat maximumNumberFormat = intl.NumberFormat.compact(
locale: localeName,
);
final String maximumString = maximumNumberFormat.format(maximum);
return 'The number is a Prime Less than $maximumString';
}
@override
String notDivisibleByPrimes(num maximum) {
final intl.NumberFormat maximumNumberFormat = intl.NumberFormat.compact(
locale: localeName,
);
final String maximumString = maximumNumberFormat.format(maximum);
return 'The number is NOT Divisible by primes less than $maximumString';
}
@override
String digitsSum(num total) {
final intl.NumberFormat totalNumberFormat = intl.NumberFormat.compact(
locale: localeName,
);
final String totalString = totalNumberFormat.format(total);
return 'The number\'s digits add up to $totalString';
}
@override
String digitsCount(num count) {
final intl.NumberFormat countNumberFormat = intl.NumberFormat.compact(
locale: localeName,
);
final String countString = countNumberFormat.format(count);
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$countString digits',
one: '1 digit',
);
return 'The number has $_temp0';
}
@override
String get pause => 'Pause';
@override
String get resume => 'Resume';
@override
String get changeHand => 'Change hand';
@override
String get newGame => 'New game';
@override
String get changeDifficulty => 'Change difficulty';
@override
String get exitGame => 'Exit game';
@override
String get highestScore => 'New hi-score!';
@override
String nthHiScore(String nth) {
String _temp0 = intl.Intl.selectLogic(
nth,
{
'2': '2nd',
'3': '3rd',
'other': '${nth}th',
},
);
return 'This is your $_temp0 highest score';
}
@override
String get enterYourName => 'Enter your name:';
@override
String get yourName => 'Your name...';
@override
String get saveHiScore => 'Save hi-score';
@override
String get dontSaveHiScore => 'Exit without saving';
@override
String get congratulations => 'Congratulations!';
@override
String score(num score) {
return 'Score: $score';
}
@override
String get playAgain => 'Play again';
@override
String get exitToMainMenu => 'Exit to main menu';
@override
String get noMoreAttempts => 'No more attempts!';
@override
String get betterLuck => 'Better luck next time...';
}
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Spanish Castilian (`es`).
class AppLocalizationsEs extends AppLocalizations {
AppLocalizationsEs([String locale = 'es']) : super(locale);
@override
String get yes => 'Sí';
@override
String get no => 'No';
@override
String get highScores => 'Récords';
@override
String get highest20Scores => '¡Las 20 mejores puntuaciones registradas en Peponator!';
@override
String get noRecordsYet => 'No hay ningún récord registrado de momento.';
@override
String get playToRegister => '¡Juega y registra el primero!';
@override
String get deleteHighScores => 'Borrar récords';
@override
String get noUndo => 'Esta acción no se puede deshacer.';
@override
String get reallyDeleteHiScores => '¿Seguro que quieres borrar todos los récords?';
@override
String get yourGuess => 'Tu respuesta...';
@override
String get attempts => 'Intentos';
@override
String get maximum => 'Máximo';
@override
String get minimum => 'Mínimo';
@override
String get specialHints => 'Pistas Especiales';
@override
String get hintsWarning => '¡Atención! Usarlas quita puntos';
@override
String get lockedHint => 'Pista Bloqueada';
@override
String get tapToUnlock => 'Toca para Desbloquear';
@override
String get unlockConfirm => '¿Seguro? Toca de nuevo para Confirmar';
@override
String get evenOddHint => '¿Es par o impar?';
@override
String get divisibleHint => '¿Entre qué número es divisible?';
@override
String get digitsSumHint => '¿Cuál es la suma de sus cifras?';
@override
String get digitsCountHint => '¿Cuántas cifras tiene?';
@override
String get evenNumber => 'El número es Par';
@override
String get oddNumber => 'El número es Impar';
@override
String divisibleBy(num number) {
final intl.NumberFormat numberNumberFormat = intl.NumberFormat.compact(
locale: localeName,
);
final String numberString = numberNumberFormat.format(number);
return 'El número es divisible entre $numberString';
}
@override
String primeLessMax(num maximum) {
final intl.NumberFormat maximumNumberFormat = intl.NumberFormat.compact(
locale: localeName,
);
final String maximumString = maximumNumberFormat.format(maximum);
return 'El número es primo inferior a $maximumString';
}
@override
String notDivisibleByPrimes(num maximum) {
final intl.NumberFormat maximumNumberFormat = intl.NumberFormat.compact(
locale: localeName,
);
final String maximumString = maximumNumberFormat.format(maximum);
return 'El número NO es divisible entre primos inferiores a $maximumString';
}
@override
String digitsSum(num total) {
final intl.NumberFormat totalNumberFormat = intl.NumberFormat.compact(
locale: localeName,
);
final String totalString = totalNumberFormat.format(total);
return 'La suma de las cifras del número da $totalString';
}
@override
String digitsCount(num count) {
final intl.NumberFormat countNumberFormat = intl.NumberFormat.compact(
locale: localeName,
);
final String countString = countNumberFormat.format(count);
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$countString cifras',
one: '1 cifra',
);
return 'El número tiene $_temp0';
}
@override
String get pause => 'Pausa';
@override
String get resume => 'Reanudar';
@override
String get changeHand => 'Cambiar de mano';
@override
String get newGame => 'Nueva partida';
@override
String get changeDifficulty => 'Cambiar dificultad';
@override
String get exitGame => 'Terminar partida';
@override
String get highestScore => '¡Esta es tu mejor puntuación!';
@override
String nthHiScore(String nth) {
return 'Esta es tu $nthª mejor puntuación';
}
@override
String get enterYourName => 'Introduce aquí tu nombre::';
@override
String get yourName => 'Tu nombre...';
@override
String get saveHiScore => 'Guardar récord';
@override
String get dontSaveHiScore => 'Salir sin guardar';
@override
String get congratulations => '¡Enhorabuena!';
@override
String score(num score) {
return 'Puntuación: $score';
}
@override
String get playAgain => 'Jugar otra vez';
@override
String get exitToMainMenu => 'Volver al inicio';
@override
String get noMoreAttempts => '¡Sin intentos!';
@override
String get betterLuck => 'Más suerte la próxima vez...';
}
import 'package:flutter/material.dart';
import 'package:peponator/l10n/app_localizations.dart';
import 'package:peponator/widgets/pista_widget.dart';
class Pista {
static const primos = [3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97];
class Pista{
final ClasePista clase;
final VoidCallback? onPressed;
late final int divisible;
late final String mensaje;
late String? mensaje;
late final int _numero;
late final int _divisible;
EstadoPista estado = EstadoPista.bloqueado;
......@@ -17,46 +17,75 @@ class Pista {
required int numero,
this.onPressed
}) {
if(clase != ClasePista.divisible){
divisible = 0;
}
else{
bool found = false;
for(int i = 0; (i<primos.length) && (primos[i]<=numero/2); i++){
if(numero % primos[i] == 0){
divisible = primos[i];
found = true;
break;
}
}
if(!found){
if(numero < 100){
divisible = 1;
}
else{
divisible = -1;
}
_numero = numero;
_divisible = clase.getDivisible(_numero);
}
bool validarNumero(int adivinar, int numero){
return clase.validarNumero(adivinar, numero, _divisible);
}
Widget createWidget(BuildContext context){
return PistaWidget(
key: Key(clase.name),
titulo: clase.getTitle(context),
mensaje: (estado.desbloqueada())? clase.generateMensaje(_numero, _divisible, context) : estado.getMensaje(context),
estado: estado,
onPressed: (estado == EstadoPista.disponible || estado == EstadoPista.confirmacion)? onPressed : null
);
}
}
enum ClasePista {
parImpar,
divisible,
sumaCifras,
numeroCifras;
static const primos = [3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97];
int getDivisible(int numero){
if(this != ClasePista.divisible) return 0;
for(int i = 0; (i<primos.length) && (primos[i]<=numero/2); i++){
if(numero % primos[i] == 0){
return primos[i];
}
}
if(numero < 100){
return 1;
}
return -1;
}
mensaje = _generaPista(numero);
String getTitle(BuildContext context){
switch(this){
case parImpar:
return AppLocalizations.of(context)?.evenOddHint ?? '¿Es par o impar?';
case divisible:
return AppLocalizations.of(context)?.divisibleHint ?? '¿Entre qué número es divisible?';
case sumaCifras:
return AppLocalizations.of(context)?.digitsSumHint ?? '¿Cuál es la suma de sus cifras?';
case numeroCifras:
return AppLocalizations.of(context)?.digitsCountHint ?? '¿Cuántas cifras tiene?';
}
}
String _generaPista(int numero){
switch(clase){
String generateMensaje(int numero, int divisible, BuildContext context){
switch(this){
case ClasePista.parImpar:
if(numero%2 == 0){
return 'El número es par';
return AppLocalizations.of(context)?.evenNumber ?? 'El número es par';
}
return 'El número es impar';
return AppLocalizations.of(context)?.oddNumber ?? 'El número es impar';
case ClasePista.divisible:
if(divisible == 1){
return 'El número es primo inferior a 100';
return AppLocalizations.of(context)?.primeLessMax(100) ?? 'El número es primo inferior a 100';
}
if(divisible == -1){
return 'El número NO es divisible entre primos inferiores a 100';
return AppLocalizations.of(context)?.notDivisibleByPrimes(100) ?? 'El número NO es divisible entre primos inferiores a 100';
}
return 'El número es divisible entre $divisible';
return AppLocalizations.of(context)?.divisibleBy(divisible) ?? 'El número es divisible entre $divisible';
case ClasePista.sumaCifras:
int pseudo = numero;
int suma = 0;
......@@ -64,7 +93,7 @@ class Pista {
suma += pseudo%10;
pseudo = (pseudo/10).floor();
}
return 'La suma de las cifras del número da $suma';
return AppLocalizations.of(context)?.digitsSum(suma) ?? 'La suma de las cifras del número da $suma';
case ClasePista.numeroCifras:
int div = 10;
int num = 1;
......@@ -72,6 +101,12 @@ class Pista {
num++;
div *= 10;
}
String? ret = AppLocalizations.of(context)?.digitsCount(num);
if(ret != null){
return ret;
}
if(num == 1){
return 'El número tiene 1 cifra';
}
......@@ -79,8 +114,8 @@ class Pista {
}
}
bool validarNumero(int adivinar, int numero){
switch(clase){
bool validarNumero(int adivinar, int numero, int divisible){
switch(this){
case ClasePista.parImpar:
return adivinar%2 == numero%2;
case ClasePista.divisible:
......@@ -90,7 +125,6 @@ class Pista {
if(divisible == -1){
for(int i = 0; (i<primos.length) && (primos[i]<=numero/2); i++){
if(numero % primos[i] == 0){
divisible = primos[i];
return false;
}
}
......@@ -115,36 +149,6 @@ class Pista {
return (numero/div < 10 && numero/div >= 1);
}
}
Widget createWidget(){
return PistaWidget(
key: Key(clase.name),
titulo: clase.getTitle(),
mensaje: (estado.desbloqueada())? mensaje : estado.getMensaje(),
estado: estado,
onPressed: (estado == EstadoPista.disponible || estado == EstadoPista.confirmacion)? onPressed : null
);
}
}
enum ClasePista {
parImpar,
divisible,
sumaCifras,
numeroCifras;
String getTitle(){
switch(this){
case parImpar:
return '¿Es par o impar?';
case divisible:
return '¿Entre qué número es divisible?';
case sumaCifras:
return '¿Cuál es la suma de sus cifras?';
case numeroCifras:
return '¿Cuántas cifras tiene?';
}
}
}
enum EstadoPista {
......@@ -200,16 +204,16 @@ enum EstadoPista {
return Colors.black;
}
String getMensaje(){
String getMensaje(BuildContext context){
switch(this){
case bloqueado:
return "PISTA BLOQUEADA";
return AppLocalizations.of(context)?.lockedHint ?? 'Pista Bloqueada';
case disponible:
return "PULSA PARA DESBLOQUEAR";
return AppLocalizations.of(context)?.tapToUnlock ?? 'Pulsa para Desbloquear';
case confirmacion:
return "¿Seguro? Pulsa de nuevo para confirmar";
return AppLocalizations.of(context)?.unlockConfirm ?? '¿Seguro? Pulsa de nuevo para Confirmar';
default:
return "";
return '';
}
}
......
......@@ -2,8 +2,10 @@ import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:path_provider/path_provider.dart';
import 'package:peponator/modelo/modelo.dart';
import 'package:peponator/l10n/app_localizations.dart';
class PantallaRecords extends StatefulWidget {
static const int maxRecords = 20;
......@@ -85,7 +87,7 @@ class _PantallaRecordsState extends State<PantallaRecords> {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'Récords',
AppLocalizations.of(context)?.highScores ?? 'Récords',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headlineLarge?.copyWith(
color: Theme.of(context).colorScheme.onPrimary,
......@@ -94,7 +96,7 @@ class _PantallaRecordsState extends State<PantallaRecords> {
),
const SizedBox(height: 8.0),
Text(
'¡Las 20 mejores puntuaciones registradas en el juego!',
AppLocalizations.of(context)?.highest20Scores ?? '¡Las 20 mejores puntuaciones registradas en el juego!',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: Theme.of(context).colorScheme.onPrimary,
......@@ -165,7 +167,7 @@ class _PantallaRecordsState extends State<PantallaRecords> {
),
const SizedBox(height: 8.0),
Text(
'${fecha.day}/${fecha.month}/${fecha.year}',
DateFormat.yMd(Localizations.localeOf(context).languageCode).format(fecha),
textAlign: TextAlign.start,
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: t,
......@@ -201,9 +203,11 @@ class _PantallaRecordsState extends State<PantallaRecords> {
}
}
else {
final String noRecord = AppLocalizations.of(context)?.noRecordsYet ?? 'No hay ningún récord registrado de momento.';
final String playToRegister = AppLocalizations.of(context)?.playToRegister ?? '¡Juega y registra el primero!';
final message = Center(
child: Text(
'No hay ningún récord registrado de momento.\n\n¡Juega y registra el primero!',
'$noRecord\n\n$playToRegister',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleLarge,
)
......@@ -221,82 +225,77 @@ class _PantallaRecordsState extends State<PantallaRecords> {
}
Widget _buildFAB(BuildContext context, Orientation orientation){
return Align(
alignment: (orientation == Orientation.portrait)? Alignment.bottomCenter : Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.only(left: 32.0),
child: FloatingActionButton.extended(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Center(child: Text(
'Borrar récords',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleLarge,
)),
content: Text(
(orientation == Orientation.portrait)?
'Esta acción no se puede deshacer. ¿Seguro que quieres borrar todos los récords?':
'Esta acción no se puede deshacer.\n¿Seguro que quieres borrar todos los récords?'
,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
),
actionsAlignment: MainAxisAlignment.spaceAround,
actions: [
TextButton(
onPressed: () {
_deleteRecords();
Navigator.pop(context);
},
style: TextButton.styleFrom(
side: BorderSide(
color: Colors.grey,
width: 2.0
)
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Text(
'Sí',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Theme.of(context).colorScheme.primary
),
),
final noUndo = AppLocalizations.of(context)?.noUndo ?? 'Esta acción no se puede deshacer.';
final reallyDeleteHiScores = AppLocalizations.of(context)?.reallyDeleteHiScores ?? '¿Seguro que quieres borrar todos los récords?';
return FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Center(child: Text(
AppLocalizations.of(context)?.deleteHighScores ?? 'Borrar récords',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleLarge,
)),
content: Text(
(orientation == Orientation.portrait)?
'$noUndo $reallyDeleteHiScores' :
'$noUndo\n$reallyDeleteHiScores'
,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
),
actionsAlignment: MainAxisAlignment.spaceAround,
actions: [
TextButton(
onPressed: () {
_deleteRecords();
Navigator.pop(context);
},
style: TextButton.styleFrom(
side: BorderSide(
color: Colors.grey,
width: 2.0
)
),
TextButton(
onPressed: () {
Navigator.pop(context);
},
style: TextButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.primary
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Text(
AppLocalizations.of(context)?.yes ?? 'Sí',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Theme.of(context).colorScheme.primary
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Text(
'No',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Theme.of(context).colorScheme.onPrimary
),
),
)
),
)
],
);
}
);
},
backgroundColor: Colors.red,
label: Text(
'Borrar récords',
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: Colors.white
),
),
),
),
TextButton(
onPressed: () {
Navigator.pop(context);
},
style: TextButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.primary
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Text(
AppLocalizations.of(context)?.no ?? 'No',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Theme.of(context).colorScheme.onPrimary
),
),
)
)
],
);
}
);
},
backgroundColor: Colors.red,
child: Icon(
Icons.delete_forever,
color: Colors.white,
size: 36,
),
);
}
......@@ -320,7 +319,9 @@ class _PantallaRecordsState extends State<PantallaRecords> {
Future<void> _deleteRecords() async {
final file = await PantallaRecords.localFile();
await file.delete();
if(await file.exists()){
await file.delete();
}
setState(() {});
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:peponator/modelo/listaDificultad.dart';
import 'package:provider/provider.dart';
import 'package:peponator/paginas/paginas.dart';
import 'package:peponator/l10n/app_localizations.dart';
class PeponatorApp extends StatelessWidget {
const PeponatorApp({super.key});
......@@ -18,6 +19,8 @@ class PeponatorApp extends StatelessWidget {
brightness: Brightness.light,
useMaterial3: true
),
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
darkTheme: ThemeData.dark(),
themeMode: ThemeMode.system,
home: PantallaJuego(),
......
import 'package:flutter/material.dart';
import 'package:peponator/l10n/app_localizations.dart';
class PantallaPausa extends StatelessWidget {
final Orientation orientacion;
......@@ -22,7 +23,7 @@ class PantallaPausa extends StatelessWidget {
return SimpleDialog(
alignment: alignment,
title: Center(child: Text(
'Pausa',
AppLocalizations.of(context)?.pause ?? 'Pausa',
style: (orientacion == Orientation.portrait)?
Theme.of(context).textTheme.headlineLarge :
Theme.of(context).textTheme.headlineSmall,
......@@ -47,7 +48,7 @@ class PantallaPausa extends StatelessWidget {
size: 32.0
),
label: Text(
element.text,
element.getText(context),
style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: (Theme.of(context).brightness == Brightness.light)? null : FontWeight.bold,
color: element.getColor(Theme.of(context).brightness) ?? Theme.of(context).colorScheme.primary
......@@ -61,16 +62,15 @@ class PantallaPausa extends StatelessWidget {
}
enum OpcionPausa {
reanudar(Icons.play_arrow_outlined, "Reanudar"),
cambioMano(Icons.front_hand_outlined, "Cambiar de mano"),
nuevaPartida(Icons.refresh, "Nueva partida"),
cambiarDificultad(Icons.settings_outlined, "Cambiar dificultad"),
salir(Icons.logout, "Terminar partida");
reanudar(Icons.play_arrow_outlined),
cambioMano(Icons.front_hand_outlined),
nuevaPartida(Icons.refresh),
cambiarDificultad(Icons.settings_outlined),
salir(Icons.logout);
final IconData icon;
final String text;
const OpcionPausa(this.icon, this.text);
const OpcionPausa(this.icon);
Color? getColor(Brightness brillo) {
switch(this){
......@@ -88,4 +88,19 @@ enum OpcionPausa {
return null;
}
}
String getText(BuildContext context) {
switch(this){
case OpcionPausa.reanudar:
return AppLocalizations.of(context)?.resume ?? 'Reanudar';
case OpcionPausa.cambioMano:
return AppLocalizations.of(context)?.changeHand ?? 'Cambiar de mano';
case OpcionPausa.nuevaPartida:
return AppLocalizations.of(context)?.newGame ?? 'Nueva partida';
case OpcionPausa.cambiarDificultad:
return AppLocalizations.of(context)?.changeDifficulty ?? 'Cambiar dificultad';
case OpcionPausa.salir:
return AppLocalizations.of(context)?.exitGame ?? 'Terminar partida';
}
}
}
\ No newline at end of file
......@@ -38,6 +38,9 @@ dependencies:
path_provider: ^2.1.5
provider: ^6.1.5
uuid: ^4.5.1
flutter_localizations:
sdk: flutter
intl: any
dev_dependencies:
flutter_test:
......@@ -61,6 +64,9 @@ flutter:
# the material Icons class.
uses-material-design: true
# Enables generation of localized YAML files
generate: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment