From 1996ed1fa7ed76edfa188d3be34cb23a4283c7bd Mon Sep 17 00:00:00 2001
From: anfeichtinger <anfeichtingers@gmail.com>
Date: Sat, 19 Jun 2021 17:37:44 +0200
Subject: [PATCH] Use flutter_lints package and update code according to
 stricter rules

---
 README.md                                   |  4 +--
 analysis_options.yaml                       | 12 ++++++-
 assets/translations/de.json                 |  2 +-
 assets/translations/en.json                 |  4 +--
 lib/cubit/theme_cubit.dart                  |  2 +-
 lib/main.dart                               | 13 +++++---
 lib/ui/screens/first_screen.dart            | 16 ++++-----
 lib/ui/screens/second_screen.dart           | 36 ++++++++++-----------
 lib/ui/screens/skeleton_screen.dart         |  8 +++--
 lib/ui/widgets/app_bar_gone.dart            |  2 +-
 lib/ui/widgets/bottom_nav_bar.dart          |  5 ++-
 lib/ui/widgets/first_screen/info_card.dart  |  6 ++--
 lib/ui/widgets/header.dart                  |  4 +--
 lib/ui/widgets/second_screen/grid_item.dart |  2 +-
 lib/ui/widgets/second_screen/link_card.dart |  2 +-
 pubspec.lock                                | 11 +++++--
 pubspec.yaml                                |  2 +-
 test/widget_test.dart                       |  5 ---
 18 files changed, 79 insertions(+), 57 deletions(-)

diff --git a/README.md b/README.md
index 2dd6c84d..247c3165 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 # Flutter Production Boilerplate
-## A flutter project containing bloc, lints, hive, easy_translations and more!
+## A flutter project containing bloc, flutter_lints, hive, easy_translations and more!
 
 This repository is the starting point for my personal projects. If you have any suggestions or improvements feel free to let me know. The project strives to implement best practices recommended by Google and other developers. These best practices include but are not limited to: 
 
@@ -40,7 +40,7 @@ This repository makes use of the following pub packages:
 | [Flutter Bloc](https://pub.dev/packages/flutter_bloc) | ^7.0.1 | State management*
 | [Hydrated Bloc](https://pub.dev/packages/hydrated_bloc) | ^7.0.1 | Persists Bloc state with Hive
 | [Equatable](https://pub.dev/packages/equatable) | ^2.0.2 | Easily compare custom classes, used for Bloc states*
-| [Lints](https://pub.dev/packages/lints) | ^1.0.1 | Stricter linting rules
+| [Flutter Lints](https://pub.dev/packages/flutter_lints) | ^1.0.3 | Stricter linting rules
 | [Path Provider](https://pub.dev/packages/path_provider) | ^2.0.2 | Get the save path for Hive
 | [Flutter Displaymode](https://pub.dev/packages/flutter_displaymode) | ^0.3.2 | Support high refresh rate displays
 | [Easy Localization](https://pub.dev/packages/easy_localization) | ^3.0.0 | Makes localization easy
diff --git a/analysis_options.yaml b/analysis_options.yaml
index ea2c9e94..5f347c7c 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1 +1,11 @@
-include: package:lints/recommended.yaml
\ No newline at end of file
+include: package:flutter_lints/flutter.yaml
+
+analyzer:
+  exclude: [build/**]
+  strong-mode:
+    implicit-casts: false
+    implicit-dynamic: false
+
+rules:
+ avoid_print: false
+ prefer_single_quotes: true
\ No newline at end of file
diff --git a/assets/translations/de.json b/assets/translations/de.json
index 570bc3da..6aafb744 100644
--- a/assets/translations/de.json
+++ b/assets/translations/de.json
@@ -8,7 +8,7 @@
   "localization_content": "Vereinfachte Übersetzungen mit dem Paket Easy Translations.",
 
   "linting_title": "Linting",
-  "linting_content": "Strengere Linting-Regeln mit Pedantic, empfohlen von Google.",
+  "linting_content": "Strengere Linting-Regeln mit Flutter Lints, empfohlen von Google.",
 
   "storage_title": "Speicher",
   "storage_content": "Extrem schnelle, in reinem Dart geschriebene Datenbank mit Hive.",
diff --git a/assets/translations/en.json b/assets/translations/en.json
index de6a9f9b..3a9270f6 100644
--- a/assets/translations/en.json
+++ b/assets/translations/en.json
@@ -8,7 +8,7 @@
   "localization_content": "Simplified translations with the Easy Translations package.",
 
   "linting_title": "Linting",
-  "linting_content": "Stricter linting rules with lints recommended by the Dart team.",
+  "linting_content": "Stricter linting rules with flutter lints recommended by the Dart team.",
 
   "storage_title": "Storage",
   "storage_content": "Blazing fast key-value database written in pure Dart with Hive.",
@@ -37,7 +37,7 @@
   "bloc": "Bloc",
   "hydrated_bloc": "Hydrated bloc",
   "equatable": "Equatable",
-  "lints": "Lints",
+  "lints": "Flutter Lints",
   "path_provider": "Path provider",
   "flutter_displaymode": "Displaymode",
   "easy_localization": "Easy localization",
diff --git a/lib/cubit/theme_cubit.dart b/lib/cubit/theme_cubit.dart
index 1d0e7d0e..a131f7ff 100644
--- a/lib/cubit/theme_cubit.dart
+++ b/lib/cubit/theme_cubit.dart
@@ -21,7 +21,7 @@ class ThemeCubit extends HydratedCubit<ThemeState> {
   }
 
   @override
-  Map<String, dynamic>? toJson(ThemeState state) {
+  Map<String, bool>? toJson(ThemeState state) {
     return {'isDark': state.themeData.brightness == Brightness.dark};
   }
 }
diff --git a/lib/main.dart b/lib/main.dart
index 8382aac6..52faed4c 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,4 +1,5 @@
 import 'dart:io';
+
 import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
@@ -27,18 +28,20 @@ void main() async {
   runApp(
     EasyLocalization(
       path: 'assets/translations',
-      supportedLocales: [
-        const Locale('en'),
-        const Locale('de'),
+      supportedLocales: const [
+        Locale('en'),
+        Locale('de'),
       ],
       fallbackLocale: const Locale('en'),
       useFallbackTranslations: true,
-      child: MyApp(),
+      child: const MyApp(),
     ),
   );
 }
 
 class MyApp extends StatelessWidget {
+  const MyApp({Key? key}) : super(key: key);
+
   @override
   Widget build(BuildContext context) {
     return BlocProvider<ThemeCubit>(
@@ -49,7 +52,7 @@ class MyApp extends StatelessWidget {
             /// Localization is not available for the title.
             title: 'Flutter Production Boilerplate',
             theme: state.themeData,
-            home: SkeletonScreen(),
+            home: const SkeletonScreen(),
             debugShowCheckedModeBanner: false,
             localizationsDelegates: context.localizationDelegates,
             supportedLocales: context.supportedLocales,
diff --git a/lib/ui/screens/first_screen.dart b/lib/ui/screens/first_screen.dart
index 552004fc..a917732c 100644
--- a/lib/ui/screens/first_screen.dart
+++ b/lib/ui/screens/first_screen.dart
@@ -8,7 +8,7 @@ import 'package:flutter_production_boilerplate/ui/widgets/first_screen/info_card
 import 'package:ionicons/ionicons.dart';
 
 class FirstScreen extends StatelessWidget {
-  const FirstScreen();
+  const FirstScreen({Key? key}) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
@@ -102,36 +102,36 @@ class FirstScreen extends StatelessWidget {
               crossAxisSpacing: 8,
               mainAxisSpacing: 8,
               childAspectRatio: 4 / 5,
-              children: [
+              children: const [
                 /// Example: it is good practice to put widgets in separate files.
                 /// This way the screen files won't become too large and
                 /// the code becomes more clear.
-                const InfoCard(
+                InfoCard(
                     title: 'localization_title',
                     content: 'localization_content',
                     icon: Ionicons.text_outline,
                     isPrimaryColor: true),
-                const InfoCard(
+                InfoCard(
                     title: 'linting_title',
                     content: 'linting_content',
                     icon: Ionicons.options_outline,
                     isPrimaryColor: false),
-                const InfoCard(
+                InfoCard(
                     title: 'storage_title',
                     content: 'storage_content',
                     icon: Ionicons.folder_outline,
                     isPrimaryColor: false),
-                const InfoCard(
+                InfoCard(
                     title: 'dark_mode_title',
                     content: 'dark_mode_content',
                     icon: Ionicons.moon_outline,
                     isPrimaryColor: true),
-                const InfoCard(
+                InfoCard(
                     title: 'state_title',
                     content: 'state_content',
                     icon: Ionicons.notifications_outline,
                     isPrimaryColor: true),
-                const InfoCard(
+                InfoCard(
                     title: 'display_title',
                     content: 'display_content',
                     icon: Ionicons.speedometer_outline,
diff --git a/lib/ui/screens/second_screen.dart b/lib/ui/screens/second_screen.dart
index d1109e09..b03cbfef 100644
--- a/lib/ui/screens/second_screen.dart
+++ b/lib/ui/screens/second_screen.dart
@@ -6,7 +6,7 @@ import 'package:flutter_production_boilerplate/ui/widgets/second_screen/text_div
 import 'package:ionicons/ionicons.dart';
 
 class SecondScreen extends StatelessWidget {
-  const SecondScreen();
+  const SecondScreen({Key? key}) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
@@ -35,18 +35,18 @@ class SecondScreen extends StatelessWidget {
               crossAxisSpacing: 8,
               mainAxisSpacing: 8,
               shrinkWrap: true,
-              children: [
-                const GridItem(
+              children: const [
+                GridItem(
                   title: 'instagram_card_title',
                   icon: Ionicons.logo_instagram,
                   url: 'https://www.instagram.com/anfeichtinger',
                 ),
-                const GridItem(
+                GridItem(
                   title: 'twitter_card_title',
                   icon: Ionicons.logo_twitter,
                   url: 'https://twitter.com/_pharrax',
                 ),
-                const GridItem(
+                GridItem(
                   title: 'donate_card_title',
                   icon: Ionicons.heart_outline,
                   url:
@@ -62,58 +62,58 @@ class SecondScreen extends StatelessWidget {
               crossAxisSpacing: 8,
               mainAxisSpacing: 8,
               shrinkWrap: true,
-              children: [
-                const GridItem(
+              children: const [
+                GridItem(
                   title: 'flutter_bloc',
                   icon: Ionicons.apps_outline,
                   url: 'https://pub.dev/packages/flutter_bloc',
                 ),
-                const GridItem(
+                GridItem(
                   title: 'bloc',
                   icon: Ionicons.grid_outline,
                   url: 'https://pub.dev/packages/bloc',
                 ),
-                const GridItem(
+                GridItem(
                   title: 'hydrated_bloc',
                   icon: Ionicons.folder_open_outline,
                   url: 'https://pub.dev/packages/hydrated_bloc',
                 ),
-                const GridItem(
+                GridItem(
                   title: 'equatable',
                   icon: Ionicons.git_compare_outline,
                   url: 'https://pub.dev/packages/equatable',
                 ),
-                const GridItem(
+                GridItem(
                   title: 'lints',
                   icon: Ionicons.options_outline,
-                  url: 'https://pub.dev/packages/lints',
+                  url: 'https://pub.dev/packages/flutter_lints',
                 ),
-                const GridItem(
+                GridItem(
                   title: 'path_provider',
                   icon: Ionicons.extension_puzzle_outline,
                   url: 'https://pub.dev/packages/path_provider',
                 ),
-                const GridItem(
+                GridItem(
                   title: 'flutter_displaymode',
                   icon: Ionicons.speedometer_outline,
                   url: 'https://pub.dev/packages/flutter_displaymode',
                 ),
-                const GridItem(
+                GridItem(
                   title: 'easy_localization',
                   icon: Ionicons.text_outline,
                   url: 'https://pub.dev/packages/easy_localization',
                 ),
-                const GridItem(
+                GridItem(
                   title: 'hive',
                   icon: Ionicons.folder_outline,
                   url: 'https://pub.dev/packages/hive',
                 ),
-                const GridItem(
+                GridItem(
                   title: 'url_launcher',
                   icon: Ionicons.share_outline,
                   url: 'https://pub.dev/packages/url_launcher',
                 ),
-                const GridItem(
+                GridItem(
                   title: 'ionicons',
                   icon: Ionicons.logo_ionic,
                   url: 'https://pub.dev/packages/ionicons',
diff --git a/lib/ui/screens/skeleton_screen.dart b/lib/ui/screens/skeleton_screen.dart
index 25192a91..bb8ae4b4 100644
--- a/lib/ui/screens/skeleton_screen.dart
+++ b/lib/ui/screens/skeleton_screen.dart
@@ -8,9 +8,11 @@ import 'package:flutter_production_boilerplate/ui/widgets/app_bar_gone.dart';
 import 'package:flutter_production_boilerplate/ui/widgets/bottom_nav_bar.dart';
 
 class SkeletonScreen extends StatelessWidget {
-  final _pageNavigation = [
-    const FirstScreen(),
-    const SecondScreen(),
+  const SkeletonScreen({Key? key}) : super(key: key);
+
+  final _pageNavigation = const [
+    FirstScreen(),
+    SecondScreen(),
   ];
 
   @override
diff --git a/lib/ui/widgets/app_bar_gone.dart b/lib/ui/widgets/app_bar_gone.dart
index 0eb8eaf5..0f58600c 100644
--- a/lib/ui/widgets/app_bar_gone.dart
+++ b/lib/ui/widgets/app_bar_gone.dart
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 
 class AppBarGone extends StatelessWidget implements PreferredSizeWidget {
-  const AppBarGone();
+  const AppBarGone({Key? key}): super(key: key);
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/ui/widgets/bottom_nav_bar.dart b/lib/ui/widgets/bottom_nav_bar.dart
index 74c3e82a..27d5356c 100644
--- a/lib/ui/widgets/bottom_nav_bar.dart
+++ b/lib/ui/widgets/bottom_nav_bar.dart
@@ -5,7 +5,10 @@ import 'package:flutter_production_boilerplate/cubit/bottom_nav_cubit.dart';
 import 'package:ionicons/ionicons.dart';
 
 class BottomNavBar extends StatelessWidget {
-  BottomNavBar();
+  /// It is okay not to use a const constructor here.
+  /// Using const breaks updating of selected BottomNavigationBarItem.
+  // ignore: prefer_const_constructors_in_immutables
+  BottomNavBar({Key? key}) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/ui/widgets/first_screen/info_card.dart b/lib/ui/widgets/first_screen/info_card.dart
index 53bd6f42..f0aca939 100644
--- a/lib/ui/widgets/first_screen/info_card.dart
+++ b/lib/ui/widgets/first_screen/info_card.dart
@@ -9,10 +9,12 @@ class InfoCard extends StatelessWidget {
   final bool isPrimaryColor;
 
   const InfoCard(
-      {required this.title,
+      {Key? key,
+      required this.title,
       required this.content,
       required this.icon,
-      required this.isPrimaryColor});
+      required this.isPrimaryColor})
+      : super(key: key);
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/ui/widgets/header.dart b/lib/ui/widgets/header.dart
index 4647d055..c0bcf1d8 100644
--- a/lib/ui/widgets/header.dart
+++ b/lib/ui/widgets/header.dart
@@ -2,9 +2,9 @@ import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
 
 class Header extends StatelessWidget {
-  final text;
+  final String text;
 
-  const Header({Key? key, this.text}) : super(key: key);
+  const Header({Key? key, required this.text}) : super(key: key);
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/ui/widgets/second_screen/grid_item.dart b/lib/ui/widgets/second_screen/grid_item.dart
index ff0e069d..d37bca93 100644
--- a/lib/ui/widgets/second_screen/grid_item.dart
+++ b/lib/ui/widgets/second_screen/grid_item.dart
@@ -9,7 +9,7 @@ class GridItem extends StatelessWidget {
   final String url;
 
   /// Named parameters are preferred, they make the code easier to understand.
-  const GridItem({required this.title, required this.icon, required this.url});
+  const GridItem({Key? key, required this.title, required this.icon, required this.url}): super(key: key);
 
   @override
   Widget build(BuildContext context) {
diff --git a/lib/ui/widgets/second_screen/link_card.dart b/lib/ui/widgets/second_screen/link_card.dart
index 7c304d0f..0a114caf 100644
--- a/lib/ui/widgets/second_screen/link_card.dart
+++ b/lib/ui/widgets/second_screen/link_card.dart
@@ -9,7 +9,7 @@ class LinkCard extends StatelessWidget {
   final IconData icon;
   final String url;
 
-  const LinkCard({required this.title, required this.icon, required this.url});
+  const LinkCard({Key? key, required this.title, required this.icon, required this.url}): super(key: key);
 
   @override
   Widget build(BuildContext context) {
diff --git a/pubspec.lock b/pubspec.lock
index 288e6b9d..a2b43af9 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -125,6 +125,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "0.3.2"
+  flutter_lints:
+    dependency: "direct dev"
+    description:
+      name: flutter_lints
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.3"
   flutter_localizations:
     dependency: transitive
     description: flutter
@@ -176,7 +183,7 @@ packages:
     source: hosted
     version: "0.6.3"
   lints:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: lints
       url: "https://pub.dartlang.org"
@@ -431,7 +438,7 @@ packages:
       name: win32
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.1.5"
+    version: "2.2.0"
   xdg_directories:
     dependency: transitive
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 97c67966..85ba8ee9 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -28,7 +28,6 @@ dependencies:
   flutter_bloc: ^7.0.1
   hydrated_bloc: ^7.0.1
   equatable: ^2.0.2
-  lints: ^1.0.1
   path_provider: ^2.0.2
   flutter_displaymode: ^0.3.2
   easy_localization: ^3.0.0
@@ -39,6 +38,7 @@ dependencies:
 dev_dependencies:
   flutter_test:
     sdk: flutter
+  flutter_lints: ^1.0.3
 
 # For information on the generic Dart part of this file, see the
 # following page: https://dart.dev/tools/pub/pubspec
diff --git a/test/widget_test.dart b/test/widget_test.dart
index 11657d32..6040beeb 100644
--- a/test/widget_test.dart
+++ b/test/widget_test.dart
@@ -5,11 +5,6 @@
 // gestures. You can also use WidgetTester to find child widgets in the widget
 // tree, read text, and verify that the values of widget properties are correct.
 
-import 'package:flutter/material.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-import 'package:flutter_production_boilerplate/main.dart';
-
 void main() {
   /* Stock test
 
-- 
GitLab