From 552ad84f100f9cfd5851d5c02e3ad970a1a90fd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr> Date: Sun, 18 Feb 2024 22:46:55 +0100 Subject: [PATCH] Use and apply flutter lints --- analysis_options.yaml | 1 + android/gradle.properties | 4 +- lib/config/menu.dart | 28 ++++----- lib/cubit/api_cubit.dart | 2 +- lib/cubit/api_state.dart | 1 + lib/cubit/settings_cubit.dart | 6 +- lib/main.dart | 2 +- lib/models/api_data.dart | 9 +-- lib/models/game/game.dart | 41 ++++++------- lib/models/game/game_board.dart | 7 ++- lib/models/game/game_cell.dart | 5 +- lib/models/game/game_settings.dart | 7 ++- lib/models/interface_type.dart | 4 +- lib/network/api.dart | 6 +- lib/repository/api.dart | 2 +- lib/ui/painters/cell_painter.dart | 2 +- lib/ui/painters/graph_painter.dart | 4 +- lib/ui/screens/about_page.dart | 8 +-- lib/ui/screens/api_page.dart | 6 +- lib/ui/screens/camera_page.dart | 6 +- lib/ui/screens/demo_page.dart | 28 ++++----- lib/ui/screens/game_page.dart | 8 +-- lib/ui/screens/graph_page.dart | 80 ++++++++++++------------- lib/ui/screens/settings_page.dart | 2 +- lib/ui/skeleton.dart | 2 +- lib/ui/widgets/api_data.dart | 14 ++--- lib/ui/widgets/app_bar.dart | 4 +- lib/ui/widgets/debug_bloc.dart | 4 +- lib/ui/widgets/error.dart | 4 +- lib/ui/widgets/game/game_board.dart | 18 +++--- lib/ui/widgets/game/game_score.dart | 18 +++--- lib/ui/widgets/game/game_settings.dart | 2 +- lib/ui/widgets/header_app.dart | 14 ++--- lib/ui/widgets/settings_form.dart | 22 +++---- lib/ui/widgets/take_picture_widget.dart | 56 ++++++++--------- lib/utils/picture_storage.dart | 4 +- pubspec.lock | 32 +++++++--- pubspec.yaml | 6 +- 38 files changed, 245 insertions(+), 224 deletions(-) create mode 100644 analysis_options.yaml diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..f9b3034 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1 @@ +include: package:flutter_lints/flutter.yaml diff --git a/android/gradle.properties b/android/gradle.properties index 84e1e41..99e5b79 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.0.45 -app.versionCode=46 +app.versionName=1.0.46 +app.versionCode=47 diff --git a/lib/config/menu.dart b/lib/config/menu.dart index 45c0692..b06e9eb 100644 --- a/lib/config/menu.dart +++ b/lib/config/menu.dart @@ -24,39 +24,39 @@ class MenuItem { class Menu { static List<MenuItem> items = [ - MenuItem( + const MenuItem( code: 'bottom_nav_sample', - icon: const Icon(UniconsLine.image), + icon: Icon(UniconsLine.image), page: DemoPage(), ), - MenuItem( + const MenuItem( code: 'bottom_nav_api', - icon: const Icon(UniconsLine.globe), + icon: Icon(UniconsLine.globe), page: ApiPage(), ), - MenuItem( + const MenuItem( code: 'bottom_nav_camera', - icon: const Icon(UniconsLine.camera), + icon: Icon(UniconsLine.camera), page: CameraPage(), ), - MenuItem( + const MenuItem( code: 'bottom_nav_chart', - icon: const Icon(UniconsLine.pen), + icon: Icon(UniconsLine.pen), page: GraphPage(), ), - MenuItem( + const MenuItem( code: 'bottom_nav_game', - icon: const Icon(UniconsLine.star), + icon: Icon(UniconsLine.star), page: GamePage(), ), - MenuItem( + const MenuItem( code: 'bottom_nav_settings', - icon: const Icon(UniconsLine.setting), + icon: Icon(UniconsLine.setting), page: SettingsPage(), ), - MenuItem( + const MenuItem( code: 'bottom_nav_about', - icon: const Icon(UniconsLine.info_circle), + icon: Icon(UniconsLine.info_circle), page: AboutPage(), ), ]; diff --git a/lib/cubit/api_cubit.dart b/lib/cubit/api_cubit.dart index 27b9f29..5fe5dd7 100644 --- a/lib/cubit/api_cubit.dart +++ b/lib/cubit/api_cubit.dart @@ -27,7 +27,7 @@ class ApiDataCubit extends HydratedCubit<ApiDataState> { } } } - print('emit new state: ' + stateAsString); + print('emit new state: $stateAsString'); emit(state); } diff --git a/lib/cubit/api_state.dart b/lib/cubit/api_state.dart index a930be0..86cbe00 100644 --- a/lib/cubit/api_state.dart +++ b/lib/cubit/api_state.dart @@ -16,6 +16,7 @@ class ApiDataFetchInitial extends ApiDataState {} class ApiDataFetchLoading extends ApiDataState {} class ApiDataFetchLoaded extends ApiDataState { + @override final ApiData data; const ApiDataFetchLoaded({ diff --git a/lib/cubit/settings_cubit.dart b/lib/cubit/settings_cubit.dart index 01d3b94..35d6c2d 100644 --- a/lib/cubit/settings_cubit.dart +++ b/lib/cubit/settings_cubit.dart @@ -35,9 +35,9 @@ class SettingsCubit extends HydratedCubit<SettingsState> { InterfaceType? interfaceType, }) { emit(SettingsState( - apiUrl: apiUrl != null ? apiUrl : state.apiUrl, - securityToken: securityToken != null ? securityToken : state.securityToken, - interfaceType: interfaceType != null ? interfaceType : state.interfaceType, + apiUrl: apiUrl ?? state.apiUrl, + securityToken: securityToken ?? state.securityToken, + interfaceType: interfaceType ?? state.interfaceType, )); } diff --git a/lib/main.dart b/lib/main.dart index 6b6e38b..ca105a7 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -63,7 +63,7 @@ class MyApp extends StatelessWidget { child: MaterialApp( title: 'Random application', theme: appTheme, - home: SkeletonScreen(), + home: const SkeletonScreen(), localizationsDelegates: context.localizationDelegates, supportedLocales: context.supportedLocales, locale: context.locale, diff --git a/lib/models/api_data.dart b/lib/models/api_data.dart index 8124108..0f8b8fc 100644 --- a/lib/models/api_data.dart +++ b/lib/models/api_data.dart @@ -21,13 +21,14 @@ class ApiData { Map<String, dynamic>? toJson() { return <String, dynamic>{ - 'number': this.number ?? 0, - 'md5': this.md5 ?? '', - 'updatedAt': this.updatedAt?.toString(), + 'number': number ?? 0, + 'md5': md5 ?? '', + 'updatedAt': updatedAt?.toString(), }; } + @override String toString() { - return jsonEncode(this.toJson()); + return jsonEncode(toJson()); } } diff --git a/lib/models/game/game.dart b/lib/models/game/game.dart index bf777d7..e099feb 100644 --- a/lib/models/game/game.dart +++ b/lib/models/game/game.dart @@ -37,57 +37,58 @@ class Game { } void stop() { - this.isRunning = false; - this.isFinished = true; + isRunning = false; + isFinished = true; } GameCell getCell(int x, int y) { - return this.board.cells[y][x]; + return board.cells[y][x]; } int? getCellValue(int x, int y) { - return this.getCell(x, y).value; + return getCell(x, y).value; } void updateCellValue(int x, int y, int? value) { - this.board.cells[y][x].value = value; + board.cells[y][x].value = value; } void setRandomCellValue(int x, int y, GameSettings settings) { final int maxValue = settings.colorsCount; - final rand = new Random(); + final rand = Random(); int value = 1 + rand.nextInt(maxValue); - this.board.cells[y][x].value = value; + board.cells[y][x].value = value; } void increaseMovesCount() { - this.movesCount += 1; + movesCount += 1; } void increaseScore(int? count) { - this.score += (count ?? 0); + score += (count ?? 0); } + @override String toString() { - return 'Game(' + this.toJson().toString() + ')'; + return 'Game(${toJson()})'; } Map<String, dynamic>? toJson() { return <String, dynamic>{ - 'board': this.board.toJson(), - 'settings': this.settings.toJson(), - 'isRunning': this.isRunning, - 'isFinished': this.isFinished, - 'availableBlocksCount': this.availableBlocksCount, - 'movesCount': this.movesCount, - 'score': this.score, + 'board': board.toJson(), + 'settings': settings.toJson(), + 'isRunning': isRunning, + 'isFinished': isFinished, + 'availableBlocksCount': availableBlocksCount, + 'movesCount': movesCount, + 'score': score, }; } void dump() { - GameBoard.printGrid(this.board.cells); - print(this.settings.toJson()); - print(this.toJson()); + GameBoard.printGrid(board.cells); + print(settings.toJson()); + print(toJson()); } } diff --git a/lib/models/game/game_board.dart b/lib/models/game/game_board.dart index 6565494..41257e0 100644 --- a/lib/models/game/game_board.dart +++ b/lib/models/game/game_board.dart @@ -19,7 +19,7 @@ class GameBoard { final int boardSizeVertical = gameSettings.boardSize; final int maxValue = gameSettings.colorsCount; - final rand = new Random(); + final rand = Random(); List<List<GameCell>> grid = []; for (var rowIndex = 0; rowIndex < boardSizeVertical; rowIndex++) { @@ -49,13 +49,14 @@ class GameBoard { print(''); } + @override String toString() { - return 'Board(' + this.toJson().toString() + ')'; + return 'Board(${toJson()})'; } Map<String, dynamic>? toJson() { return <String, dynamic>{ - 'cells': this.cells.toString(), + 'cells': cells.toString(), }; } } diff --git a/lib/models/game/game_cell.dart b/lib/models/game/game_cell.dart index 25667cc..4cba17b 100644 --- a/lib/models/game/game_cell.dart +++ b/lib/models/game/game_cell.dart @@ -5,13 +5,14 @@ class GameCell { this.value, ); + @override String toString() { - return 'Cell(' + this.toJson().toString() + ')'; + return 'Cell(${toJson()})'; } Map<String, dynamic>? toJson() { return <String, dynamic>{ - 'value': this.value, + 'value': value, }; } } diff --git a/lib/models/game/game_settings.dart b/lib/models/game/game_settings.dart index 4610c78..2b108da 100644 --- a/lib/models/game/game_settings.dart +++ b/lib/models/game/game_settings.dart @@ -32,14 +32,15 @@ class GameSettings { ); } + @override String toString() { - return 'GameSettings(' + this.toJson().toString() + ')'; + return 'GameSettings(${toJson()})'; } Map<String, dynamic>? toJson() { return <String, dynamic>{ - 'boardSize': this.boardSize, - 'colorsCount': this.colorsCount, + 'boardSize': boardSize, + 'colorsCount': colorsCount, }; } } diff --git a/lib/models/interface_type.dart b/lib/models/interface_type.dart index 05dc342..2976321 100644 --- a/lib/models/interface_type.dart +++ b/lib/models/interface_type.dart @@ -8,7 +8,7 @@ enum InterfaceType { class InterfaceTypes { static List<Widget> selectWidgets = <Widget>[ - Text('interface_type_basic').tr(), - Text('interface_type_expert').tr(), + const Text('interface_type_basic').tr(), + const Text('interface_type_expert').tr(), ]; } diff --git a/lib/network/api.dart b/lib/network/api.dart index 23a6207..aa75936 100644 --- a/lib/network/api.dart +++ b/lib/network/api.dart @@ -10,10 +10,10 @@ class ApiService { final String baseUrl = 'https://tools.harrault.fr/tools/api'; Future<Response?> getData() async { - String url = baseUrl + '/get.php'; + String url = '$baseUrl/get.php'; try { - print('fetching api data... ' + url); - final Response? response = await _dio.get(url); + print('fetching api data... $url'); + final Response response = await _dio.get(url); print('ok got api response.'); print(response); return response; diff --git a/lib/repository/api.dart b/lib/repository/api.dart index ce3a0ef..d6548b0 100644 --- a/lib/repository/api.dart +++ b/lib/repository/api.dart @@ -8,7 +8,7 @@ class ApiRepository { Future<ApiData> getApiData() async { print('(getApiData) delayed API call...'); - final response = await Future.delayed(Duration(milliseconds: 1000)) + final response = await Future.delayed(const Duration(milliseconds: 1000)) .then((value) => apiService.getData()); if (response != null) { print('(getApiData) got api response'); diff --git a/lib/ui/painters/cell_painter.dart b/lib/ui/painters/cell_painter.dart index a2cf510..851f70e 100644 --- a/lib/ui/painters/cell_painter.dart +++ b/lib/ui/painters/cell_painter.dart @@ -30,7 +30,7 @@ class CellPainter extends CustomPainter { const borderWidth = 0.05; - final Rect baseSquare = Rect.fromPoints(Offset(0, 0), Offset(size.width, size.height)); + final Rect baseSquare = Rect.fromPoints(const Offset(0, 0), Offset(size.width, size.height)); final paintBaseSquare = Paint() ..style = PaintingStyle.fill diff --git a/lib/ui/painters/graph_painter.dart b/lib/ui/painters/graph_painter.dart index ac9358c..38a30c6 100644 --- a/lib/ui/painters/graph_painter.dart +++ b/lib/ui/painters/graph_painter.dart @@ -35,14 +35,14 @@ class GraphPainter extends CustomPainter { paintBackground.color = Colors.black; paintBackground.style = PaintingStyle.fill; - final Rect rectBackground = Rect.fromPoints(Offset(0, 0), Offset(size.width, size.height)); + final Rect rectBackground = Rect.fromPoints(const Offset(0, 0), Offset(size.width, size.height)); canvas.drawRect(rectBackground, paintBackground); // Draw some lines Paint paintLine = Paint(); paintLine.style = PaintingStyle.fill; - for (int i = 0; i < this.linesCount; i++) { + for (int i = 0; i < linesCount; i++) { paintLine.color = getRandomColor(); paintLine.strokeWidth = Random().nextDouble() * 4 + 2; diff --git a/lib/ui/screens/about_page.dart b/lib/ui/screens/about_page.dart index a93505a..f183a4a 100644 --- a/lib/ui/screens/about_page.dart +++ b/lib/ui/screens/about_page.dart @@ -14,15 +14,15 @@ class AboutPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: <Widget>[ - SizedBox(height: 8), - AppHeader(text: 'about_title'), - Text('about_content').tr(), + const SizedBox(height: 8), + const AppHeader(text: 'about_title'), + const Text('about_content').tr(), FutureBuilder<PackageInfo>( future: PackageInfo.fromPlatform(), builder: (context, snapshot) { switch (snapshot.connectionState) { case ConnectionState.done: - return Text('about_version').tr( + return const Text('about_version').tr( namedArgs: { 'version': snapshot.data!.version, }, diff --git a/lib/ui/screens/api_page.dart b/lib/ui/screens/api_page.dart index 9b02532..22dc963 100644 --- a/lib/ui/screens/api_page.dart +++ b/lib/ui/screens/api_page.dart @@ -17,9 +17,9 @@ class ApiPage extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 4), physics: const BouncingScrollPhysics(), children: <Widget>[ - SizedBox(height: 8), - AppHeader(text: 'api_page_title'), - SizedBox(height: 20), + const SizedBox(height: 8), + const AppHeader(text: 'api_page_title'), + const SizedBox(height: 20), BlocBuilder<ApiDataCubit, ApiDataState>( builder: (BuildContext context, ApiDataState apiDataState) { return ApiDataWidget( diff --git a/lib/ui/screens/camera_page.dart b/lib/ui/screens/camera_page.dart index 98c2282..828c6e2 100644 --- a/lib/ui/screens/camera_page.dart +++ b/lib/ui/screens/camera_page.dart @@ -13,12 +13,12 @@ class CameraPage extends StatelessWidget { Widget build(BuildContext context) { return Material( color: Theme.of(context).colorScheme.background, - child: Column( + child: const Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ - const SizedBox(height: 8), - const TakePictureWidget(), + SizedBox(height: 8), + TakePictureWidget(), ], ), ); diff --git a/lib/ui/screens/demo_page.dart b/lib/ui/screens/demo_page.dart index 8d10142..2c7269e 100644 --- a/lib/ui/screens/demo_page.dart +++ b/lib/ui/screens/demo_page.dart @@ -18,17 +18,17 @@ class DemoPage extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 4), physics: const BouncingScrollPhysics(), children: <Widget>[ - SizedBox(height: 8), - AppHeader(text: 'TOP'), - SizedBox(height: 20), + const SizedBox(height: 8), + const AppHeader(text: 'TOP'), + const SizedBox(height: 20), persistedCounterBlock(BlocProvider.of<DataCubit>(context)), - SizedBox(height: 20), + const SizedBox(height: 20), testBlocConsumer(), testBlocBuilder(), - SizedBox(height: 20), + const SizedBox(height: 20), fakeApiCall(), - SizedBox(height: 20), - AppHeader(text: 'BOTTOM'), + const SizedBox(height: 20), + const AppHeader(text: 'BOTTOM'), ], ), ); @@ -40,13 +40,13 @@ class DemoPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ IconButton( - icon: Icon(UniconsSolid.arrow_circle_down), + icon: const Icon(UniconsSolid.arrow_circle_down), color: appTheme.primaryColor, onPressed: () => dataCubit.updateCounter(-1), ), testBlocConsumer(), IconButton( - icon: Icon(UniconsSolid.arrow_circle_up), + icon: const Icon(UniconsSolid.arrow_circle_up), color: appTheme.primaryColor, onPressed: () => dataCubit.updateCounter(1), ), @@ -61,9 +61,9 @@ class DemoPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Text('apiUrl: ' + settingsSate.apiUrl.toString()), - Text('securityToken: ' + (settingsSate.securityToken.toString())), - Text('interfaceType: ' + settingsSate.interfaceType.toString()), + Text('apiUrl: ${settingsSate.apiUrl}'), + Text('securityToken: ${settingsSate.securityToken}'), + Text('interfaceType: ${settingsSate.interfaceType}'), ], ); }, @@ -77,7 +77,7 @@ class DemoPage extends StatelessWidget { }, builder: (context, dataState) { // return widget here based on state - return Text('BlocConsumer / ' + dataState.toString()); + return Text('BlocConsumer / $dataState'); }, ); } @@ -94,7 +94,7 @@ class DemoPage extends StatelessWidget { return BlocBuilder<DataCubit, DataState>( builder: (context, dataState) { // return widget here based on state - return Text('BlocBuilder / ' + dataState.toString()); + return Text('BlocBuilder / $dataState'); }, ); } diff --git a/lib/ui/screens/game_page.dart b/lib/ui/screens/game_page.dart index 7822504..1f845c8 100644 --- a/lib/ui/screens/game_page.dart +++ b/lib/ui/screens/game_page.dart @@ -24,7 +24,7 @@ class _GamePageState extends State<GamePage> { onPressed: () { gameCubit.updateGameState(Game.createNew()); }, - icon: Icon(UniconsSolid.star), + icon: const Icon(UniconsSolid.star), color: Colors.white, ) ]; @@ -38,7 +38,7 @@ class _GamePageState extends State<GamePage> { gameCubit.updateGameState(currentGame); setState(() {}); }, - icon: Icon(UniconsLine.exit), + icon: const Icon(UniconsLine.exit), color: Colors.white, )); } @@ -65,9 +65,9 @@ class _GamePageState extends State<GamePage> { gameState.game?.isRunning == true ? GameBoardWidget( game: gameState.game!, - widgetSize: Size(boardWidgetWidth, boardWidgetHeight), + widgetSize: const Size(boardWidgetWidth, boardWidgetHeight), ) - : GameSettingsWidget(), + : const GameSettingsWidget(), buildGameActionsBloc(context), ], ); diff --git a/lib/ui/screens/graph_page.dart b/lib/ui/screens/graph_page.dart index 892151e..6a4c247 100644 --- a/lib/ui/screens/graph_page.dart +++ b/lib/ui/screens/graph_page.dart @@ -17,50 +17,48 @@ class _GraphPageState extends State<GraphPage> { double boardWidth = MediaQuery.of(context).size.width; return SizedBox.expand( - child: Container( - child: FittedBox( - fit: BoxFit.contain, - alignment: Alignment.center, - child: SizedBox( - height: (MediaQuery.of(context).size.height), - width: (MediaQuery.of(context).size.width), - child: SafeArea( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Center( - child: GestureDetector( - onTapUp: (details) { - double xTap = details.localPosition.dx; - double yTap = details.localPosition.dy; - print('[' + xTap.toString() + ',' + yTap.toString() + ']'); - }, - child: Container( - margin: EdgeInsets.all(4), - padding: EdgeInsets.all(4), - child: CustomPaint( - size: Size(boardWidth, boardWidth), - willChange: false, - painter: GraphPainter(linesCount: _currentSliderValue.toInt()), - ), + child: FittedBox( + fit: BoxFit.contain, + alignment: Alignment.center, + child: SizedBox( + height: (MediaQuery.of(context).size.height), + width: (MediaQuery.of(context).size.width), + child: SafeArea( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Center( + child: GestureDetector( + onTapUp: (details) { + double xTap = details.localPosition.dx; + double yTap = details.localPosition.dy; + print('[$xTap,$yTap]'); + }, + child: Container( + margin: const EdgeInsets.all(4), + padding: const EdgeInsets.all(4), + child: CustomPaint( + size: Size(boardWidth, boardWidth), + willChange: false, + painter: GraphPainter(linesCount: _currentSliderValue.toInt()), ), ), ), - Slider( - value: _currentSliderValue, - min: 10, - max: 50, - divisions: 5, - label: _currentSliderValue.round().toString(), - onChanged: (double value) { - setState(() { - _currentSliderValue = value; - }); - }, - ), - ], - ), + ), + Slider( + value: _currentSliderValue, + min: 10, + max: 50, + divisions: 5, + label: _currentSliderValue.round().toString(), + onChanged: (double value) { + setState(() { + _currentSliderValue = value; + }); + }, + ), + ], ), ), ), diff --git a/lib/ui/screens/settings_page.dart b/lib/ui/screens/settings_page.dart index 3e0195d..195d012 100644 --- a/lib/ui/screens/settings_page.dart +++ b/lib/ui/screens/settings_page.dart @@ -8,7 +8,7 @@ class SettingsPage extends StatelessWidget { @override Widget build(BuildContext context) { - return Column( + return const Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, diff --git a/lib/ui/skeleton.dart b/lib/ui/skeleton.dart index e863619..513b39d 100644 --- a/lib/ui/skeleton.dart +++ b/lib/ui/skeleton.dart @@ -19,7 +19,7 @@ class _SkeletonScreenState extends State<SkeletonScreen> { Widget build(BuildContext context) { return Scaffold( extendBodyBehindAppBar: false, - appBar: StandardAppBar(), + appBar: const StandardAppBar(), body: Swiper( itemCount: Menu.itemsCount, itemBuilder: (BuildContext context, int index) { diff --git a/lib/ui/widgets/api_data.dart b/lib/ui/widgets/api_data.dart index 3690792..669de42 100644 --- a/lib/ui/widgets/api_data.dart +++ b/lib/ui/widgets/api_data.dart @@ -19,19 +19,19 @@ class ApiDataWidget extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('status: ' + status.toString()), - Text('number: ' + (this.data?.number.toString() ?? '')), - Text('md5: ' + (this.data?.md5.toString() ?? '')), - Text('updatedAt: ' + (this.data?.updatedAt.toString() ?? '')), + Text('status: $status'), + Text('number: ${data?.number.toString() ?? ''}'), + Text('md5: ${data?.md5.toString() ?? ''}'), + Text('updatedAt: ${data?.updatedAt.toString() ?? ''}'), status == ApiStatus.loading - ? Container( + ? const SizedBox( width: 12, height: 12, - child: const CircularProgressIndicator(), + child: CircularProgressIndicator(), ) : const SizedBox.shrink(), status == ApiStatus.failed - ? ShowErrorWidget(message: 'state.failure.message') + ? const ShowErrorWidget(message: 'state.failure.message') : const SizedBox.shrink(), ], ); diff --git a/lib/ui/widgets/app_bar.dart b/lib/ui/widgets/app_bar.dart index 648a641..0d60da6 100644 --- a/lib/ui/widgets/app_bar.dart +++ b/lib/ui/widgets/app_bar.dart @@ -8,8 +8,8 @@ class StandardAppBar extends StatelessWidget implements PreferredSizeWidget { @override Widget build(BuildContext context) { return AppBar( - title: AppHeader(text: 'app_name'), - actions: [ + title: const AppHeader(text: 'app_name'), + actions: const [ // ], ); diff --git a/lib/ui/widgets/debug_bloc.dart b/lib/ui/widgets/debug_bloc.dart index 502bacc..cbc6dfe 100644 --- a/lib/ui/widgets/debug_bloc.dart +++ b/lib/ui/widgets/debug_bloc.dart @@ -16,11 +16,11 @@ class DebugBloc extends StatelessWidget { ), ), child: Padding( - padding: EdgeInsets.all(5), + padding: const EdgeInsets.all(5), child: Text( content, textAlign: TextAlign.start, - style: TextStyle(fontSize: 13), + style: const TextStyle(fontSize: 13), ), ), ); diff --git a/lib/ui/widgets/error.dart b/lib/ui/widgets/error.dart index e65f242..9aacdcb 100644 --- a/lib/ui/widgets/error.dart +++ b/lib/ui/widgets/error.dart @@ -9,9 +9,9 @@ class ShowErrorWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Text( - '⚠️ ' + tr(message), + '⚠️ ${tr(message)}', textAlign: TextAlign.start, - style: TextStyle(color: Colors.red), + style: const TextStyle(color: Colors.red), ); } } diff --git a/lib/ui/widgets/game/game_board.dart b/lib/ui/widgets/game/game_board.dart index 6f11e5b..f354e21 100644 --- a/lib/ui/widgets/game/game_board.dart +++ b/lib/ui/widgets/game/game_board.dart @@ -49,7 +49,7 @@ class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMi // "move down" cells final controller = AnimationController( vsync: this, - duration: Duration(milliseconds: 750), + duration: const Duration(milliseconds: 750), )..addListener(() { if (mounted) { setState(() {}); @@ -99,7 +99,7 @@ class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMi final cellWidth = widgetWidth / columnsCount; final cellHeight = widgetHeight / rowsCount; - if (animations.length == 0) { + if (animations.isEmpty) { resetAnimations(widget.game.settings); } @@ -110,7 +110,7 @@ class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMi final int? value = widget.game.getCellValue(x, y); if (value != null) { - final Animation<double>? translation = this.animations[y][x]; + final Animation<double>? translation = animations[y][x]; final Widget cellContent = CustomPaint( size: Size(cellWidth, cellHeight), @@ -121,7 +121,7 @@ class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMi final Widget cellWidget = Positioned( left: (x * cellWidth).toDouble(), top: ((y + (translation?.value ?? 0)) * cellHeight).toDouble(), - child: Container( + child: SizedBox( width: cellWidth, height: cellHeight, child: cellContent, @@ -154,13 +154,13 @@ class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMi child: buildBoard(), onTapUp: (details) { bool canRemoveCell = true; - animations.forEach((row) { - row.forEach((cell) { + for (var row in animations) { + for (var cell in row) { if (cell != null) { canRemoveCell = false; } - }); - }); + } + } if (canRemoveCell) { double xTap = details.localPosition.dx; @@ -168,7 +168,7 @@ class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMi int x = (xTap / widgetWidth * columnsCount).toInt(); int y = (yTap / widgetHeight * rowsCount).toInt(); - print('[' + x.toString() + ',' + y.toString() + ']'); + print('[$x,$y]'); removeCell(context, x, y); } else { diff --git a/lib/ui/widgets/game/game_score.dart b/lib/ui/widgets/game/game_score.dart index e52193c..cea8f9a 100644 --- a/lib/ui/widgets/game/game_score.dart +++ b/lib/ui/widgets/game/game_score.dart @@ -14,19 +14,19 @@ class GameScoreWidget extends StatelessWidget { Widget build(BuildContext context) { return Container( width: MediaQuery.of(context).size.width, - padding: EdgeInsets.all(5), + padding: const EdgeInsets.all(5), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text('Settings:'), - Text(' board size: ' + this.game.settings.boardSize.toString()), - Text(' colors count: ' + this.game.settings.colorsCount.toString()), - Text('Game:'), - Text(' isRunning: ' + this.game.isRunning.toString()), - Text(' isFinished: ' + this.game.isFinished.toString()), - Text(' movesCount: ' + this.game.movesCount.toString()), - Text(' score: ' + this.game.score.toString()), + const Text('Settings:'), + Text(' board size: ${game.settings.boardSize}'), + Text(' colors count: ${game.settings.colorsCount}'), + const Text('Game:'), + Text(' isRunning: ${game.isRunning}'), + Text(' isFinished: ${game.isFinished}'), + Text(' movesCount: ${game.movesCount}'), + Text(' score: ${game.score}'), ], ), ); diff --git a/lib/ui/widgets/game/game_settings.dart b/lib/ui/widgets/game/game_settings.dart index 3170c69..783e770 100644 --- a/lib/ui/widgets/game/game_settings.dart +++ b/lib/ui/widgets/game/game_settings.dart @@ -7,6 +7,6 @@ class GameSettingsWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return Text('(fake settings block)'); + return const Text('(fake settings block)'); } } diff --git a/lib/ui/widgets/header_app.dart b/lib/ui/widgets/header_app.dart index b19ad44..39bfa86 100644 --- a/lib/ui/widgets/header_app.dart +++ b/lib/ui/widgets/header_app.dart @@ -23,11 +23,11 @@ class AppHeader extends StatelessWidget { textAlign: TextAlign.start, style: Theme.of(context).textTheme.headlineMedium!.apply(fontWeightDelta: 2), ), - SizedBox(width: 2), + const SizedBox(width: 2), expertInterfaceIndicator(), - SizedBox(width: 2), + const SizedBox(width: 2), dataCounterIndicator(), - SizedBox(width: 2), + const SizedBox(width: 2), apiLoadingIndicator(), ], ); @@ -46,7 +46,7 @@ class AppHeader extends StatelessWidget { Widget dataCounterIndicator() { return BlocBuilder<DataCubit, DataState>( builder: (context, dataState) { - return Text('(' + dataState.counter.toString() + ')'); + return Text('(${dataState.counter})'); }, ); } @@ -55,10 +55,10 @@ class AppHeader extends StatelessWidget { return BlocBuilder<ApiDataCubit, ApiDataState>( builder: (context, apiDataState) { return (apiDataState is ApiDataFetchLoading) - ? Text('⏳') + ? const Text('⏳') : (apiDataState is ApiDataFetchLoaded) - ? Text('✅') - : Text('⚠️'); + ? const Text('✅') + : const Text('⚠️'); }, ); } diff --git a/lib/ui/widgets/settings_form.dart b/lib/ui/widgets/settings_form.dart index ac40063..5cd6348 100644 --- a/lib/ui/widgets/settings_form.dart +++ b/lib/ui/widgets/settings_form.dart @@ -54,23 +54,23 @@ class _SettingsFormState extends State<SettingsForm> { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: <Widget>[ - Text('settings_label_api_url').tr(), + const Text('settings_label_api_url').tr(), TextFormField( controller: apiUrlController, - decoration: InputDecoration( + decoration: const InputDecoration( border: UnderlineInputBorder(), ), ), - SizedBox(height: 16), - Text('settings_label_security_token').tr(), + const SizedBox(height: 16), + const Text('settings_label_security_token').tr(), TextFormField( controller: securityTokenController, - decoration: InputDecoration( + decoration: const InputDecoration( border: UnderlineInputBorder(), ), ), - SizedBox(height: 16), - Text('settings_label_interface_type').tr(), + const SizedBox(height: 16), + const Text('settings_label_interface_type').tr(), ToggleButtons( direction: Axis.horizontal, onPressed: (int index) { @@ -90,15 +90,15 @@ class _SettingsFormState extends State<SettingsForm> { isSelected: _selectedInterfaceType, children: interfaceTypesWidgets, ), - SizedBox(height: 20), + const SizedBox(height: 20), ElevatedButton( child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Icon(UniconsLine.save), - SizedBox(width: 8), - Text('settings_button_save').tr(), + const Icon(UniconsLine.save), + const SizedBox(width: 8), + const Text('settings_button_save').tr(), ], ), onPressed: () => saveSettings(), diff --git a/lib/ui/widgets/take_picture_widget.dart b/lib/ui/widgets/take_picture_widget.dart index 7a73090..efece10 100644 --- a/lib/ui/widgets/take_picture_widget.dart +++ b/lib/ui/widgets/take_picture_widget.dart @@ -28,24 +28,20 @@ class TakePictureWidgetState extends State<TakePictureWidget> { } loadCamera() async { - final List<CameraDescription>? cameras = await availableCameras(); - if (cameras != null) { - controller = CameraController( - cameras.first, - ResolutionPreset.max, - enableAudio: false, - ); + final List<CameraDescription> cameras = await availableCameras(); + controller = CameraController( + cameras.first, + ResolutionPreset.max, + enableAudio: false, + ); - controller!.initialize().then((_) { - if (!mounted) { - return; - } - setState(() {}); - }); - } else { - print("No camera found."); + controller!.initialize().then((_) { + if (!mounted) { + return; + } + setState(() {}); + }); } - } @override void dispose() { @@ -60,50 +56,50 @@ class TakePictureWidgetState extends State<TakePictureWidget> { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Container( + SizedBox( height: 400, child: controller == null - ? Center(child: Text("Loading camera...")) + ? const Center(child: Text("Loading camera...")) : !controller!.value.isInitialized - ? Center(child: CircularProgressIndicator()) + ? const Center(child: CircularProgressIndicator()) : CameraPreview(controller!), ), ElevatedButton.icon( - label: Text("Take picture"), - icon: Icon(UniconsLine.camera), + label: const Text("Take picture"), + icon: const Icon(UniconsLine.camera), onPressed: () async { try { if ((controller != null) && (controller!.value.isInitialized)) { final XFile image = await controller!.takePicture(); - print('image.path: ' + image.path); - debug.add('image.path: ' + image.path); + print('image.path: ${image.path}'); + debug.add('image.path: ${image.path}'); File savedFile = await storage!.writeCounter(File(image.path)); - debug.add('image.path: ' + image.path); + debug.add('image.path: ${image.path}'); String imagePath = savedFile.path; - print('imagePath: ' + imagePath); - debug.add('imagePath: ' + imagePath); + print('imagePath: $imagePath'); + debug.add('imagePath: $imagePath'); previousImages.add(imagePath); setState(() {}); } } catch (e) { - debug.add('error: ' + e.toString()); + debug.add('error: $e'); setState(() {}); print(e); } }, ), - Text('debug: '), + const Text('debug: '), Column( children: debug.map((String line) { return Text(line); }).toList(), ), - previousImages.length == 0 - ? Text('no previous images') + previousImages.isEmpty + ? const Text('no previous images') : Column( children: previousImages.map((String imagePath) { return Row( diff --git a/lib/utils/picture_storage.dart b/lib/utils/picture_storage.dart index 72e2278..ebf663b 100644 --- a/lib/utils/picture_storage.dart +++ b/lib/utils/picture_storage.dart @@ -13,14 +13,14 @@ class PictureStorage { Future<String> _localFilePath(String name) async { final path = await _localPath; - return path + '/' + name; + return '$path/$name'; } Future<File> moveFile(File sourceFile, String newPath) async { try { return await sourceFile.rename(newPath); } on FileSystemException catch (e) { - print('Found exception while moving file: ' + e.toString()); + print('Found exception while moving file: $e'); final newFile = await sourceFile.copy(newPath); await sourceFile.delete(); return newFile; diff --git a/pubspec.lock b/pubspec.lock index b3dd33c..dea0f19 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -166,6 +166,14 @@ packages: url: "https://pub.dev" source: hosted version: "8.1.3" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7 + url: "https://pub.dev" + source: hosted + version: "3.0.1" flutter_localizations: dependency: transitive description: flutter @@ -193,7 +201,7 @@ packages: source: sdk version: "0.0.0" hive: - dependency: transitive + dependency: "direct main" description: name: hive sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941" @@ -232,22 +240,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.18.1" + 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: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" nested: dependency: transitive description: @@ -273,13 +289,13 @@ packages: source: hosted version: "2.0.1" path: - dependency: transitive + dependency: "direct main" description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_provider: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 96d1982..401d954 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: A random application, for testing purpose only. publish_to: 'none' -version: 1.0.45+46 +version: 1.0.46+47 environment: sdk: '^3.0.0' @@ -22,6 +22,8 @@ dependencies: package_info_plus: ^5.0.1 flutter_swipe: ^1.0.1 dio: ^5.3.3 + hive: ^2.2.3 + path: ^1.9.0 flutter: uses-material-design: false @@ -40,3 +42,5 @@ flutter: weight: 400 - asset: assets/fonts/Nunito-Light.ttf weight: 300 +dev_dependencies: + flutter_lints: ^3.0.1 -- GitLab