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 ad6a6f31e64926d71ad8741a524f4a9a7946a3d1..fe8bedd11648e2bac231b68b065ca0a7d764eecd 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -44,7 +44,7 @@ android { defaultConfig { applicationId "org.benoitharrault.tetrisdual" - minSdkVersion 16 + minSdkVersion flutter.minSdkVersion targetSdkVersion 30 versionCode appVersionCode.toInteger() versionName appVersionName diff --git a/android/gradle.properties b/android/gradle.properties index 65eed6426393974efb5a056ec44936d42b5ef2a1..4bb5439f682100f8ef4ba80a557fe4f2f0ab14c2 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=0.0.8 -app.versionCode=8 +app.versionName=0.0.9 +app.versionCode=9 diff --git a/fastlane/metadata/android/en-US/changelogs/9.txt b/fastlane/metadata/android/en-US/changelogs/9.txt new file mode 100644 index 0000000000000000000000000000000000000000..6ab11150150fc75a46c9acc317890208e5a120b9 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/9.txt @@ -0,0 +1 @@ +Add automatic flutter linter. Apply code lints. Update dependencies. diff --git a/fastlane/metadata/android/fr-FR/changelogs/9.txt b/fastlane/metadata/android/fr-FR/changelogs/9.txt new file mode 100644 index 0000000000000000000000000000000000000000..315dd65b6fea52abf09c73bd8b62e0a6e41082b7 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/9.txt @@ -0,0 +1 @@ +Ajout d'un correcteur automatique de code. Application des correction. Mise à jour des dépendances. diff --git a/lib/entity/counter.dart b/lib/entity/counter.dart index f9ae8597d1f871e82b78346071505fc703891a38..31fedae0d2c1f1bf3858fc36569b109c3caacbc0 100644 --- a/lib/entity/counter.dart +++ b/lib/entity/counter.dart @@ -1,6 +1,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; + import 'package:tetrisdual/provider/data.dart'; class Counter { @@ -10,56 +11,79 @@ class Counter { int _holes = 0; // Count non fillable holes caused by this new tetrimino // Points definitions - int _base = 50; - int _pointsIfMatch = 50; - int _pointsPerLine = 60; - int _pointsPerHole = -10; + static const int _base = 50; + static const int _pointsIfMatch = 50; + static const int _pointsPerLine = 60; + static const int _pointsPerHole = -10; - Color categoryIconColor = Colors.green; - Color buttonIconColor = Colors.blue; - double iconSize = 30.0; + static const double iconSize = 30.0; + static const double fontSize = 50.0; + static const double spacerHeight = 7; - TableRow spacer() { - double height = 7; - return TableRow(children: [ - SizedBox(height: height), - SizedBox(height: height), - SizedBox(height: height), - SizedBox(height: height) - ]); - } + // Counter categories icons + static const Color categoryIconColor = Colors.green; + static const Icon iconTouchingColor = Icon( + Icons.join_full, + color: categoryIconColor, + size: iconSize, + ); + static const Icon iconRowsCount = Icon( + Icons.table_rows, + color: categoryIconColor, + size: iconSize, + ); + static const Icon iconHolesCount = Icon( + Icons.check_box_outline_blank, + color: categoryIconColor, + size: iconSize, + ); + + // Action buttons icons + static const Color buttonIconColor = Colors.blue; + static const Icon iconRemove = Icon( + Icons.remove, + color: buttonIconColor, + size: iconSize, + ); + static const Icon iconAdd = Icon( + Icons.add, + color: buttonIconColor, + size: iconSize, + ); Widget buildCounterWidget(Data myProvider) { - return Container( - child: Table( - children: [ - buildMatchWidget(myProvider), - spacer(), - buildLinesWidget(myProvider), - spacer(), - buildHolesWidget(myProvider), - spacer(), - ], - ), + return Table( + children: [ + buildMatchWidget(myProvider), + buildSpacerRow(), + buildLinesWidget(myProvider), + buildSpacerRow(), + buildHolesWidget(myProvider), + buildSpacerRow(), + ], ); } + TableRow buildSpacerRow() { + return const TableRow(children: [ + SizedBox(height: spacerHeight), + SizedBox(height: spacerHeight), + SizedBox(height: spacerHeight), + SizedBox(height: spacerHeight) + ]); + } + TableRow buildMatchWidget(Data myProvider) { return TableRow( children: [ - Icon( - Icons.join_full, - color: categoryIconColor, - size: iconSize, - ), + iconTouchingColor, IconButton( padding: EdgeInsets.zero, - constraints: BoxConstraints(), - icon: Icon( - Icons.remove, - color: buttonIconColor, - size: iconSize, + constraints: const BoxConstraints(), + style: const ButtonStyle( + tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), + icon: iconRemove, onPressed: () { _match = false; myProvider.redraw(); @@ -74,12 +98,11 @@ class Counter { ), IconButton( padding: EdgeInsets.zero, - constraints: BoxConstraints(), - icon: Icon( - Icons.add, - color: buttonIconColor, - size: iconSize, + constraints: const BoxConstraints(), + style: const ButtonStyle( + tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), + icon: iconAdd, onPressed: () { _match = true; myProvider.redraw(); @@ -92,19 +115,14 @@ class Counter { TableRow buildLinesWidget(Data myProvider) { return TableRow( children: [ - Icon( - Icons.table_rows, - color: categoryIconColor, - size: iconSize, - ), + iconRowsCount, IconButton( padding: EdgeInsets.zero, - constraints: BoxConstraints(), - icon: Icon( - Icons.remove, - color: buttonIconColor, - size: iconSize, + constraints: const BoxConstraints(), + style: const ButtonStyle( + tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), + icon: iconRemove, onPressed: () { _lines = max(_lines - 1, 0); myProvider.redraw(); @@ -113,20 +131,23 @@ class Counter { Center( child: Text( _lines.toString(), - style: TextStyle( + style: const TextStyle( fontFamily: 'Blocks', - fontSize: 50, + fontSize: fontSize, + ), + textHeightBehavior: const TextHeightBehavior( + applyHeightToFirstAscent: false, + applyHeightToLastDescent: false, ), ), ), IconButton( padding: EdgeInsets.zero, - constraints: BoxConstraints(), - icon: Icon( - Icons.add, - color: buttonIconColor, - size: iconSize, + constraints: const BoxConstraints(), + style: const ButtonStyle( + tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), + icon: iconAdd, onPressed: () { _lines = min(_lines + 1, 4); myProvider.redraw(); @@ -139,19 +160,14 @@ class Counter { TableRow buildHolesWidget(Data myProvider) { return TableRow( children: [ - Icon( - Icons.check_box_outline_blank, - color: categoryIconColor, - size: iconSize, - ), + iconHolesCount, IconButton( padding: EdgeInsets.zero, - constraints: BoxConstraints(), - icon: Icon( - Icons.remove, - color: buttonIconColor, - size: iconSize, + constraints: const BoxConstraints(), + style: const ButtonStyle( + tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), + icon: iconRemove, onPressed: () { _holes = max(_holes - 1, 0); myProvider.redraw(); @@ -160,22 +176,25 @@ class Counter { Center( child: Text( _holes.toString(), - style: TextStyle( + style: const TextStyle( fontFamily: 'Blocks', - fontSize: 50, + fontSize: fontSize, + ), + textHeightBehavior: const TextHeightBehavior( + applyHeightToFirstAscent: false, + applyHeightToLastDescent: false, ), ), ), IconButton( padding: EdgeInsets.zero, - constraints: BoxConstraints(), - icon: Icon( - Icons.add, - color: buttonIconColor, - size: iconSize, + constraints: const BoxConstraints(), + style: const ButtonStyle( + tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), + icon: iconAdd, onPressed: () { - _holes = min(_holes + 1, 4); + _holes = min(_holes + 1, 9); myProvider.redraw(); }, ), diff --git a/lib/entity/player.dart b/lib/entity/player.dart index fe637add88582623829d352a7846c31ff5acb827..cef7f92cdc452487d61b7e6acbfda837020e75cf 100644 --- a/lib/entity/player.dart +++ b/lib/entity/player.dart @@ -1,6 +1,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; + import 'package:tetrisdual/entity/counter.dart'; import 'package:tetrisdual/layout/board_painter.dart'; import 'package:tetrisdual/provider/data.dart'; @@ -11,106 +12,108 @@ class Player { int _score = 0; int _currentTetrimino = 0; - Counter _counter = new Counter(); + final Counter _counter = Counter(); Widget buildTetriminoWidget(Data myProvider, double width) { - return Container( - child: GestureDetector( - onTapUp: (details) { - if (playerId == myProvider.getCurrentPlayer().playerId) { - pickRandomTetrimino(); - myProvider.redraw(); - } - }, - child: Container( - child: CustomPaint( - size: Size(width, width), - willChange: false, - painter: BoardPainter(_currentTetrimino), - isComplex: true, - key: Key(_currentTetrimino.toString()), - ), - ), + return GestureDetector( + onTapUp: (details) { + if (playerId == myProvider.getCurrentPlayer().playerId) { + pickRandomTetrimino(); + myProvider.redraw(); + } + }, + child: CustomPaint( + size: Size(width, width), + willChange: false, + painter: BoardPainter(_currentTetrimino), + isComplex: true, + key: Key(_currentTetrimino.toString()), ), ); } Widget buildManagerWidget(Data myProvider) { - List<Widget> items = []; - - if (myProvider.currentPlayer == playerId) { - items.add(_counter.buildCounterWidget(myProvider)); - items.add(buildSubmitWidget(myProvider)); - } - return Expanded( child: Container( - margin: EdgeInsets.all(5), + margin: const EdgeInsets.all(5), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, - children: items, + children: myProvider.currentPlayer == playerId + ? [ + _counter.buildCounterWidget(myProvider), + buildSubmitWidget(myProvider), + ] + : [], ), ), ); } Widget buildSubmitWidget(Data myProvider) { - double fontSize = 70; + const double gainFontSize = 70; - return Container( - decoration: BoxDecoration( - border: Border( - top: BorderSide( - color: Colors.black, - width: 2, - ), + const gainTestStyle = TextStyle( + fontFamily: 'Blocks', + fontSize: gainFontSize, + fontWeight: FontWeight.bold, + ); + const submitIcon = Icon( + Icons.done_all, + color: Colors.orange, + size: gainFontSize / 2, + ); + + const topBorderBlack = BoxDecoration( + border: Border( + top: BorderSide( + color: Colors.black, + width: 2, ), ), - padding: EdgeInsets.only( - top: 5, + ); + + return Container( + decoration: topBorderBlack, + padding: const EdgeInsets.only( + top: 10, ), child: Row( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - '+' + _counter.computePoints().toString(), - style: TextStyle( - fontFamily: 'Blocks', - fontSize: fontSize, - fontWeight: FontWeight.bold, + '+${_counter.computePoints()}', + style: gainTestStyle, + textHeightBehavior: const TextHeightBehavior( + applyHeightToFirstAscent: false, + applyHeightToLastDescent: false, ), ), - SizedBox( - width: 10, - ), + const SizedBox(width: 10), IconButton( padding: EdgeInsets.zero, - constraints: BoxConstraints(), - icon: Icon( - Icons.done_all, - color: Colors.orange, - size: fontSize / 2.5, + constraints: const BoxConstraints(), + style: const ButtonStyle( + tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), + icon: submitIcon, onPressed: () { _score = _score + _counter.computePoints(); _counter.reset(); myProvider.toggleCurrentPlayer(); }, ), - SizedBox( - width: 10, - ), + const SizedBox(width: 10), ], ), ); } Widget buildPlayerBoard(Data myProvider, double screenWidth, bool isActive) { - double tetriminoBlockWidth = screenWidth / 2.3; - Color borderColor = isActive ? Colors.greenAccent : Colors.blueGrey; - double borderWidth = 10; + final double tetriminoBlockWidth = screenWidth / 2.3; + final Color borderColor = isActive ? Colors.greenAccent : Colors.blueGrey; + const double borderWidth = 10; return Column( mainAxisAlignment: MainAxisAlignment.center, @@ -118,11 +121,15 @@ class Player { children: [ Text( _score.toString(), - style: TextStyle( + style: const TextStyle( fontFamily: 'Blocks', fontSize: 130, fontWeight: FontWeight.bold, ), + textHeightBehavior: const TextHeightBehavior( + applyHeightToFirstAscent: false, + applyHeightToLastDescent: false, + ), ), Container( decoration: BoxDecoration( @@ -132,8 +139,8 @@ class Player { ), ), child: Row( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, children: [ isActive ? buildTetriminoWidget(myProvider, tetriminoBlockWidth) diff --git a/lib/layout/board.dart b/lib/layout/board.dart index 34118b7efe03e5db5e1ba0a634ee357e6bc4c803..b324c6ff4d0dfd583761f8e95a157ae889dfbf46 100644 --- a/lib/layout/board.dart +++ b/lib/layout/board.dart @@ -1,31 +1,37 @@ import 'package:flutter/material.dart'; + import 'package:tetrisdual/provider/data.dart'; class Board { - static Container buildGameBoard(Data myProvider, double screenWidth) { - Widget player1 = new RotatedBox( + static Widget buildGameBoard(Data myProvider, double screenWidth) { + final Widget player1 = RotatedBox( quarterTurns: 2, child: myProvider .getPlayer(1) .buildPlayerBoard(myProvider, screenWidth, myProvider.currentPlayer == 1), ); - Widget player2 = myProvider + + final Widget player2 = myProvider .getPlayer(2) .buildPlayerBoard(myProvider, screenWidth, myProvider.currentPlayer == 2); - Widget togglePlayerWidget = GestureDetector( + final Widget togglePlayerWidget = GestureDetector( onTapUp: (details) { myProvider.toggleCurrentPlayer(); }, - child: Text( + child: const Text( '🔄', style: TextStyle( fontSize: 50, ), + textHeightBehavior: TextHeightBehavior( + applyHeightToFirstAscent: false, + applyHeightToLastDescent: false, + ), ), ); - return Container( + return Center( child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, diff --git a/lib/layout/board_painter.dart b/lib/layout/board_painter.dart index 1ec3cc1b91c718e077b8761b9009767e8e75c2b6..1ada211ad7ce141581510a49bb35bc5e21feff87 100644 --- a/lib/layout/board_painter.dart +++ b/lib/layout/board_painter.dart @@ -7,10 +7,15 @@ class BoardPainter extends CustomPainter { final int currentTetrimino; - void drawPixels(List<List<int>> pixels, Canvas canvas, double drawSize, Color pixelColor) { + void drawPixels( + List<List<int>> pixels, + Canvas canvas, + double drawSize, + Color pixelColor, + ) { int blockWidth = 1; int blockHeight = 1; - pixels.forEach((pixel) { + for (List<int> pixel in pixels) { int x = pixel[0] + 1; int y = pixel[1] + 1; if (x > blockWidth) { @@ -19,52 +24,53 @@ class BoardPainter extends CustomPainter { if (y > blockHeight) { blockHeight = y; } - }); + } - double pixelSize = drawSize / (max(blockWidth, blockHeight) + 2); - double xOffset = + final double pixelSize = drawSize / (max(blockWidth, blockHeight) + 2); + final double xOffset = (blockHeight > blockWidth) ? (blockHeight - blockWidth) * pixelSize / 2 : 0; - double yOffset = + final double yOffset = (blockWidth > blockHeight) ? (blockWidth - blockHeight) * pixelSize / 2 : 0; // Fill background final paintPixelBackground = Paint(); paintPixelBackground.color = pixelColor; paintPixelBackground.style = PaintingStyle.fill; - pixels.forEach((pixel) { - int x = pixel[0]; - int y = pixel[1]; + for (List<int> pixel in pixels) { + final int x = pixel[0]; + final int y = pixel[1]; final Rect pixelBackground = Rect.fromPoints( Offset(xOffset + pixelSize * (x + 1), yOffset + pixelSize * (y + 1)), Offset(xOffset + pixelSize * (x + 2), yOffset + pixelSize * (y + 2))); canvas.drawRect(pixelBackground, paintPixelBackground); - }); + } // Border lines final paintPixelBorder = Paint(); paintPixelBorder.color = Colors.grey.shade200; paintPixelBorder.style = PaintingStyle.stroke; paintPixelBorder.strokeWidth = 4; - pixels.forEach((pixel) { - int x = pixel[0]; - int y = pixel[1]; + for (List<int> pixel in pixels) { + final int x = pixel[0]; + final int y = pixel[1]; final Rect rectBackground = Rect.fromPoints( Offset(xOffset + pixelSize * (x + 1), yOffset + pixelSize * (y + 1)), Offset(xOffset + pixelSize * (x + 2), yOffset + pixelSize * (y + 2))); canvas.drawRect(rectBackground, paintPixelBorder); - }); + } } @override void paint(Canvas canvas, Size size) { - double drawSize = min(size.width, size.height); + final double drawSize = min(size.width, size.height); // Fill background final paintBackground = Paint(); paintBackground.color = Colors.grey.shade800; paintBackground.style = PaintingStyle.fill; - final Rect rectBackground = Rect.fromPoints(Offset(0, 0), Offset(drawSize, drawSize)); + final Rect rectBackground = + Rect.fromPoints(const Offset(0, 0), Offset(drawSize, drawSize)); canvas.drawRect(rectBackground, paintBackground); // Add tetrimino diff --git a/lib/layout/game.dart b/lib/layout/game.dart index 4d44d2dcde0bbafe9763eca9673c285d22538b1c..b8a54c803d424b0059b7c509f2d2e82072d453cf 100644 --- a/lib/layout/game.dart +++ b/lib/layout/game.dart @@ -1,20 +1,19 @@ import 'package:flutter/material.dart'; + import 'package:tetrisdual/layout/board.dart'; import 'package:tetrisdual/provider/data.dart'; import 'package:tetrisdual/utils/game_utils.dart'; class Game { - static Container buildGameWidget(Data myProvider, double screenWidth) { - return Container( - child: !myProvider.isGameFinished - ? Board.buildGameBoard(myProvider, screenWidth) - : Game.buildEndGameMessage(myProvider), - ); + static Widget buildGameWidget(Data myProvider, double screenWidth) { + return !myProvider.isGameFinished + ? Board.buildGameBoard(myProvider, screenWidth) + : Game.buildEndGameMessage(myProvider); } static TextButton buildQuitGameButton(Data myProvider) { return TextButton( - child: Image( + child: const Image( image: AssetImage('assets/icons/button_back.png'), fit: BoxFit.fill, ), @@ -23,21 +22,21 @@ class Game { } static Container buildEndGameMessage(Data myProvider) { - String decorationImageAssetName = 'assets/icons/game_fail.png'; + const String decorationImageAssetName = 'assets/icons/game_fail.png'; - Widget decorationWidget = TextButton( - child: Image( + final Widget decorationWidget = TextButton( + child: const Image( image: AssetImage(decorationImageAssetName), fit: BoxFit.fill, ), - onPressed: () => null, + onPressed: () {}, ); return Container( - margin: EdgeInsets.all(2), - padding: EdgeInsets.all(2), + margin: const EdgeInsets.all(2), + padding: const EdgeInsets.all(2), child: Table( - defaultColumnWidth: IntrinsicColumnWidth(), + defaultColumnWidth: const IntrinsicColumnWidth(), children: [ TableRow( children: [ diff --git a/lib/layout/parameters.dart b/lib/layout/parameters.dart index b2d26077c5baee475f01adc4cde5487447388bab..97f81cfd2939f44abb01b4b754ca3a139b477f9a 100644 --- a/lib/layout/parameters.dart +++ b/lib/layout/parameters.dart @@ -1,55 +1,54 @@ import 'package:flutter/material.dart'; + import 'package:tetrisdual/provider/data.dart'; import 'package:tetrisdual/utils/game_utils.dart'; class Parameters { - static double separatorHeight = 2.0; - static double blockMargin = 3.0; - static double blockPadding = 2.0; - static Color buttonBackgroundColor = Colors.white; - static Color buttonBorderColorActive = Colors.blue; - static Color buttonBorderColorInactive = Colors.white; - static double buttonBorderWidth = 10.0; - static double buttonBorderRadius = 8.0; - static double buttonPadding = 0.0; - static double buttonMargin = 0.0; - - static Container buildParametersSelector(Data myProvider) { - List<Widget> lines = []; - - List parameters = myProvider.availableParameters; - for (var index = 0; index < parameters.length; index++) { + static const double separatorHeight = 2.0; + static const double blockMargin = 3.0; + static const double blockPadding = 2.0; + static const Color buttonBackgroundColor = Colors.white; + static const Color buttonBorderColorActive = Colors.blue; + static const Color buttonBorderColorInactive = Colors.white; + static const double buttonBorderWidth = 10.0; + static const double buttonBorderRadius = 8.0; + static const double buttonPadding = 0.0; + static const double buttonMargin = 0.0; + + static Widget buildParametersSelector(Data myProvider) { + final List<Widget> lines = []; + + final List<String> parameters = myProvider.availableParameters; + for (int index = 0; index < parameters.length; index++) { lines.add(buildParameterSelector(myProvider, parameters[index])); - lines.add(SizedBox(height: separatorHeight)); + lines.add(const SizedBox(height: separatorHeight)); } - Widget buttonsBlock = buildStartNewGameButton(myProvider); + final Widget buttonsBlock = buildStartNewGameButton(myProvider); - return Container( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox(height: separatorHeight), - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - children: lines, - ), - ), - SizedBox(height: separatorHeight), - Container( - child: buttonsBlock, + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox(height: separatorHeight), + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: lines, ), - ], - ), + ), + const SizedBox(height: separatorHeight), + Container( + child: buttonsBlock, + ), + ], ); } static Image buildImageWidget(String imageAssetCode) { return Image( - image: AssetImage('assets/icons/' + imageAssetCode + '.png'), + image: AssetImage('assets/icons/$imageAssetCode.png'), fit: BoxFit.fill, ); } @@ -65,7 +64,7 @@ class Parameters { children: [ TextButton( child: buildImageContainerWidget('placeholder'), - onPressed: () => null, + onPressed: () {}, ), ], ); @@ -73,10 +72,10 @@ class Parameters { static Container buildStartNewGameButton(Data myProvider) { return Container( - margin: EdgeInsets.all(blockMargin), - padding: EdgeInsets.all(blockPadding), + margin: const EdgeInsets.all(blockMargin), + padding: const EdgeInsets.all(blockPadding), child: Table( - defaultColumnWidth: IntrinsicColumnWidth(), + defaultColumnWidth: const IntrinsicColumnWidth(), children: [ TableRow( children: [ @@ -98,18 +97,18 @@ class Parameters { } static Widget buildParameterSelector(Data myProvider, String parameterCode) { - List availableValues = myProvider.getParameterAvailableValues(parameterCode); + final List<String> availableValues = myProvider.getParameterAvailableValues(parameterCode); if (availableValues.length == 1) { - return SizedBox(height: 0.0); + return const SizedBox(height: 0.0); } return Table( - defaultColumnWidth: IntrinsicColumnWidth(), + defaultColumnWidth: const IntrinsicColumnWidth(), children: [ TableRow( children: [ - for (var index = 0; index < availableValues.length; index++) + for (int index = 0; index < availableValues.length; index++) Column( children: [ _buildParameterButton(myProvider, parameterCode, availableValues[index]) @@ -122,16 +121,19 @@ class Parameters { } static Widget _buildParameterButton( - Data myProvider, String parameterCode, String parameterValue) { - String currentValue = myProvider.getParameterValue(parameterCode).toString(); + Data myProvider, + String parameterCode, + String parameterValue, + ) { + final String currentValue = myProvider.getParameterValue(parameterCode).toString(); - bool isActive = (parameterValue == currentValue); - String imageAsset = parameterCode + '_' + parameterValue; + final bool isActive = (parameterValue == currentValue); + final String imageAsset = '${parameterCode}_$parameterValue'; return TextButton( child: Container( - margin: EdgeInsets.all(buttonMargin), - padding: EdgeInsets.all(buttonPadding), + margin: const EdgeInsets.all(buttonMargin), + padding: const EdgeInsets.all(buttonPadding), decoration: BoxDecoration( color: buttonBackgroundColor, borderRadius: BorderRadius.circular(buttonBorderRadius), diff --git a/lib/main.dart b/lib/main.dart index b232341f260a92893c59aad787f867e50df4faad..121d1109f25290bd210df2442c310a169db8ab28 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,17 +1,20 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:tetrisdual/provider/data.dart'; -import 'package:tetrisdual/screens/home.dart'; import 'package:provider/provider.dart'; import 'package:overlay_support/overlay_support.dart'; +import 'package:tetrisdual/provider/data.dart'; +import 'package:tetrisdual/screens/home.dart'; + void main() { WidgetsFlutterBinding.ensureInitialized(); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]) - .then((value) => runApp(MyApp())); + .then((value) => runApp(const MyApp())); } class MyApp extends StatelessWidget { + const MyApp({super.key}); + @override Widget build(BuildContext context) { return ChangeNotifierProvider( @@ -19,14 +22,13 @@ class MyApp extends StatelessWidget { child: Consumer<Data>(builder: (context, data, child) { return OverlaySupport( child: MaterialApp( - debugShowCheckedModeBanner: false, theme: ThemeData( primaryColor: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), - home: Home(), + home: const Home(), routes: { - Home.id: (context) => Home(), + Home.id: (context) => const Home(), }, ), ); diff --git a/lib/provider/data.dart b/lib/provider/data.dart index 061baf17929c050ac48f182ec5c8041889cef5b2..b1f4ad0e5d4c79c0252a7762b9fa900f5da04412 100644 --- a/lib/provider/data.dart +++ b/lib/provider/data.dart @@ -2,32 +2,30 @@ import 'dart:math'; import 'package:flutter/foundation.dart'; import 'package:shared_preferences/shared_preferences.dart'; + import 'package:tetrisdual/entity/player.dart'; class Data extends ChangeNotifier { // Configuration available parameters - List _availableParameters = []; + final List<String> _availableParameters = []; - List get availableParameters => _availableParameters; + List<String> get availableParameters => _availableParameters; // Application default configuration // Application current configuration String getParameterValue(String parameterCode) { - switch (parameterCode) { - } + switch (parameterCode) {} return ''; } - List getParameterAvailableValues(String parameterCode) { - switch (parameterCode) { - } + List<String> getParameterAvailableValues(String parameterCode) { + switch (parameterCode) {} return []; } void setParameterValue(String parameterCode, String parameterValue) async { - switch (parameterCode) { - } + switch (parameterCode) {} final prefs = await SharedPreferences.getInstance(); prefs.setString(parameterCode, parameterValue); } @@ -75,12 +73,12 @@ class Data extends ChangeNotifier { } Player getPlayer(int playerId) { - int playerIndex = playerId - 1; + final int playerIndex = playerId - 1; Player? player = _players[playerIndex]; // Create new player if none if (null == player) { - player = new Player(playerId); + player = Player(playerId); _players[playerIndex] = player; } @@ -98,7 +96,7 @@ class Data extends ChangeNotifier { void resetGame() { _gameIsRunning = false; _gameIsFinished = false; - _players = [new Player(1), new Player(2)]; + _players = [Player(1), Player(2)]; notifyListeners(); } } diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 5b8ee82f10c9b18fdcaf0aaccb32a9b69e3b44bd..34cdc098057ec2fe06739f673a9aec55382fbbf2 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -1,19 +1,22 @@ import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:overlay_support/overlay_support.dart'; + import 'package:tetrisdual/layout/game.dart'; import 'package:tetrisdual/layout/parameters.dart'; import 'package:tetrisdual/provider/data.dart'; import 'package:tetrisdual/utils/game_utils.dart'; -import 'package:provider/provider.dart'; -import 'package:overlay_support/overlay_support.dart'; class Home extends StatefulWidget { + const Home({super.key}); + static const String id = 'home'; @override - _HomeState createState() => _HomeState(); + HomeState createState() => HomeState(); } -class _HomeState extends State<Home> { +class HomeState extends State<Home> { @override void initState() { super.initState(); @@ -21,42 +24,29 @@ class _HomeState extends State<Home> { @override Widget build(BuildContext context) { - Data myProvider = Provider.of<Data>(context); - double screenWidth = MediaQuery.of(context).size.width; + final Data myProvider = Provider.of<Data>(context); + final double screenWidth = MediaQuery.of(context).size.width; - List<Widget> menuActions = []; + final List<Widget> menuActions = []; if (myProvider.isGameRunning) { - menuActions = [ - TextButton( - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(4), - border: Border.all( - color: Colors.blue, - width: 4, - ), - ), - child: Image( - image: AssetImage('assets/icons/button_back.png'), - fit: BoxFit.fill, - ), - ), - onPressed: () => toast('Long press to quit game...'), - onLongPress: () => GameUtils.quitGame(myProvider), + menuActions.add(TextButton( + child: const Image( + image: AssetImage('assets/icons/button_back.png'), + fit: BoxFit.fill, ), - ]; + onPressed: () => toast('Long press to quit game...'), + onLongPress: () => GameUtils.quitGame(myProvider), + )); } return Scaffold( appBar: AppBar( actions: menuActions, ), - body: SafeArea( - child: myProvider.isGameRunning - ? Game.buildGameWidget(myProvider, screenWidth) - : Parameters.buildParametersSelector(myProvider), - ), + body: myProvider.isGameRunning + ? Game.buildGameWidget(myProvider, screenWidth) + : Parameters.buildParametersSelector(myProvider), ); } } diff --git a/lib/utils/game_utils.dart b/lib/utils/game_utils.dart index 5bd436ba68ef0e2c9943efce9b629e8e90326049..fed7b66ae2d25e27d9b6e4fc1ef9d702228f0ca2 100644 --- a/lib/utils/game_utils.dart +++ b/lib/utils/game_utils.dart @@ -6,8 +6,6 @@ class GameUtils { } static Future<void> startNewGame(Data myProvider) async { - print('Starting game'); - myProvider.resetGame(); myProvider.enableRandomPlayer(); myProvider.getCurrentPlayer().pickRandomTetrimino(); diff --git a/pubspec.lock b/pubspec.lock index f78ae3bfbc5b91625f56452dcbc944e3e78db356..394474ffa93627c54bc013d08e68346854cf7420 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,52 +21,68 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" 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 source: sdk version: "0.0.0" + 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: @@ -87,10 +103,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: @@ -103,10 +119,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: @@ -119,34 +135,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: @@ -159,42 +175,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 @@ -212,26 +228,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 239b6c1531400caa90940eaa3d23a4906488535e..456fd9def63bf71f451809812bbdd4363fa54843 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: tetrisdual description: Tetris Dual Game publish_to: 'none' -version: 1.0.0+1 +version: 0.0.9+9 environment: sdk: '^3.0.0' @@ -13,6 +13,9 @@ dependencies: shared_preferences: ^2.2.1 overlay_support: ^2.1.0 +dev_dependencies: + flutter_lints: ^3.0.1 + flutter: uses-material-design: true assets: