Browse Source

standby complete

Fares 11 months ago
parent
commit
5370e5df19

+ 4 - 4
lib/api/oaca.http

@@ -1,9 +1,9 @@
 GET https://www.oaca.nat.tn/vols/api/flight/filter
 ?frmmvtCod=D
 &frmaeropVil=-1
-&frmnumVol=
-&frmairport=djerba
+&frmnumVol=TU722
+&frmairport=tun
 &frmhour=0
-&frmday=16
-&frmmonth=9
+&frmday=13
+&frmmonth=11
 &frmacty=2024

+ 207 - 12
lib/fltinfo/view/dutyinfo_page.dart

@@ -11,6 +11,7 @@ import 'package:go_router/go_router.dart';
 import 'package:google_fonts/google_fonts.dart';
 import 'package:jiffy/jiffy.dart';
 import 'package:linear_progress_bar/linear_progress_bar.dart';
+import 'package:multi_select_flutter/multi_select_flutter.dart';
 import 'package:tp5/core/core.dart';
 import 'package:tp5/csv/csv_data.dart';
 import 'package:tp5/csv/data.dart';
@@ -45,6 +46,24 @@ class _DutyinfoPageState extends ConsumerState<DutyinfoPage> {
   @override
   void initState() {
     Future.delayed(Duration.zero, () {
+      if (widget.params.tlc != null) {
+        final qualif = ref.read(dataProvider).qualif;
+        collegeSelected = qualif
+            .where((e) => e.tlc == widget.params.tlc)
+            .map((e) => e.college ?? "")
+            .toSet()
+            .toList();
+        acSelected = qualif
+            .where((e) => e.tlc == widget.params.tlc)
+            .map((e) => e.ac ?? "")
+            .toSet()
+            .toList();
+        baseSelected = qualif
+            .where((e) => e.tlc == widget.params.tlc)
+            .map((e) => e.base ?? "")
+            .toSet()
+            .toList();
+      }
       crewPnlegLoad();
     });
     super.initState();
@@ -182,7 +201,8 @@ class _DutyinfoPageState extends ConsumerState<DutyinfoPage> {
   }
 
   _notifiedCrew() {
-    final qualif = ref.watch(qualifProvider(CrewFilter()));
+    // final qualif = ref.watch(qualifProvider(CrewFilter()));
+    final qualif = ref.watch(dataProvider).qualif;
 
     return WCadre(
       titleright: crewPnlegLoading
@@ -229,7 +249,10 @@ class _DutyinfoPageState extends ConsumerState<DutyinfoPage> {
                               (e) => e["college"].toString(), collegeSort)
                           .map<Widget>((e) {
                     final x = crewPnleg.elementAt(e["index"] as int);
-                    final pn = qualif.firstWhereOrNull((e) => e.tlc == x.tlc);
+                    // final pn = qualif.firstWhereOrNull((e) => e.tlc == x.tlc);
+                    final pn = (qualif.firstWhereOrNull(
+                            (e) => (e.tlc == x.tlc) && (e.ac == x.actype)) ??
+                        qualif.firstWhereOrNull((e) => e.tlc == x.tlc));
                     return WCrew(
                       college: pn?.college,
                       mle: x.tlc,
@@ -243,8 +266,30 @@ class _DutyinfoPageState extends ConsumerState<DutyinfoPage> {
     );
   }
 
+  List<String> collegeSelected = [];
+  List<String> acSelected = [];
+  List<String> baseSelected = [];
+
   _stdbyCrew() {
-    final qualif = ref.watch(qualifProvider(CrewFilter()));
+    // final qualif = ref.watch(qualifProvider(CrewFilter()));
+    final qualif = ref.watch(dataProvider).qualif;
+    final tlcs = crewPnleg.map((e) => e.tlc).toSet();
+    final pairs = qualif
+        .where((e) => tlcs.contains(e.tlc))
+        .map((e) => "${e.college},${e.ac},${e.base}")
+        .toSet()
+        .map((e) => e.split(","))
+        .toList();
+    final List<String> pnfilterd = qualif
+        .where((q) =>
+            ((collegeSelected.isEmpty || collegeSelected.contains(q.college)) &&
+                (acSelected.isEmpty || acSelected.contains(q.ac)) &&
+                (baseSelected.isEmpty || baseSelected.contains(q.base))))
+        .map((e) => e.tlc ?? "")
+        .toSet()
+        .toList();
+    final List<Pnleg> crewPnlegFiltered =
+        crewPnleg.where((e) => pnfilterd.contains(e.tlc)).toList();
     return WCadre(
       titleright: crewPnlegLoading
           ? Padding(
@@ -267,18 +312,138 @@ class _DutyinfoPageState extends ConsumerState<DutyinfoPage> {
           ? const Text("No data found !")
           : Column(
               children: [
+                MyRow(
+                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+                  children: [
+                    Gap(5),
+                    Column(
+                      children: [
+                        const Text('College:', style: TextStyle(fontSize: 11)),
+                        Text("(${(collegeSelected.length)})",
+                            style: TextStyle(fontSize: 11))
+                      ],
+                    ),
+                    Gap(5),
+                    MultiSelectChipDisplay(
+                      colorator: (value) => (collegeSelected.contains(value))
+                          ? Colors.green[800]
+                          : Colors.grey[900],
+                      //chipColor: Colors.blue[900],
+                      icon: null,
+                      textStyle: TextStyle(fontSize: 9, color: Colors.white),
+                      scrollBar: HorizontalScrollBar(),
+                      scroll: true,
+                      items: pairs
+                          .map((e) => e[0])
+                          .sortedByCompare((e) => e, collegeSort)
+                          .toSet()
+                          .map((e) => MultiSelectItem(e, "$e"))
+                          .toList(),
+                      onTap: (value) {
+                        setState(() {
+                          if (collegeSelected.contains(value)) {
+                            collegeSelected.remove(value);
+                          } else {
+                            collegeSelected.add(value);
+                          }
+                        });
+                      },
+                    ),
+                  ],
+                ),
+                MyRow(
+                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+                  children: [
+                    Gap(5),
+                    Column(
+                      children: [
+                        const Text('ACs:', style: TextStyle(fontSize: 11)),
+                        Text("(${(acSelected.length)})",
+                            style: TextStyle(fontSize: 11))
+                      ],
+                    ),
+                    Gap(5),
+                    MultiSelectChipDisplay(
+                      colorator: (value) => (acSelected.contains(value))
+                          ? Colors.green[800]
+                          : Colors.grey[900],
+                      //chipColor: Colors.blue[900],
+                      icon: null,
+                      textStyle: TextStyle(fontSize: 9, color: Colors.white),
+                      scrollBar: HorizontalScrollBar(),
+                      scroll: true,
+                      items: pairs
+                          .map((e) => e[1])
+                          .sortedByCompare((e) => e, acSort)
+                          .toSet()
+                          .map((e) => MultiSelectItem(e, "$e"))
+                          .toList(),
+                      onTap: (value) {
+                        setState(() {
+                          if (acSelected.contains(value)) {
+                            acSelected.remove(value);
+                          } else {
+                            acSelected.add(value);
+                          }
+                        });
+                      },
+                    ),
+                  ],
+                ),
+                MyRow(
+                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+                  children: [
+                    const Gap(5),
+                    Column(
+                      children: [
+                        const Text('Base:', style: TextStyle(fontSize: 11)),
+                        Text("(${(baseSelected.length)})",
+                            style: TextStyle(fontSize: 11))
+                      ],
+                    ),
+                    const Gap(5),
+                    MultiSelectChipDisplay(
+                      colorator: (value) => (baseSelected.contains(value))
+                          ? Colors.green[800]
+                          : Colors.grey[900],
+                      //chipColor: Colors.blue[900],
+                      icon: null,
+                      textStyle: TextStyle(fontSize: 9, color: Colors.white),
+                      scrollBar: HorizontalScrollBar(),
+                      scroll: true,
+                      items: pairs
+                          .map((e) => e[2])
+                          .sortedByCompare((e) => e, baseSort)
+                          .toSet()
+                          .map((e) => MultiSelectItem(e, "$e"))
+                          .toList(),
+                      onTap: (value) {
+                        setState(() {
+                          if (baseSelected.contains(value)) {
+                            baseSelected.remove(value);
+                          } else {
+                            baseSelected.add(value);
+                          }
+                        });
+                      },
+                    ),
+                  ],
+                ),
                 Padding(
                   padding: const EdgeInsets.all(8.0),
                   child: Column(
-                      children: crewPnleg
+                      children: crewPnlegFiltered
                           .mapIndexed((int i, leg) {
                             // print(leg);
                             return {
                               "index": i,
                               "college": (qualif
-                                      .firstWhereOrNull((e) => e.tlc == leg.tlc)
-                                      ?.college ??
-                                  "--"),
+                                          .where((e) => e.tlc == leg.tlc)
+                                          .map((e) => e.college)
+                                          .sortedByCompare(
+                                              (e) => e ?? "", collegeSort))
+                                      .firstOrNull ??
+                                  "--",
                               // "jdep": (leg.jdep?.millisecondsSinceEpoch ?? 0)
                               "jdep": (leg.label ?? "0")
                             };
@@ -290,9 +455,13 @@ class _DutyinfoPageState extends ConsumerState<DutyinfoPage> {
                                   ],
                               jdepcollegeSort)
                           .map<Widget>((e) {
-                            final x = crewPnleg.elementAt(e["index"] as int);
-                            final pn =
-                                qualif.firstWhereOrNull((e) => e.tlc == x.tlc);
+                            final x =
+                                crewPnlegFiltered.elementAt(e["index"] as int);
+                            // final pn =
+                            //     qualif.firstWhereOrNull((e) => e.tlc == x.tlc);
+                            final pn = (qualif.firstWhereOrNull((e) =>
+                                    (e.tlc == x.tlc) && (e.ac == x.actype)) ??
+                                qualif.firstWhereOrNull((e) => e.tlc == x.tlc));
                             return Row(
                               children: [
                                 Text("${e["jdep"]}"),
@@ -315,6 +484,7 @@ class _DutyinfoPageState extends ConsumerState<DutyinfoPage> {
 
 class DutyinfoParams {
   const DutyinfoParams({
+    this.tlc,
     this.sameday = false,
     this.date,
     this.start,
@@ -326,6 +496,7 @@ class DutyinfoParams {
     this.dep,
     this.des,
   });
+  final String? tlc;
   final bool sameday;
   final Jiffy? start;
   final Jiffy? end;
@@ -343,8 +514,32 @@ int collegeSort(String a, String b) {
   final order = ['CP', 'FO', 'PU', 'SE', 'ST', 'JU'];
 
   // Get the index of each element in the order list
-  final indexA = order.indexOf(a);
-  final indexB = order.indexOf(b);
+  final indexA = !order.contains(a) ? 99 : order.indexOf(a);
+  final indexB = !order.contains(b) ? 99 : order.indexOf(b);
+
+  // Compare based on the index
+  return indexA.compareTo(indexB);
+}
+
+int acSort(String a, String b) {
+  // Define the order based on your requirements
+  final order = ['320', '330', '32N', '319', '32T'];
+
+  // Get the index of each element in the order list
+  final indexA = !order.contains(a) ? 99 : order.indexOf(a);
+  final indexB = !order.contains(b) ? 99 : order.indexOf(b);
+
+  // Compare based on the index
+  return indexA.compareTo(indexB);
+}
+
+int baseSort(String a, String b) {
+  // Define the order based on your requirements
+  final order = ['TUN', 'MIR', 'DJE'];
+
+  // Get the index of each element in the order list
+  final indexA = !order.contains(a) ? 99 : order.indexOf(a);
+  final indexB = !order.contains(b) ? 99 : order.indexOf(b);
 
   // Compare based on the index
   return indexA.compareTo(indexB);

+ 5 - 2
lib/fltinfo/view/fltinfo_page.dart

@@ -420,8 +420,11 @@ class _FltinfoPageState extends ConsumerState<FltinfoPage> {
                         final x =
                             crewPnleg[crewPnleg.keys.elementAt(crewPosPnleg)]!
                                 .elementAt(e["index"] as int);
-                        final pn =
-                            qualif.firstWhereOrNull((e) => e.tlc == x.tlc);
+                        // final pn =
+                        //     qualif.firstWhereOrNull((e) => e.tlc == x.tlc);
+                        final pn = (qualif.firstWhereOrNull((e) =>
+                                (e.tlc == x.tlc) && (e.ac == x.actype)) ??
+                            qualif.firstWhereOrNull((e) => e.tlc == x.tlc));
                         return WCrew(
                           college: pn?.college,
                           mle: x.tlc,

+ 9 - 3
lib/ftl/view/ftl_page.dart

@@ -156,7 +156,9 @@ class _FtlPageState extends ConsumerState<FtlPage> {
         }
       }
     } finally {
-      ref.read(isLoadingProvider.notifier).state = false;
+      if (mounted) {
+        ref.read(isLoadingProvider.notifier).state = false;
+      }
     }
   }
 
@@ -197,7 +199,9 @@ class _FtlPageState extends ConsumerState<FtlPage> {
 
     final reson = await ref.read(crewlinkapiProvider).rosterMinMax();
     //print("ftlpage: reson: $reson");
-    ref.read(isLoadingProvider.notifier).state = false;
+    if (mounted) {
+      ref.read(isLoadingProvider.notifier).state = false;
+    }
 
     dynamic res;
 
@@ -275,7 +279,9 @@ class _FtlPageState extends ConsumerState<FtlPage> {
     // await ftldata.calcduties(date: null);
     await ftldata.calcduties(date: ftlcalcdate);
 
-    ref.read(isLoadingProvider.notifier).state = false;
+    if (mounted) {
+      ref.read(isLoadingProvider.notifier).state = false;
+    }
   }
 
   List<FtlDuty> get dutiestodisplay => ftldata.duties

+ 6 - 2
lib/lido/view/lidolist_page.dart

@@ -86,7 +86,9 @@ class _LidolistPageState extends ConsumerState<LidolistPage> {
         context.showError(out["error"]);
       }
       setState(() {});
-      ref.read(isLoadingProvider.notifier).state = false;
+      if (mounted) {
+        ref.read(isLoadingProvider.notifier).state = false;
+      }
       _scrollToDate();
       //print("Lidolistpage: out= $out");
       // print((LidoapiList.fromJson(out["data"][0])));
@@ -218,7 +220,9 @@ class _LidolistPageState extends ConsumerState<LidolistPage> {
 
   void _searchFlights(xcontext) async {
     ref.read(isLoadingProvider.notifier).state = true;
-    ref.read(isLoadingProvider.notifier).state = false;
+    if (mounted) {
+      ref.read(isLoadingProvider.notifier).state = false;
+    }
     ctrldep.text = widget.params.dep ?? "";
     ctrldes.text = widget.params.des ?? "";
     ctrlairline.text = widget.params.al ?? "";

+ 9 - 3
lib/roster/view/crewlist_page.dart

@@ -111,7 +111,9 @@ class _CrewlistPageState extends ConsumerState<CrewlistPage> {
         _scrollToDate();
       }
     } finally {
-      ref.read(isLoadingProvider.notifier).state = false;
+      if (mounted) {
+        ref.read(isLoadingProvider.notifier).state = false;
+      }
     }
   }
 
@@ -344,7 +346,9 @@ class _CrewlistPageState extends ConsumerState<CrewlistPage> {
     final resoff = Hive.box("crewlink").get(_crewlistMinMaxKey);
 
     final reson = await ref.read(crewlinkapiProvider).showCrewMinMax();
-    ref.read(isLoadingProvider.notifier).state = false;
+    if (mounted) {
+      ref.read(isLoadingProvider.notifier).state = false;
+    }
 
     dynamic res;
     if (reson["error"] == null && reson?["data"] != null) {
@@ -533,7 +537,9 @@ class _CrewlistPageState extends ConsumerState<CrewlistPage> {
     ref.read(isLoadingProvider.notifier).state = true;
     final resoff = Hive.box("crewlink").get(_crewlistMinMaxKey);
     final reson = await ref.read(crewlinkapiProvider).showCrewMinMax();
-    ref.read(isLoadingProvider.notifier).state = false;
+    if (mounted) {
+      ref.read(isLoadingProvider.notifier).state = false;
+    }
     dynamic res;
     if (reson["error"] == null && reson?["data"] != null) {
       Hive.box("crewlink").put(_crewlistMinMaxKey, reson["data"]);

+ 12 - 4
lib/roster/view/roster_page.dart

@@ -136,7 +136,9 @@ class _RosterPageState extends ConsumerState<RosterPage> {
         _scrollToDate();
       }
     } finally {
-      ref.read(isLoadingProvider.notifier).state = false;
+      if (mounted) {
+        ref.read(isLoadingProvider.notifier).state = false;
+      }
     }
   }
 
@@ -367,7 +369,9 @@ class _RosterPageState extends ConsumerState<RosterPage> {
                       final res = await ref
                           .read(crewlinkapiProvider)
                           .notif(download: true, fileid: fileidnotif);
-                      ref.read(isLoadingProvider.notifier).state = false;
+                      if (mounted) {
+                        ref.read(isLoadingProvider.notifier).state = false;
+                      }
                       if (res is Map && res["data"]?["id"] != null) {
                         _showNotif();
                       } else {
@@ -496,7 +500,9 @@ class _RosterPageState extends ConsumerState<RosterPage> {
                       //     "notif": true
                       //   }
                       // };
-                      ref.read(isLoadingProvider.notifier).state = false;
+                      if (mounted) {
+                        ref.read(isLoadingProvider.notifier).state = false;
+                      }
                       final ackok = (ack is Map && ack["error"] == null
                           //&&
                           //ack["data"]?["error"] != null
@@ -568,7 +574,9 @@ class _RosterPageState extends ConsumerState<RosterPage> {
     final resoff = Hive.box("crewlink").get(_rosterMinMaxKey);
 
     final reson = await ref.read(crewlinkapiProvider).rosterMinMax();
-    ref.read(isLoadingProvider.notifier).state = false;
+    if (mounted) {
+      ref.read(isLoadingProvider.notifier).state = false;
+    }
 
     dynamic res;
 

+ 1 - 1
lib/rosters/rosters_page.dart

@@ -253,7 +253,7 @@ class _RostersPageState extends ConsumerState<RostersPage> {
         onTap: () {
           context.push("/dutyinfo",
               extra: DutyinfoParams(
-                sameday: true,
+                sameday: true, tlc: leg.tlc,
                 dutytype: leg.dutytype,
                 // label: leg.label,
                 // dep: leg.dep,

+ 30 - 22
pubspec.lock

@@ -449,10 +449,10 @@ packages:
     dependency: "direct main"
     description:
       name: go_router
-      sha256: ce89c5a993ca5eea74535f798478502c30a625ecb10a1de4d7fef5cd1bcac2a4
+      sha256: "8ae664a70174163b9f65ea68dd8673e29db8f9095de7b5cd00e167c621f4fef5"
       url: "https://pub.dev"
     source: hosted
-    version: "14.4.1"
+    version: "14.6.0"
   google_fonts:
     dependency: "direct main"
     description:
@@ -701,6 +701,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.0.0"
+  multi_select_flutter:
+    dependency: "direct main"
+    description:
+      name: multi_select_flutter
+      sha256: "503857b415d390d29159df8a9d92d83c6aac17aaf1c307fb7bcfc77d097d20ed"
+      url: "https://pub.dev"
+    source: hosted
+    version: "4.1.3"
   package_config:
     dependency: transitive
     description:
@@ -945,10 +953,10 @@ packages:
     dependency: transitive
     description:
       name: shared_preferences
-      sha256: "746e5369a43170c25816cc472ee016d3a66bc13fcf430c0bc41ad7b4b2922051"
+      sha256: "95f9997ca1fb9799d494d0cb2a780fd7be075818d59f00c43832ed112b158a82"
       url: "https://pub.dev"
     source: hosted
-    version: "2.3.2"
+    version: "2.3.3"
   shared_preferences_android:
     dependency: transitive
     description:
@@ -1118,18 +1126,18 @@ packages:
     dependency: transitive
     description:
       name: syncfusion_flutter_core
-      sha256: "31d2ddf410ee41abb3ecf85b7b6e8e1563307ad52ee784ddd91337e30280f715"
+      sha256: "225b1cc135549bb4eef096d63b7323c30ee61c4b095c7e8a14bf9333e243d84b"
       url: "https://pub.dev"
     source: hosted
-    version: "27.1.58"
+    version: "27.2.2"
   syncfusion_flutter_pdf:
     dependency: "direct main"
     description:
       name: syncfusion_flutter_pdf
-      sha256: ada2e2cf5603be558ff9e67e5941858cb15d6fac1de4d5307b3ecfb97bfe8108
+      sha256: a1d9191fe72015977437b677ef57a44b860c8f9d23d62d2c41c431892ccfff5c
       url: "https://pub.dev"
     source: hosted
-    version: "27.1.58"
+    version: "27.2.2"
   syncfusion_flutter_pdfviewer:
     dependency: "direct main"
     description:
@@ -1142,42 +1150,42 @@ packages:
     dependency: transitive
     description:
       name: syncfusion_flutter_signaturepad
-      sha256: e37efd2e2d57af7e4597073769dee3c2f343d46c324a6d81a055302fad65fc7c
+      sha256: "9b81ad7e3a12f0306355bda761070065f849d40f664ceef5d35b1bcc33a709a5"
       url: "https://pub.dev"
     source: hosted
-    version: "27.1.58"
+    version: "27.2.2"
   syncfusion_pdfviewer_macos:
     dependency: transitive
     description:
       name: syncfusion_pdfviewer_macos
-      sha256: f90e57ffc3c9460ed8096e2c585977af180f30889b0f620844ef587745b3e4bd
+      sha256: bf9d0371506e44e02427e082ec673a5ed4a0030d30e679c05750917393f10e08
       url: "https://pub.dev"
     source: hosted
-    version: "27.1.58"
+    version: "27.2.2"
   syncfusion_pdfviewer_platform_interface:
     dependency: transitive
     description:
       name: syncfusion_pdfviewer_platform_interface
-      sha256: "70f4730f4db0d00a9f38a25ffb71403e579f3f091ef824a69dfe8b35dc2f1270"
+      sha256: b4358d5ccdfa83d9aed1547529078423e5d41731dc1c37faedb51bc5373e178a
       url: "https://pub.dev"
     source: hosted
-    version: "27.1.58"
+    version: "27.2.2"
   syncfusion_pdfviewer_web:
     dependency: transitive
     description:
       name: syncfusion_pdfviewer_web
-      sha256: dfbd5c6f7d504129f854df448ad6cd330878ae55c105409cf26c4834257be2f6
+      sha256: "89e9f5f6fdb220f3bc6a9c5b08bd77f967c21ef273114f97f10e62582ab553e1"
       url: "https://pub.dev"
     source: hosted
-    version: "27.1.58"
+    version: "27.2.2"
   syncfusion_pdfviewer_windows:
     dependency: transitive
     description:
       name: syncfusion_pdfviewer_windows
-      sha256: "30ef646d5a42a89e47b3faa6a9af4d814bef87bccd4214ed46a191698657c5ca"
+      sha256: e698c992d9463a66f345e9b81744360345635a4c7b2cf66458a914de898621d5
       url: "https://pub.dev"
     source: hosted
-    version: "27.1.58"
+    version: "27.2.2"
   term_glyph:
     dependency: transitive
     description:
@@ -1198,10 +1206,10 @@ packages:
     dependency: "direct main"
     description:
       name: timezone
-      sha256: "2236ec079a174ce07434e89fcd3fcda430025eb7692244139a9cf54fdcf1fc7d"
+      sha256: ffc9d5f4d1193534ef051f9254063fa53d588609418c84299956c3db9383587d
       url: "https://pub.dev"
     source: hosted
-    version: "0.9.4"
+    version: "0.10.0"
   timing:
     dependency: transitive
     description:
@@ -1254,10 +1262,10 @@ packages:
     dependency: transitive
     description:
       name: url_launcher_linux
-      sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af
+      sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
       url: "https://pub.dev"
     source: hosted
-    version: "3.2.0"
+    version: "3.2.1"
   url_launcher_macos:
     dependency: transitive
     description:

+ 2 - 1
pubspec.yaml

@@ -56,6 +56,7 @@ dependencies:
   #sticky_headers: #^0.3.0+2
   linear_progress_bar: #^1.1.2
   #supabase_auth_ui: ^0.5.4
+  multi_select_flutter: #^4.1.3.0.0
 
 dev_dependencies:
   flutter_test:
@@ -69,7 +70,7 @@ dev_dependencies:
   #json_serializable: #^6.6.1
   custom_lint:
   riverpod_lint: #^2.3.1
-  flutter_launcher_icons: "^0.14.1"
+  flutter_launcher_icons: #^0.14.1
 
 flutter_launcher_icons:
   android: "launcher_icon"