From db4ee0cf0fc2c80bdad1041952a560076dc7c63a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr> Date: Tue, 13 Apr 2021 15:53:04 +0200 Subject: [PATCH] Store categories in JSON file, improve app conception --- android/gradle.properties | 4 +- assets/files/categories-fr.json | 94 ++++++++++ lib/main.dart | 270 +++------------------------- lib/provider/data.dart | 53 ++++++ lib/screens/home.dart | 161 +++++++++++++++++ lib/utils/random_pick_category.dart | 31 ++++ lib/utils/random_pick_letter.dart | 22 +++ pubspec.lock | 15 ++ pubspec.yaml | 3 + 9 files changed, 401 insertions(+), 252 deletions(-) create mode 100644 assets/files/categories-fr.json create mode 100644 lib/provider/data.dart create mode 100644 lib/screens/home.dart create mode 100644 lib/utils/random_pick_category.dart create mode 100644 lib/utils/random_pick_letter.dart diff --git a/android/gradle.properties b/android/gradle.properties index 2aadffb..ad752d3 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.1 -app.versionCode=7 +app.versionName=1.2.2 +app.versionCode=8 diff --git a/assets/files/categories-fr.json b/assets/files/categories-fr.json new file mode 100644 index 0000000..230043a --- /dev/null +++ b/assets/files/categories-fr.json @@ -0,0 +1,94 @@ +{ + "categories": [ + "Pays", + "Prénoms fille", + "Prénoms garçon", + "Animaux", + "Métiers", + "Villes", + "Dessins animés", + "Séries", + "Films", + "Auteurs (littéraire)", + "Acteurs / Actices", + "Chanteurs / Chanteuses", + "Choses / Objets", + "Fruits et/ou légumes", + "Couleurs", + "Marques", + "Moyens de transport", + "Outils", + "Capitales", + "Instruments de musique", + "Boissons", + "Fleurs", + "Plats", + "Personnages historiques", + "Vêtements", + + "Minéraux et pierres précieuses", + "Étoiles, planètes et constellations", + "Fleuves, cours d'eau et océans", + "Partie du corps humain", + "Oiseaux", + "Poissons", + "Qualités et défauts", + "Arbres", + "Bandes dessinées", + "Départements français", + "Insectes", + "Desserts", + "Mammifères", + "Epices", + "Héros de mythologie", + "Héros fictifs", + "Fromages", + "Jeux", + "Eléments de véhicules", + "Ustensils de ménage", + "Sites internet", + "Sportifs", + + "Félins", + "Sculpteurs", + "Monnaies du monde", + "Mots de plus de 8 lettres", + "Cadeaux de Noël", + "Marques de voiture", + "Titres de magazines", + "Mots en anglais", + "Mots en espagnol", + "Compositeurs de musiques classiques", + "Footballeurs", + "Pays d'Afrique", + "Pays d'Amérique", + "Pays d'Asie", + "Pays d'Europe", + "Races de chiens", + "Races de chats", + "Héros de comics", + "Métiers dont rêvent les enfants", + "Tennisman", + "Sports collectifs", + "Humoristes", + "Objets/Choses qui se trouvent dans une voiture", + "Objets/Choses qui se trouvent dans un camping", + "Choses qui se trouvent dans un cartable d'écolier", + "Villes françaises", + "Emissions de TV", + "Peintres célèbres", + "Contes de fées", + "Titres de chansons", + + "Qui sent mauvais", + "Qui fait plaisir", + "Se trouve dans un sac à main", + "Noms que l'on donne à un doudou", + "Mauvais pour la santé", + "Mauvais pour l'environement", + "Phobies", + "Plats que l'on peut manger à la cantine scolaire ou professionnelle", + "Emissions de télé-réalité", + "Choses qui grattent" + ] +} diff --git a/lib/main.dart b/lib/main.dart index efb9aa0..a317c62 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,259 +1,29 @@ import 'package:flutter/material.dart'; -import 'dart:math'; -import 'dart:async'; +import 'package:provider/provider.dart'; -void main() { - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Petit bac', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: MyHomePage(title: 'Petit bac'), - ); - } -} - -class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); - - final String title; - final Random _rnd = Random(); - final String _chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - final List _categories = [ - 'Pays', - 'Prénoms fille', - 'Prénoms garçon', - 'Animaux', - 'Métiers', - 'Villes', - 'Dessins animés', - 'Séries', - 'Films', - 'Auteurs (littéraire)', - 'Acteurs / Actices', - 'Chanteurs / Chanteuses', - 'Choses / Objets', - 'Fruits et/ou légumes', - 'Couleurs', - 'Marques', - 'Moyens de transport', - 'Outils', - 'Capitales', - 'Instruments de musique', - 'Boissons', - 'Fleurs', - 'Plats', - 'Personnages historiques', - 'Vêtements', - - 'Minéraux et pierres précieuses', - 'Étoiles, planètes et constellations', - 'Fleuves, cours d\'eau et océans', - 'Partie du corps humain', - 'Oiseaux', - 'Poissons', - 'Qualités et défauts', - 'Arbres', - 'Bandes dessinées', - 'Départements français', - 'Insectes', - 'Desserts', - 'Mammifères', - 'Epices', - 'Héros de mythologie', - 'Héros fictifs', - 'Fromages', - 'Jeux', - 'Eléments de véhicules', - 'Ustensils de ménage', - 'Sites internet', - 'Sportifs', - - 'Félins', - 'Sculpteurs', - 'Monnaies du monde', - 'Mots de plus de 8 lettres', - 'Cadeaux de Noël', - 'Marques de voiture', - 'Titres de magazines', - 'Mots en anglais', - 'Mots en espagnol', - 'Compositeurs de musiques classiques', - 'Footballeurs', - 'Pays d\'Afrique', - 'Pays d\'Amérique', - 'Pays d\'Asie', - 'Pays d\'Europe', - 'Races de chiens', - 'Races de chats', - 'Héros de comics', - 'Métiers dont rêvent les enfants', - 'Tennisman', - 'Sports collectifs', - 'Humoristes', - 'Objets/Choses qui se trouvent dans une voiture', - 'Objets/Choses qui se trouvent dans un camping', - 'Choses qui se trouvent dans un cartable d\'écolier', - 'Villes françaises', - 'Emissions de TV', - 'Peintres célèbres', - 'Contes de fées', - 'Titres de chansons', - - 'Qui sent mauvais', - 'Qui fait plaisir', - 'Se trouve dans un sac à main', - 'Noms que l\'on donne à un doudou', - 'Mauvais pour la santé', - 'Mauvais pour l\'environement', - 'Phobies', - 'Plats que l\'on peut manger à la cantine scolaire ou professionnelle', - 'Emissions de télé-réalité', - 'Choses qui grattent', - ]; - - @override - _MyHomePageState createState() => _MyHomePageState(); -} +import 'provider/data.dart'; +import 'screens/home.dart'; -class _MyHomePageState extends State<MyHomePage> { - String _randomLetter = ''; - String _randomCategory = ''; - Timer _timer; - int _start = 10; - - void _pickRandomLetter() { - setState(() { - _randomLetter = widget._chars[widget._rnd.nextInt(widget._chars.length)]; - }); - } - - void _pickRandomCategory() { - setState(() { - _randomCategory = widget._categories[widget._rnd.nextInt(widget._categories.length)]; - }); - } - - void _startMiniGame() { - _pickRandomLetter(); - _pickRandomCategory(); - startTimer(); - } - - @override - void initState() { - _pickRandomLetter(); - _pickRandomCategory(); - } - - void startTimer() { - const oneSec = const Duration(seconds: 1); - if (_timer != null) { - _timer.cancel(); - } - _start = 10; - _timer = new Timer.periodic( - oneSec, - (Timer timer) { - if (_start == 0) { - setState(() { - timer.cancel(); - }); - } else { - setState(() { - _start--; - }); - } - }, - ); - } - - @override - void dispose() { - _timer.cancel(); - super.dispose(); - } +void main() => runApp(MyApp()); +class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(widget.title), - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: <Widget>[ - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: <Widget>[ - Text( - '$_randomLetter', - style: Theme.of(context).textTheme.headline2, - ), - RaisedButton( - onPressed: _pickRandomLetter, - color: Colors.orange, - padding: EdgeInsets.all(10.0), - child: Row( - children: <Widget>[ - Icon(Icons.shuffle), - Text("Piocher une lettre") - ], - ), - ), - ], - ), - SizedBox(height: 20), - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: <Widget>[ - Text( - '$_randomCategory', - style: Theme.of(context).textTheme.headline3, - ), - FlatButton( - onPressed: _pickRandomCategory, - color: Colors.orange, - padding: EdgeInsets.all(10.0), - child: Row( - children: <Widget>[ - Icon(Icons.shuffle), - Text("Piocher une catégorie") - ], - ), - ), - ], - ), - SizedBox(height: 40), - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: <Widget>[ - FlatButton( - onPressed: _startMiniGame, - color: Colors.blue, - padding: EdgeInsets.all(10.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: <Widget>[ - Text( - '$_start', - style: Theme.of(context).textTheme.headline2, - ), - ], - ), - ), - ], - ), - ], - ), - ), + return ChangeNotifierProvider( + create: (BuildContext context) => Data(), + child: Consumer<Data>(builder: (context, data, child) { + return MaterialApp( + debugShowCheckedModeBanner: false, + theme: ThemeData( + primaryColor: Colors.blue, + visualDensity: VisualDensity.adaptivePlatformDensity, + ), + home: Home(), + routes: { + Home.id: (context) => Home(), + }, + ); + }), ); } } diff --git a/lib/provider/data.dart b/lib/provider/data.dart new file mode 100644 index 0000000..1c709ad --- /dev/null +++ b/lib/provider/data.dart @@ -0,0 +1,53 @@ +import 'package:flutter/foundation.dart'; + +class Data extends ChangeNotifier { + + // randomization + bool _searchingCategory = false; + bool _searchingLetter = false; + String _category = ''; + String _letter = ''; + int _timer = 0; + + bool get searchingCategory => _searchingCategory; + + set searchingCategory(bool value) { + _searchingCategory = value; + notifyListeners(); + } + + bool get searchingLetter => _searchingLetter; + + set searchingLetter(bool value) { + _searchingLetter = value; + notifyListeners(); + } + + String get category => _category; + + set updateCategory(String value) { + _category = value; + notifyListeners(); + } + + String get letter => _letter; + + set updateLetter(String value) { + _letter = value; + notifyListeners(); + } + + int get timer => _timer; + + set updateTimer(int value) { + _timer = value; + notifyListeners(); + } + + void resetGame() { + _category = ''; + _letter = ''; + _timer = 0; + notifyListeners(); + } +} diff --git a/lib/screens/home.dart b/lib/screens/home.dart new file mode 100644 index 0000000..5da13a0 --- /dev/null +++ b/lib/screens/home.dart @@ -0,0 +1,161 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'dart:math'; +import 'dart:async'; + +import '../provider/data.dart'; +import '../utils/random_pick_category.dart'; +import '../utils/random_pick_letter.dart'; + +class Home extends StatelessWidget { + static const String id = 'home'; + + String _randomLetter = ''; + String _randomCategory = ''; + Timer _timer; + int _timerStart = 10; + + Future<void> startMiniGame(BuildContext context, Data myProvider) async { + pickCategory(context, myProvider); + pickLetter(context, myProvider); + startTimer(context, myProvider); + } + + Future<void> startTimer(BuildContext context, Data myProvider) async { + const oneSec = const Duration(seconds: 1); + if (_timer != null) { + _timer.cancel(); + } + _timerStart = 10; + myProvider.updateTimer = _timerStart; + _timer = new Timer.periodic( + oneSec, + (Timer timer) { + if (_timerStart == 0) { + timer.cancel(); + } else { + _timerStart--; + myProvider.updateTimer = _timerStart; + } + }, + ); + } + + @override + void dispose() { + _timer.cancel(); + } + + Future<void> pickCategory(BuildContext context, Data myProvider) async { + myProvider.searchingCategory = true; + RandomPickCategory randomPickCategory; + int attempts = 0; + do { + randomPickCategory = RandomPickCategory(); + await randomPickCategory.init(); + if (randomPickCategory.category != null) { + myProvider.updateCategory = randomPickCategory.category; + myProvider.searchingCategory = false; + break; + } + attempts++; + } while (attempts < 3); + } + + Future<void> pickLetter(BuildContext context, Data myProvider) async { + myProvider.searchingLetter = true; + RandomPickLetter randomPickLetter; + int attempts = 0; + do { + randomPickLetter = RandomPickLetter(); + await randomPickLetter.init(); + if (randomPickLetter.letter != null) { + myProvider.updateLetter = randomPickLetter.letter; + myProvider.searchingLetter = false; + break; + } + attempts++; + } while (attempts < 3); + } + + + @override + Widget build(BuildContext context) { + Data _myProvider = Provider.of<Data>(context); + + return Scaffold( + appBar: AppBar( + title: Text('Petit bac'), + ), + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: <Widget>[ + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: <Widget>[ + Text( + _myProvider.letter, + style: Theme.of(context).textTheme.headline2, + ), + RaisedButton( + onPressed: () => pickLetter(context, _myProvider), + color: Colors.orange, + padding: EdgeInsets.all(10.0), + child: Row( + children: <Widget>[ + Icon(Icons.shuffle), + Text("Piocher une lettre") + ], + ), + ), + ], + ), + SizedBox(height: 20), + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: <Widget>[ + Text( + _myProvider.category, + style: Theme.of(context).textTheme.headline3, + ), + FlatButton( + onPressed: () => pickCategory(context, _myProvider), + color: Colors.orange, + padding: EdgeInsets.all(10.0), + child: Row( + children: <Widget>[ + Icon(Icons.shuffle), + Text("Piocher une catégorie") + ], + ), + ), + ], + ), + SizedBox(height: 40), + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: <Widget>[ + FlatButton( + onPressed: () => startMiniGame(context, _myProvider), + color: Colors.blue, + padding: EdgeInsets.all(10.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: <Widget>[ + Text( + _myProvider.timer.toString(), + style: Theme.of(context).textTheme.headline2, + ), + ], + ), + ), + ], + ), + ], + ), + ), + ); + } +} diff --git a/lib/utils/random_pick_category.dart b/lib/utils/random_pick_category.dart new file mode 100644 index 0000000..7ef32ba --- /dev/null +++ b/lib/utils/random_pick_category.dart @@ -0,0 +1,31 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:flutter/services.dart'; +import 'dart:math' show Random; + +class RandomPickCategory { + RandomPickCategory(); + + String _category; + final random = Random(); + + init() async { + await categoryFromLocalFile(); + } + + Future<void> categoryFromLocalFile() async { + String jsonString; + try { + jsonString = await rootBundle.loadString('assets/files/categories-fr.json'); + final jsonResponse = await json.decode(jsonString); + var categoryList = jsonResponse[jsonResponse.keys.toList().join()]; + int randomCategoryIndex = random.nextInt(categoryList.length); + String category = categoryList[random.nextInt(categoryList.length)]; + _category = category ?? 'UNEXPECTED ERROR'; + } catch (e) { + _category = 'UNEXPECTED ERROR'; + } + } + + String get category => _category; +} diff --git a/lib/utils/random_pick_letter.dart b/lib/utils/random_pick_letter.dart new file mode 100644 index 0000000..15635c9 --- /dev/null +++ b/lib/utils/random_pick_letter.dart @@ -0,0 +1,22 @@ +import 'dart:async'; +import 'dart:convert'; +import 'package:flutter/services.dart'; +import 'dart:math' show Random; + +class RandomPickLetter { + RandomPickLetter(); + + String _letter; + final random = Random(); + final String _chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + + init() async { + await letterFromLocalFile(); + } + + Future<void> letterFromLocalFile() async { + _letter = _chars[random.nextInt(_chars.length)]; + } + + String get letter => _letter; +} diff --git a/pubspec.lock b/pubspec.lock index 9e492de..48d7003 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -74,6 +74,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0" + nested: + dependency: transitive + description: + name: nested + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" path: dependency: transitive description: @@ -81,6 +88,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0" + provider: + dependency: "direct main" + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.0" sky_engine: dependency: transitive description: flutter @@ -144,3 +158,4 @@ packages: version: "2.1.0" sdks: dart: ">=2.12.0-0.0 <3.0.0" + flutter: ">=1.16.0" diff --git a/pubspec.yaml b/pubspec.yaml index 9e1633f..ba60a9c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,6 +9,7 @@ environment: dependencies: flutter: sdk: flutter + provider: ^5.0.0 dev_dependencies: flutter_test: @@ -16,3 +17,5 @@ dev_dependencies: flutter: uses-material-design: true + assets: + - assets/files/ -- GitLab