diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f9b303465f19b5fbf5ec669cd083c9cc38ecda9a --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1 @@ +include: package:flutter_lints/flutter.yaml diff --git a/android/app/build.gradle b/android/app/build.gradle index 43cc9c1b62f9be8c42926cc257067ea1e3b7cc53..93ce228eb943f7ce4a83bea52fff9267aeafe7d2 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -44,7 +44,7 @@ android { defaultConfig { applicationId "org.benoitharrault.hangman" - minSdkVersion 16 + minSdkVersion flutter.minSdkVersion targetSdkVersion 30 versionCode appVersionCode.toInteger() versionName appVersionName diff --git a/android/gradle.properties b/android/gradle.properties index 3318272db1e10ae954687f141fb3deb1438c9e31..91d05c86778fa34b39008c2c72b0291deca2778a 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true -app.versionName=1.2.11 -app.versionCode=22 +app.versionName=1.2.12 +app.versionCode=23 diff --git a/lib/main.dart b/lib/main.dart index f624310bb3505ba73eee2b7a700c7433d0b94699..99fcffa4754263d3fc9fc19dfec853002fc4f404 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,9 +7,11 @@ import 'screens/game.dart'; import 'screens/scores.dart'; import 'utils/constants.dart'; -void main() => runApp(Hangman()); +void main() => runApp(const Hangman()); class Hangman extends StatelessWidget { + const Hangman({super.key}); + @override Widget build(BuildContext context) { return ChangeNotifierProvider( @@ -19,14 +21,14 @@ class Hangman extends StatelessWidget { return MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData( - primaryColor: Color(darkGreen), + primaryColor: const Color(darkGreen), visualDensity: VisualDensity.adaptivePlatformDensity, ), - home: Home(), + home: const Home(), routes: { - Home.id: (context) => Home(), - Game.id: (context) => Game(), - Scores.id: (context) => Scores(), + Home.id: (context) => const Home(), + Game.id: (context) => const Game(), + Scores.id: (context) => const Scores(), }, ); }, diff --git a/lib/provider/data.dart b/lib/provider/data.dart index e624d6015a45d74b4e0028351d07a9758c91caaf..6da76105ba16877fc77943ee75305e7a6af63b77 100644 --- a/lib/provider/data.dart +++ b/lib/provider/data.dart @@ -1,4 +1,5 @@ import 'package:flutter/foundation.dart'; + import '../utils/shared_prefs.dart'; import '../utils/constants.dart'; diff --git a/lib/screens/game.dart b/lib/screens/game.dart index bfb2e5e8219d1e28f917614b2ad83eaa36d99ac2..1305fc1d42ab83ea7f5eebc8ffe1126371338600 100644 --- a/lib/screens/game.dart +++ b/lib/screens/game.dart @@ -1,11 +1,14 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; + import '../provider/data.dart'; import '../utils/constants.dart'; import '../utils/random_pick.dart'; import '../widgets/letters.dart'; class Game extends StatelessWidget { + const Game({super.key}); + static const String id = 'game'; Future<void> pickWord(BuildContext context, Data myProvider) async { @@ -32,11 +35,11 @@ class Game extends StatelessWidget { @override Widget build(BuildContext context) { Orientation orientation = MediaQuery.of(context).orientation; - Data _myProvider = Provider.of<Data>(context); + Data myProvider = Provider.of<Data>(context); return Scaffold( - backgroundColor: Color(board), - floatingActionButton: _myProvider.levelPref == defaultLevel + backgroundColor: const Color(board), + floatingActionButton: myProvider.levelPref == defaultLevel ? FloatingActionButton( foregroundColor: Colors.white, backgroundColor: Colors.transparent, @@ -46,11 +49,11 @@ class Game extends StatelessWidget { context: context, builder: (context) { return AlertDialog( - title: Text('Indice'), - content: Text(_myProvider.clue), + title: const Text('Indice'), + content: Text(myProvider.clue), actions: <Widget>[ TextButton( - child: Text('Revenir au jeu'), + child: const Text('Revenir au jeu'), onPressed: () => Navigator.of(context).pop(), ) ], @@ -58,30 +61,30 @@ class Game extends StatelessWidget { }, ); }, - child: Icon(Icons.help_outline), + child: const Icon(Icons.help_outline), ) : null, floatingActionButtonLocation: orientation == Orientation.portrait ? FloatingActionButtonLocation.endTop : FloatingActionButtonLocation.centerTop, body: orientation == Orientation.portrait - ? Column( + ? const Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Flexible( child: Padding( padding: EdgeInsets.only(top: 60.0, left: 30.0, right: 30.0, bottom: 10.0), - child: const ImgGallow(), + child: ImgGallow(), ), ), Padding( - padding: const EdgeInsets.symmetric(horizontal: 30.0), - child: const HiddenWord(), + padding: EdgeInsets.symmetric(horizontal: 30.0), + child: HiddenWord(), ), - const LetterButtons(), + LetterButtons(), ], ) - : Row( + : const Row( children: [ Expanded( flex: 2, @@ -89,13 +92,13 @@ class Game extends StatelessWidget { children: [ Expanded( child: Padding( - padding: const EdgeInsets.only(top: 40.0), + padding: EdgeInsets.only(top: 40.0), child: ImgGallow(), ), ), Padding( - padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0), - child: const HiddenWord(), + padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0), + child: HiddenWord(), ), ], ), @@ -108,16 +111,16 @@ class Game extends StatelessWidget { } class ImgGallow extends StatelessWidget { - const ImgGallow({Key? key}) : super(key: key); + const ImgGallow({super.key}); @override Widget build(BuildContext context) { - Data _myProvider = Provider.of<Data>(context); + Data myProvider = Provider.of<Data>(context); return Stack( children: [ for (int error = 0; error < 9; error++) AnimatedOpacity( - opacity: _myProvider.errors >= error ? 1.0 : 0.0, - duration: Duration(milliseconds: _myProvider.errors >= error ? 800 : 0), + opacity: myProvider.errors >= error ? 1.0 : 0.0, + duration: Duration(milliseconds: myProvider.errors >= error ? 800 : 0), child: Image.asset('assets/images/img${error + 1}.png'), ) ], @@ -126,16 +129,16 @@ class ImgGallow extends StatelessWidget { } class HiddenWord extends StatelessWidget { - const HiddenWord({Key? key}) : super(key: key); + const HiddenWord({super.key}); @override Widget build(BuildContext context) { - Data _myProvider = Provider.of<Data>(context); + Data myProvider = Provider.of<Data>(context); return FittedBox( child: Text( - (_myProvider.hiddenWord.isEmpty || _myProvider.hiddenWord == '') + (myProvider.hiddenWord.isEmpty || myProvider.hiddenWord == '') ? 'UNEXPECTED ERROR' - : _myProvider.hiddenWord, - style: TextStyle( + : myProvider.hiddenWord, + style: const TextStyle( fontFamily: 'Tiza', color: Colors.white, fontSize: 34.0, diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 09d9590c4ed0edfa3444c797881c27477ed385c6..b17a520cd12f88f71a05e1a062efb5abdb7fec20 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -8,22 +8,24 @@ import '../widgets/dialog_fetch_error.dart'; import '../utils/constants.dart'; class Home extends StatelessWidget { + const Home({super.key}); + static const String id = 'home'; @override Widget build(BuildContext context) { - Data _myProvider = Provider.of<Data>(context); + final Data myProvider = Provider.of<Data>(context); - void _errorWord(context) { + void errorWord(context) { showDialog( context: context, builder: (_) => AlertDialog( - title: Text('Erreur inattendue'), - content: Text('Erreur inattendue à la récupération d\'un mot aléatoire.\n' + title: const Text('Erreur inattendue'), + content: const Text('Erreur inattendue à la récupération d\'un mot aléatoire.\n' 'Installer une nouvelle version de l\'application pourrait corriger cette anomalie.'), actions: <Widget>[ TextButton( - child: Text('Fermer'), + child: const Text('Fermer'), onPressed: () => Navigator.of(context).pop(), ) ], @@ -35,137 +37,137 @@ class Home extends StatelessWidget { appBar: MyAppBar(appBar: AppBar()), body: Builder( builder: (context) => Center( - child: _myProvider.searching == true + child: myProvider.searching == true ? WillPopScope( onWillPop: () async => false, - child: Center( + child: const Center( child: CircularProgressIndicator(), ), ) - : Container( - child: SingleChildScrollView( - child: SizedBox( - height: MediaQuery.of(context).size.height / 1.25, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0), - child: FittedBox( - fit: BoxFit.fitWidth, - child: Text( - 'LE PENDU', - style: TextStyle( - fontFamily: 'Tiza', - fontSize: 28.0, - color: Colors.grey[700], - ), + : SingleChildScrollView( + padding: const EdgeInsets.all(15.0), + child: SizedBox( + height: MediaQuery.of(context).size.height / 1.25, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 20.0, vertical: 10.0), + child: FittedBox( + fit: BoxFit.fitWidth, + child: Text( + 'LE PENDU', + style: TextStyle( + fontFamily: 'Tiza', + fontSize: 28.0, + color: Colors.grey[700], ), ), ), - Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text('Mode en ligne'), - Switch( - value: _myProvider.gameModeValue, - onChanged: (bool value) => - _myProvider.updateGameMode = value, - activeTrackColor: Color(board), - activeColor: Colors.greenAccent[400], - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text('Niveau'), - DropdownButton<String>( - value: _myProvider.levelValue != '' - ? _myProvider.levelValue - : onlineGameMode[_myProvider.gameModeValue]?.first, - items: onlineGameMode[_myProvider.gameModeValue] - ?.map<DropdownMenuItem<String>>((String value) { - return DropdownMenuItem<String>( - value: value, - child: Text(value), - ); - }).toList(), - onChanged: (String? value) => - _myProvider.updateLevel = value ?? '', - ), - ], - ), - ], - ), - ElevatedButton.icon( - style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: Color(board), - padding: EdgeInsets.all(10.0), + ), + Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text('Mode en ligne'), + Switch( + value: myProvider.gameModeValue, + onChanged: (bool value) => myProvider.updateGameMode = value, + activeTrackColor: const Color(board), + activeColor: Colors.greenAccent[400], + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text('Niveau'), + DropdownButton<String>( + value: myProvider.levelValue != '' + ? myProvider.levelValue + : onlineGameMode[myProvider.gameModeValue]?.first, + items: onlineGameMode[myProvider.gameModeValue] + ?.map<DropdownMenuItem<String>>((String value) { + return DropdownMenuItem<String>( + value: value, + child: Text(value), + ); + }).toList(), + onChanged: (String? value) => + myProvider.updateLevel = value ?? '', + ), + ], ), - onPressed: () async { - _myProvider.resetGame(); - _myProvider.searching = true; - bool control = true; - await Game().pickWord(context, _myProvider); - if (_myProvider.secretWord == '' || - _myProvider.hiddenWord == '') { - control = false; - var response = await Navigator.push( - context, - MaterialPageRoute(builder: (context) => DialogFetchError()), - ); - if (response == false) { - _myProvider.searching = false; - _myProvider.resetGame(); - } else { - _myProvider.setPrefGameMode = false; - _myProvider.setPrefLevel = defaultLevel; - await Game().pickWord(context, _myProvider); - control = true; - } + ], + ), + TextButton.icon( + style: TextButton.styleFrom( + foregroundColor: Colors.white, + backgroundColor: const Color(board), + padding: const EdgeInsets.all(10.0), + ), + onPressed: () async { + myProvider.resetGame(); + myProvider.searching = true; + bool control = true; + await const Game().pickWord(context, myProvider); + if (myProvider.secretWord == '' || myProvider.hiddenWord == '') { + control = false; + var response = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const DialogFetchError(), + ), + ); + if (response == false) { + myProvider.searching = false; + myProvider.resetGame(); + } else { + myProvider.setPrefGameMode = false; + myProvider.setPrefLevel = defaultLevel; + await const Game().pickWord(context, myProvider); + control = true; } + } - if (_myProvider.secretWord == 'UNEXPECTED ERROR') { - control = false; - _myProvider.resetGame(); - _errorWord(context); - } + if (myProvider.secretWord == 'UNEXPECTED ERROR') { + control = false; + myProvider.resetGame(); + errorWord(context); + } - if (control) { - Navigator.pushNamed(context, Game.id) - .then((value) => _myProvider.searching = false); - } - }, - icon: Icon( - Icons.check_box, - color: Colors.white, - size: 60.0, - ), - label: Column( - children: [ - Text( - 'JOUER', - style: TextStyle( - fontSize: 22.0, - letterSpacing: 2.0, - ), + if (control) { + Navigator.pushNamed(context, Game.id) + .then((value) => myProvider.searching = false); + } + }, + icon: const Icon( + Icons.check_box, + color: Colors.white, + size: 60.0, + ), + label: Column( + children: [ + const Text( + 'JOUER', + style: TextStyle( + fontSize: 22.0, + letterSpacing: 2.0, ), - Text( - 'Mode de jeu: ${_myProvider.levelPref}', - style: TextStyle( - fontSize: 10.0, - fontWeight: FontWeight.w300, - ), + ), + Text( + 'Mode de jeu: ${myProvider.levelPref}', + style: const TextStyle( + fontSize: 10.0, + fontWeight: FontWeight.w300, ), - ], - ), + ), + ], ), - ], - ), + ), + ], ), ), ), diff --git a/lib/screens/scores.dart b/lib/screens/scores.dart index 9f77ae552f07d43863c7dde7bc42673e303dfb80..f1e62fe255d8ee98319b11ab9cfa2bd23abc6d9a 100644 --- a/lib/screens/scores.dart +++ b/lib/screens/scores.dart @@ -1,22 +1,26 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; + import '../provider/data.dart'; import '../utils/constants.dart'; class Scores extends StatelessWidget { + const Scores({super.key}); + static const String id = 'scores'; @override Widget build(BuildContext context) { - Data _myProvider = Provider.of<Data>(context); + final Data myProvider = Provider.of<Data>(context); + return Scaffold( - backgroundColor: Color(board), + backgroundColor: const Color(board), appBar: AppBar( - title: Text('Scores'), + title: const Text('Scores'), actions: [ IconButton( - icon: Icon(Icons.delete_forever), - onPressed: () => _myProvider.resetScores(), + icon: const Icon(Icons.delete_forever), + onPressed: () => myProvider.resetScores(), ), ], ), @@ -24,11 +28,11 @@ class Scores extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ - Flexible( + const Flexible( child: FractionallySizedBox(heightFactor: 0.6), ), Padding( - padding: EdgeInsets.symmetric(horizontal: 10.0), + padding: const EdgeInsets.symmetric(horizontal: 10.0), child: FittedBox( fit: BoxFit.fitWidth, child: Text( @@ -41,7 +45,7 @@ class Scores extends StatelessWidget { ), ), ), - Flexible(child: FractionallySizedBox(heightFactor: 0.2)), + const Flexible(child: FractionallySizedBox(heightFactor: 0.2)), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -51,15 +55,15 @@ class Scores extends StatelessWidget { color: Colors.grey[200], size: 60.0, ), - '${_myProvider.victoryCount}', + '${myProvider.victoryCount}', ), CardBox( ImageIcon( - AssetImage('assets/images/gameover.png'), + const AssetImage('assets/images/gameover.png'), color: Colors.grey[200], size: 60.0, ), - '${_myProvider.defeatCount}', + '${myProvider.defeatCount}', ), ], ), @@ -74,21 +78,21 @@ class CardBox extends StatelessWidget { final Widget imagen; final String text; - CardBox(this.imagen, this.text); + const CardBox(this.imagen, this.text, {super.key}); @override Widget build(BuildContext context) { return Flexible( child: Card( elevation: 10.0, - margin: EdgeInsets.symmetric(horizontal: 10.0), + margin: const EdgeInsets.symmetric(horizontal: 10.0), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), - color: Color(darkGreen), + color: const Color(darkGreen), child: Column( children: [ Container( - padding: EdgeInsets.all(10.0), - decoration: BoxDecoration( + padding: const EdgeInsets.all(10.0), + decoration: const BoxDecoration( border: Border( bottom: BorderSide( color: Colors.grey, @@ -102,7 +106,7 @@ class CardBox extends StatelessWidget { ), ), Container( - padding: EdgeInsets.all(20.0), + padding: const EdgeInsets.all(20.0), child: Text( text, style: TextStyle( diff --git a/lib/utils/constants.dart b/lib/utils/constants.dart index 53cba215ffaa336845efc4b67a3255bf3e2aebf5..ef2ab77fd46920fe1e4314140213158617e6379a 100644 --- a/lib/utils/constants.dart +++ b/lib/utils/constants.dart @@ -15,23 +15,23 @@ const int board = 0xff004D00; const int accent = 0xffD81B60; // GameOver -enum GameOver { VICTORY, DEFEAT } +enum GameOver { victory, defeat } extension GameOverExtension on GameOver { static const titles = { - GameOver.VICTORY: 'Victoire !', - GameOver.DEFEAT: 'Pendu !', + GameOver.victory: 'Victoire !', + GameOver.defeat: 'Pendu !', }; String get title => titles[this] ?? '?'; static const icons = { - GameOver.VICTORY: Icons.military_tech, - GameOver.DEFEAT: Icons.gavel, + GameOver.victory: Icons.military_tech, + GameOver.defeat: Icons.gavel, }; IconData get icon => icons[this] ?? Icons.error; } -const victory = GameOver.VICTORY; -const defeat = GameOver.DEFEAT; +const victory = GameOver.victory; +const defeat = GameOver.defeat; diff --git a/lib/utils/random_pick.dart b/lib/utils/random_pick.dart index ff903b1be2fa94769ff63743f46be3f958de4044..08d44467afeba688f4893db31c0d732c1e19ecd6 100644 --- a/lib/utils/random_pick.dart +++ b/lib/utils/random_pick.dart @@ -77,8 +77,8 @@ class RandomPick { Future _waitList() => Future(() { final completer = Completer(); - int indexRandom = random.nextInt(list_french_words.length); - completer.complete(list_french_words.sublist(indexRandom, indexRandom + 1).join('\n')); + int indexRandom = random.nextInt(listFrenchWords.length); + completer.complete(listFrenchWords.sublist(indexRandom, indexRandom + 1).join('\n')); return completer.future; }); diff --git a/lib/utils/shared_prefs.dart b/lib/utils/shared_prefs.dart index cde8a6e980d030d9d55ff69808a3bf2c5b348bab..fff13bf5d21b6797fa5c8673d74bf837ba0c583e 100644 --- a/lib/utils/shared_prefs.dart +++ b/lib/utils/shared_prefs.dart @@ -8,9 +8,7 @@ class SharedPrefs { static const String _prefsDefeatCount = 'defeatCount'; init() async { - if (_sharedPrefs == null) { - _sharedPrefs = await SharedPreferences.getInstance(); - } + _sharedPrefs ??= await SharedPreferences.getInstance(); } bool get gameMode => _sharedPrefs?.getBool(_prefsGameMode) ?? false; diff --git a/lib/widgets/dialog_fetch_error.dart b/lib/widgets/dialog_fetch_error.dart index fc44528706273e4538a4b458f95756a682f92007..f49154570d67e06e698336e6c820f139456acd10 100644 --- a/lib/widgets/dialog_fetch_error.dart +++ b/lib/widgets/dialog_fetch_error.dart @@ -2,17 +2,17 @@ import 'package:hangman/utils/constants.dart'; import 'package:flutter/material.dart'; class DialogFetchError extends StatelessWidget { - const DialogFetchError({Key? key}) : super(key: key); + const DialogFetchError({super.key}); @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: Color(board), + backgroundColor: const Color(board), body: WillPopScope( onWillPop: () async => false, child: AlertDialog( - title: Text('Connexion impossible'), - content: Text('Impossible de récupérer un mot aléatoire. ' + title: const Text('Connexion impossible'), + content: const Text('Impossible de récupérer un mot aléatoire. ' 'La connexion internet est peut-être inaccessible.\n' 'Changer vers un mode de jeu hors-ligne ?'), actions: [ diff --git a/lib/widgets/dialog_gameover.dart b/lib/widgets/dialog_gameover.dart index e18de8de47cd5248d859c3fdd09f5e7bd10694b2..af0a6ccd217eca4c2e4e6d6c1c4a7cd6471a2867 100644 --- a/lib/widgets/dialog_gameover.dart +++ b/lib/widgets/dialog_gameover.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; + import '../screens/home.dart'; import '../screens/game.dart'; import '../provider/data.dart'; @@ -7,22 +8,23 @@ import '../utils/constants.dart'; class DialogGameOver extends StatelessWidget { final GameOver gameOver; - const DialogGameOver(this.gameOver); + const DialogGameOver(this.gameOver, {super.key}); @override Widget build(BuildContext context) { - Data _myProvider = Provider.of<Data>(context); + final Data myProvider = Provider.of<Data>(context); + return Scaffold( backgroundColor: Colors.transparent, - body: _myProvider.searching == true - ? Center(child: CircularProgressIndicator()) + body: myProvider.searching == true + ? const Center(child: CircularProgressIndicator()) : WillPopScope( onWillPop: () async => false, child: AlertDialog( title: Row( children: [ Icon(gameOver.icon), - SizedBox(width: 10.0), + const SizedBox(width: 10.0), Text(gameOver.title), ], ), @@ -31,9 +33,9 @@ class DialogGameOver extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - if (gameOver == GameOver.DEFEAT) - Text('Le mot secret était ${_myProvider.secretWord}'), - Text('Rejouer ?'), + if (gameOver == GameOver.defeat) + Text('Le mot secret était ${myProvider.secretWord}'), + const Text('Rejouer ?'), ], ), ), @@ -47,8 +49,8 @@ class DialogGameOver extends StatelessWidget { TextButton( child: const Text('REJOUER'), onPressed: () async { - _myProvider.resetSuccessAndErrors(); - await Game().pickWord(context, _myProvider); + myProvider.resetSuccessAndErrors(); + await const Game().pickWord(context, myProvider); Navigator.of(context).pop(); }, ), diff --git a/lib/widgets/letters.dart b/lib/widgets/letters.dart index d871ab56674b5f46b655b40e763598a417655023..69938500563a791b509acf21a62ff733a306c343 100644 --- a/lib/widgets/letters.dart +++ b/lib/widgets/letters.dart @@ -1,60 +1,62 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; + import '../provider/data.dart'; import '../utils/constants.dart'; import '../widgets/dialog_gameover.dart'; class LetterButtons extends StatelessWidget { - const LetterButtons({Key? key}) : super(key: key); + const LetterButtons({super.key}); @override Widget build(BuildContext context) { - Orientation orientation = MediaQuery.of(context).orientation; + final Orientation orientation = MediaQuery.of(context).orientation; var size = MediaQuery.of(context).size; final double paddingTop = MediaQuery.of(context).padding.top; final double itemHeight = (size.height - paddingTop) / 2; final double itemWidth = size.width / 2; - Data _myProvider = Provider.of<Data>(context); + final Data myProvider = Provider.of<Data>(context); + + final List<String> lettersList = letters.split(''); + final List<Widget> keys = []; - List<String> lettersList = letters.split(''); - List<Widget> keys = []; - lettersList.forEach((key) { + for (var key in lettersList) { keys.add( Padding( padding: const EdgeInsets.all(2.0), - child: ElevatedButton( - style: ElevatedButton.styleFrom( + child: TextButton( + style: TextButton.styleFrom( backgroundColor: Colors.grey, foregroundColor: Colors.white, - shadowColor: Color(accent), + shadowColor: const Color(accent), ), - onPressed: _myProvider.usedLetters.contains(key) + onPressed: myProvider.usedLetters.contains(key) ? null : () async { - _myProvider.updateUsedLetters(key); - if (_myProvider.secretWord.contains(key)) { - for (int index = 0; index < _myProvider.secretWord.length; index++) { - if (key == _myProvider.secretWord[index]) { - _myProvider.updateHiddenWord(index, key); + myProvider.updateUsedLetters(key); + if (myProvider.secretWord.contains(key)) { + for (int index = 0; index < myProvider.secretWord.length; index++) { + if (key == myProvider.secretWord[index]) { + myProvider.updateHiddenWord(index, key); } } - if (_myProvider.hiddenWord == _myProvider.secretWord) { - _myProvider.addVictory(); + if (myProvider.hiddenWord == myProvider.secretWord) { + myProvider.addVictory(); showDialog( context: context, - builder: (context) => DialogGameOver(victory), + builder: (context) => const DialogGameOver(victory), ); } } else { - _myProvider.addError(); - if (_myProvider.errors == 8) { - await Future.delayed(Duration(milliseconds: 900)); //???? - _myProvider.addDefeat(); + myProvider.addError(); + if (myProvider.errors == 8) { + await Future.delayed(const Duration(milliseconds: 900)); //???? + myProvider.addDefeat(); showDialog( context: context, - builder: (context) => DialogGameOver(defeat), + builder: (context) => const DialogGameOver(defeat), ); } } @@ -66,12 +68,13 @@ class LetterButtons extends StatelessWidget { ), ), ); - }); + } + return Container( alignment: orientation == Orientation.portrait ? Alignment.bottomCenter : Alignment.center, - color: Color(darkGreen), - padding: EdgeInsets.all(10.0), + color: const Color(darkGreen), + padding: const EdgeInsets.all(10.0), margin: EdgeInsets.only(top: orientation == Orientation.portrait ? 0.0 : paddingTop), child: GridView.count( padding: EdgeInsets.zero, diff --git a/lib/widgets/my_app_bar.dart b/lib/widgets/my_app_bar.dart index 4737a1bb6eb3108a3c968eb1862b1811ef7d6987..230a4920c0cf55ca0ce00dfea3020fac40434f90 100644 --- a/lib/widgets/my_app_bar.dart +++ b/lib/widgets/my_app_bar.dart @@ -4,8 +4,9 @@ import 'package:flutter/services.dart' show SystemNavigator; import '../screens/scores.dart'; class MyAppBar extends StatelessWidget implements PreferredSizeWidget { + const MyAppBar({super.key, this.appBar}); + final AppBar? appBar; - const MyAppBar({Key? key, this.appBar}) : super(key: key); @override Size get preferredSize => Size.fromHeight(appBar?.preferredSize.height ?? 0.0); @@ -13,7 +14,7 @@ class MyAppBar extends StatelessWidget implements PreferredSizeWidget { @override Widget build(BuildContext context) { return AppBar( - title: Text('Hangman'), + title: const Text('Hangman'), automaticallyImplyLeading: false, actions: [ PopupMenuButton<String>( diff --git a/lib/words/list_french_words.dart b/lib/words/list_french_words.dart index 2c30936d57de57dabeade785bdae31d81a243c9a..26f77025aef6bd99628169924d664f0526b983e5 100644 --- a/lib/words/list_french_words.dart +++ b/lib/words/list_french_words.dart @@ -1,5 +1,5 @@ /// The list of french words, ~340,000 words in total -const List<String> list_french_words = [ +const List<String> listFrenchWords = [ 'a', 'à', 'abaissa', diff --git a/pubspec.lock b/pubspec.lock index 82c5618ab06a199f852de3ddf3f0b2e1b75d5bee..e2b0f4c5b1edd0b4cb6a0da78a520387e41db303 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" csslib: dependency: transitive description: @@ -37,31 +37,39 @@ packages: dependency: "direct main" description: name: diacritic - sha256: a84e03ec2779375fb86430dbe9d8fba62c68376f2499097a5f6e75556babe706 + sha256: "96db5db6149cbe4aa3cfcbfd170aca9b7648639be7e48025f9d458517f807fe4" url: "https://pub.dev" source: hosted - version: "0.1.4" + version: "0.1.5" ffi: dependency: transitive description: name: ffi - sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.2" file: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.0" flutter: dependency: "direct main" description: flutter source: sdk version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7 + url: "https://pub.dev" + source: hosted + version: "3.0.1" flutter_web_plugins: dependency: transitive description: flutter @@ -79,10 +87,10 @@ packages: dependency: "direct main" description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.1" http_parser: dependency: transitive description: @@ -91,22 +99,30 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + lints: + dependency: transitive + description: + name: lints + sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 + url: "https://pub.dev" + source: hosted + version: "3.0.0" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.11.0" nested: dependency: transitive description: @@ -119,10 +135,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_provider_linux: dependency: transitive description: @@ -135,10 +151,10 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_windows: dependency: transitive description: @@ -151,34 +167,34 @@ packages: dependency: transitive description: name: platform - sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.4" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" url: "https://pub.dev" source: hosted - version: "2.1.6" + version: "2.1.8" provider: dependency: "direct main" description: name: provider - sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f + sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096" url: "https://pub.dev" source: hosted - version: "6.0.5" + version: "6.1.1" shared_preferences: dependency: "direct main" description: name: shared_preferences - sha256: b7f41bad7e521d205998772545de63ff4e6c97714775902c199353f8bf1511ac + sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" shared_preferences_android: dependency: transitive description: @@ -191,42 +207,42 @@ packages: dependency: transitive description: name: shared_preferences_foundation - sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7" + sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c" url: "https://pub.dev" source: hosted - version: "2.3.4" + version: "2.3.5" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - sha256: c2eb5bf57a2fe9ad6988121609e47d3e07bb3bdca5b6f8444e4cf302428a128a + sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a + sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf + sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - sha256: f763a101313bd3be87edffe0560037500967de9c394a714cd598d945517f694f + sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" sky_engine: dependency: transitive description: flutter @@ -276,26 +292,26 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: "1d9158c616048c38f712a6646e317a3426da10e884447626167240d45209cbad" url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.5.0" win32: dependency: transitive description: name: win32 - sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" + sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8" url: "https://pub.dev" source: hosted - version: "5.0.9" + version: "5.2.0" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" + sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.0.4" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" - flutter: ">=3.7.0" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.19.0" diff --git a/pubspec.yaml b/pubspec.yaml index 927a124e34f889d9fa0252366176fc979f1d5e1e..1f6e51b00c0e7b8361e58ac17dff169c78e7c5cf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: hangman description: Hangman game, have fun with words and letters! publish_to: 'none' -version: 1.2.11+22 +version: 1.2.12+23 environment: sdk: '^3.0.0' @@ -15,6 +15,9 @@ dependencies: http: ^1.1.0 diacritic: ^0.1.4 +dev_dependencies: + flutter_lints: ^3.0.1 + flutter: uses-material-design: true assets: