Jonny Borges
Committed by GitHub

Merge branch 'master' into feature/hover_snackbar

Showing 85 changed files with 2293 additions and 998 deletions

Too many changes to show.

To preserve performance only 85 of 85+ files are displayed.

No preview for this file type
@@ -23,7 +23,7 @@ jobs: @@ -23,7 +23,7 @@ jobs:
23 # https://github.com/marketplace/actions/flutter-action 23 # https://github.com/marketplace/actions/flutter-action
24 - uses: subosito/flutter-action@v2 24 - uses: subosito/flutter-action@v2
25 with: 25 with:
26 - flutter-version: "3.0.5" 26 + flutter-version: "3.7.3"
27 channel: "stable" 27 channel: "stable"
28 - run: flutter pub get 28 - run: flutter pub get
29 #- run: flutter analyze 29 #- run: flutter analyze
  1 +## [5.0.0-release-candidate-2]
  2 +This version adds built-in support for animation in Flutter in an easy, clear way, and without having to create a StatefulWidget with controllers and animations. All you need to do is call the name of the animation.
  3 +
  4 +If you want to add a "fadeIn" effect to any widget, simply add .fadeIn() to the end of it.
  5 +
  6 +```dart
  7 + Container(
  8 + color: Colors.blue,
  9 + height: 100,
  10 + width: 100,
  11 + ).fadeIn(),
  12 +```
  13 +
  14 +
  15 +https://user-images.githubusercontent.com/35742643/221383556-075a0b71-1617-4a31-a3c7-1acc68732f59.mp4
  16 +
  17 +Maybe you want to merge two or more animations, just concatenate them at the end of the widget.
  18 +
  19 +```dart
  20 + Container(
  21 + color: Colors.blue,
  22 + height: 100,
  23 + width: 100,
  24 + ).fadeIn().bounce(begin: -0.8, end: 0.3),
  25 +```
  26 +
  27 +https://user-images.githubusercontent.com/35742643/221383613-9044c92f-7c6b-48c4-aa79-0a0c20d4068a.mp4
  28 +
  29 +
  30 +Creating animation sequences in Flutter is one of the most painful things to do with the framework. You need to create tons of AnimationControllers. Well, using GetX 5 you just need to tell your animation that it is sequential. Just like that.
  31 +
  32 +```dart
  33 + const FlutterLogo(size: 110)
  34 + .bounce(begin: -0.8, end: 0.4)
  35 + .fadeIn()
  36 + .spin(isSequential: true)
  37 + .wobble(isSequential: true, begin: 0, end: 8)
  38 + .flip(isSequential: true)
  39 + .fadeOut(isSequential: true),
  40 +```
  41 +
  42 +Result:
  43 +
  44 +
  45 +https://user-images.githubusercontent.com/35742643/221393968-20cb2411-516b-44a7-8b85-45090bece532.mp4
  46 +
  47 +
  48 +## [5.0.0-release-candidate]
  49 +Refactor StateManager, RouteManager and InstanceManager from scratch
  50 +Fixed Bugs
  51 +Added a Scopped DI
  52 +Api now uses Navigator 2
  53 +Added new RouteOutlet
  54 +Added a new futurize method to StateMixin, that tracks updates, errors, and states programatically,
  55 +
1 ## [4.6.1] 56 ## [4.6.1]
2 Fix GetConnect on Flutter web 57 Fix GetConnect on Flutter web
3 58
@@ -1274,3 +1274,5 @@ Any contribution is welcome! @@ -1274,3 +1274,5 @@ Any contribution is welcome!
1274 - [Flutter State Management with GetX – Complete App](https://www.appwithflutter.com/flutter-state-management-with-getx/) - by App With Flutter. 1274 - [Flutter State Management with GetX – Complete App](https://www.appwithflutter.com/flutter-state-management-with-getx/) - by App With Flutter.
1275 - [Flutter Routing with Animation using Get Package](https://www.appwithflutter.com/flutter-routing-using-get-package/) - by App With Flutter. 1275 - [Flutter Routing with Animation using Get Package](https://www.appwithflutter.com/flutter-routing-using-get-package/) - by App With Flutter.
1276 - [A minimal example on dartpad](https://dartpad.dev/2b3d0d6f9d4e312c5fdbefc414c1727e?) - by [Roi Peker](https://github.com/roipeker) 1276 - [A minimal example on dartpad](https://dartpad.dev/2b3d0d6f9d4e312c5fdbefc414c1727e?) - by [Roi Peker](https://github.com/roipeker)
  1277 +- [GetConnect: The best way to perform API operations in Flutter with Get.](https://absyz.com/getconnect-the-best-way-to-perform-api-operations-in-flutter-with-getx/) - by [MD Sarfaraj](https://github.com/socialmad)
  1278 +- [How To Create an App with GetX Architect in Flutter with Get CLI](https://www.youtube.com/watch?v=7mb4qBA7kTk&t=1380s) - by [MD Sarfaraj](https://github.com/socialmad)
1 # Include option is buggy: 1 # Include option is buggy:
2 -include: package:lints/recommended.yaml 2 +include: package:flutter_lints/flutter.yaml
3 # In case the include issue gets fixed, lines below INCLUDE_FIX 3 # In case the include issue gets fixed, lines below INCLUDE_FIX
4 # can be removed 4 # can be removed
@@ -34,6 +34,7 @@ @@ -34,6 +34,7 @@
34 /android/ 34 /android/
35 /web/ 35 /web/
36 /macos/ 36 /macos/
  37 +/windows/
37 38
38 # Web related 39 # Web related
39 lib/generated_plugin_registrant.dart 40 lib/generated_plugin_registrant.dart
1 # This file tracks properties of this Flutter project. 1 # This file tracks properties of this Flutter project.
2 # Used by Flutter tool to assess capabilities and perform upgrades etc. 2 # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 # 3 #
4 -# This file should be version controlled and should not be manually edited. 4 +# This file should be version controlled.
5 5
6 version: 6 version:
7 - revision: 7c6f9dd2396dfe7deb6fd11edc12c10786490083  
8 - channel: dev 7 + revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  8 + channel: stable
9 9
10 project_type: app 10 project_type: app
  11 +
  12 +# Tracks metadata for the flutter migrate command
  13 +migration:
  14 + platforms:
  15 + - platform: root
  16 + create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  17 + base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  18 + - platform: android
  19 + create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  20 + base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  21 + - platform: ios
  22 + create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  23 + base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  24 + - platform: linux
  25 + create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  26 + base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  27 + - platform: macos
  28 + create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  29 + base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  30 + - platform: web
  31 + create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  32 + base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  33 + - platform: windows
  34 + create_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  35 + base_revision: 9944297138845a94256f1cf37beb88ff9a8e811a
  36 +
  37 + # User provided section
  38 +
  39 + # List of Local paths (relative to this file) that should be
  40 + # ignored by the migrate tool.
  41 + #
  42 + # Files that are not part of the templates will be ignored by default.
  43 + unmanaged_files:
  44 + - 'lib/main.dart'
  45 + - 'ios/Runner.xcodeproj/project.pbxproj'
  1 +# This file configures the analyzer, which statically analyzes Dart code to
  2 +# check for errors, warnings, and lints.
  3 +#
  4 +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
  5 +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
  6 +# invoked from the command line by running `flutter analyze`.
  7 +
  8 +# The following line activates a set of recommended lints for Flutter apps,
  9 +# packages, and plugins designed to encourage good coding practices.
  10 +include: package:flutter_lints/flutter.yaml
  11 +
  12 +linter:
  13 + # The lint rules applied to this project can be customized in the
  14 + # section below to disable rules from the `package:flutter_lints/flutter.yaml`
  15 + # included above or to enable additional rules. A list of all available lints
  16 + # and their documentation is published at
  17 + # https://dart-lang.github.io/linter/lints/index.html.
  18 + #
  19 + # Instead of disabling a lint rule for the entire project in the
  20 + # section below, it can also be suppressed for a single line of code
  21 + # or a specific dart file by using the `// ignore: name_of_lint` and
  22 + # `// ignore_for_file: name_of_lint` syntax on the line or in the file
  23 + # producing the lint.
  24 + rules:
  25 + camel_case_types: false
  26 + constant_identifier_names: false
  27 + # avoid_print: false # Uncomment to disable the `avoid_print` rule
  28 + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
  29 +
  30 +# Additional information about this file can be found at
  31 +# https://dart.dev/guides/language/analysis-options
@@ -6,7 +6,7 @@ import 'pt_br.dart'; @@ -6,7 +6,7 @@ import 'pt_br.dart';
6 6
7 class TranslationService extends Translations { 7 class TranslationService extends Translations {
8 static Locale? get locale => Get.deviceLocale; 8 static Locale? get locale => Get.deviceLocale;
9 - static final fallbackLocale = Locale('en', 'US'); 9 + static const fallbackLocale = Locale('en', 'US');
10 @override 10 @override
11 Map<String, Map<String, String>> get keys => { 11 Map<String, Map<String, String>> get keys => {
12 'en_US': en_US, 12 'en_US': en_US,
@@ -6,7 +6,7 @@ import 'routes/app_pages.dart'; @@ -6,7 +6,7 @@ import 'routes/app_pages.dart';
6 import 'shared/logger/logger_utils.dart'; 6 import 'shared/logger/logger_utils.dart';
7 7
8 void main() { 8 void main() {
9 - runApp(MyApp()); 9 + runApp(const MyApp());
10 } 10 }
11 11
12 class MyApp extends StatelessWidget { 12 class MyApp extends StatelessWidget {
@@ -10,7 +10,7 @@ class CountryView extends GetView<HomeController> { @@ -10,7 +10,7 @@ class CountryView extends GetView<HomeController> {
10 @override 10 @override
11 Widget build(BuildContext context) { 11 Widget build(BuildContext context) {
12 return Container( 12 return Container(
13 - decoration: BoxDecoration( 13 + decoration: const BoxDecoration(
14 image: DecorationImage( 14 image: DecorationImage(
15 fit: BoxFit.cover, 15 fit: BoxFit.cover,
16 colorFilter: ColorFilter.linearToSrgbGamma(), 16 colorFilter: ColorFilter.linearToSrgbGamma(),
@@ -18,38 +18,36 @@ class CountryView extends GetView<HomeController> { @@ -18,38 +18,36 @@ class CountryView extends GetView<HomeController> {
18 "https://images.pexels.com/photos/3902882/pexels-photo-3902882.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"))), 18 "https://images.pexels.com/photos/3902882/pexels-photo-3902882.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940"))),
19 child: BackdropFilter( 19 child: BackdropFilter(
20 filter: ImageFilter.blur(sigmaX: 15.0, sigmaY: 15.0), 20 filter: ImageFilter.blur(sigmaX: 15.0, sigmaY: 15.0),
21 - child: Container(  
22 - child: Scaffold( 21 + child: Scaffold(
  22 + backgroundColor: Colors.transparent,
  23 + appBar: AppBar(
  24 + title: Text('corona_by_country'.tr),
23 backgroundColor: Colors.transparent, 25 backgroundColor: Colors.transparent,
24 - appBar: AppBar(  
25 - title: Text('corona_by_country'.tr),  
26 - backgroundColor: Colors.transparent,  
27 - elevation: 0,  
28 - centerTitle: true,  
29 - ),  
30 - body: Center(  
31 - child: ListView.builder(  
32 - itemCount: controller.state.countries.length,  
33 - itemBuilder: (context, index) {  
34 - final country = controller.state.countries[index];  
35 - return ListTile(  
36 - onTap: () async {  
37 - //Get.rootDelegate.toNamed('/home/country');  
38 - final data = await Get.toNamed(  
39 - '/home/country/details?id=$index');  
40 - print(data);  
41 - },  
42 - trailing: CircleAvatar(  
43 - backgroundImage: NetworkImage(  
44 - "https://flagpedia.net/data/flags/normal/${country.countryCode.toLowerCase()}.png"),  
45 - ),  
46 - title: Text(country.country),  
47 - subtitle: Text(  
48 - // ignore: lines_longer_than_80_chars  
49 - '${'total_infecteds'.tr}${' ${country.totalConfirmed}'}'),  
50 - );  
51 - }),  
52 - ), 26 + elevation: 0,
  27 + centerTitle: true,
  28 + ),
  29 + body: Center(
  30 + child: ListView.builder(
  31 + itemCount: controller.state.countries.length,
  32 + itemBuilder: (context, index) {
  33 + final country = controller.state.countries[index];
  34 + return ListTile(
  35 + onTap: () async {
  36 + //Get.rootDelegate.toNamed('/home/country');
  37 + final data =
  38 + await Get.toNamed('/home/country/details?id=$index');
  39 + Get.log(data);
  40 + },
  41 + trailing: CircleAvatar(
  42 + backgroundImage: NetworkImage(
  43 + "https://flagpedia.net/data/flags/normal/${country.countryCode.toLowerCase()}.png"),
  44 + ),
  45 + title: Text(country.country),
  46 + subtitle: Text(
  47 + // ignore: lines_longer_than_80_chars
  48 + '${'total_infecteds'.tr}${' ${country.totalConfirmed}'}'),
  49 + );
  50 + }),
53 ), 51 ),
54 ), 52 ),
55 ), 53 ),
@@ -15,77 +15,79 @@ class DetailsView extends GetView<HomeController> { @@ -15,77 +15,79 @@ class DetailsView extends GetView<HomeController> {
15 decoration: BoxDecoration( 15 decoration: BoxDecoration(
16 image: DecorationImage( 16 image: DecorationImage(
17 fit: BoxFit.cover, 17 fit: BoxFit.cover,
18 - colorFilter: ColorFilter.linearToSrgbGamma(), 18 + colorFilter: const ColorFilter.linearToSrgbGamma(),
19 image: NetworkImage( 19 image: NetworkImage(
20 "https://flagpedia.net/data/flags/normal/${country.countryCode.toLowerCase()}.png"), 20 "https://flagpedia.net/data/flags/normal/${country.countryCode.toLowerCase()}.png"),
21 ), 21 ),
22 ), 22 ),
23 child: BackdropFilter( 23 child: BackdropFilter(
24 filter: ImageFilter.blur(sigmaX: 15.0, sigmaY: 15.0), 24 filter: ImageFilter.blur(sigmaX: 15.0, sigmaY: 15.0),
25 - child: Container(  
26 - child: Scaffold(  
27 - backgroundColor: Colors.transparent,  
28 - appBar: AppBar(  
29 - title: Text('details'.tr),  
30 - backgroundColor: Colors.black12,  
31 - elevation: 0,  
32 - centerTitle: true,  
33 - ),  
34 - body: Center(  
35 - child: Column(  
36 - mainAxisAlignment: MainAxisAlignment.center,  
37 - children: [  
38 - Text(  
39 - '${country.country}',  
40 - style: TextStyle(fontSize: 45, fontWeight: FontWeight.bold),  
41 - ),  
42 - SizedBox(  
43 - height: 35,  
44 - ),  
45 - Text(  
46 - 'total_confirmed'.tr,  
47 - style: TextStyle(  
48 - fontSize: 25,  
49 - ),  
50 - ),  
51 - Text(  
52 - '${country.totalConfirmed}',  
53 - style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),  
54 - ),  
55 - SizedBox(  
56 - height: 10,  
57 - ),  
58 - Text(  
59 - 'total_deaths'.tr,  
60 - style: TextStyle(  
61 - fontSize: 25,  
62 - ),  
63 - ),  
64 - Text(  
65 - '${country.totalDeaths}',  
66 - style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),  
67 - ),  
68 - SizedBox(  
69 - height: 10, 25 + child: Scaffold(
  26 + backgroundColor: Colors.transparent,
  27 + appBar: AppBar(
  28 + title: Text('details'.tr),
  29 + backgroundColor: Colors.black12,
  30 + elevation: 0,
  31 + centerTitle: true,
  32 + ),
  33 + body: Center(
  34 + child: Column(
  35 + mainAxisAlignment: MainAxisAlignment.center,
  36 + children: [
  37 + Text(
  38 + country.country,
  39 + style:
  40 + const TextStyle(fontSize: 45, fontWeight: FontWeight.bold),
  41 + ),
  42 + const SizedBox(
  43 + height: 35,
  44 + ),
  45 + Text(
  46 + 'total_confirmed'.tr,
  47 + style: const TextStyle(
  48 + fontSize: 25,
70 ), 49 ),
71 - Text(  
72 - 'total_recovered'.tr,  
73 - style: TextStyle(  
74 - fontSize: 25,  
75 - ), 50 + ),
  51 + Text(
  52 + '${country.totalConfirmed}',
  53 + style:
  54 + const TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
  55 + ),
  56 + const SizedBox(
  57 + height: 10,
  58 + ),
  59 + Text(
  60 + 'total_deaths'.tr,
  61 + style: const TextStyle(
  62 + fontSize: 25,
76 ), 63 ),
77 - Text(  
78 - '${country.totalRecovered}',  
79 - style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold), 64 + ),
  65 + Text(
  66 + '${country.totalDeaths}',
  67 + style:
  68 + const TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
  69 + ),
  70 + const SizedBox(
  71 + height: 10,
  72 + ),
  73 + Text(
  74 + 'total_recovered'.tr,
  75 + style: const TextStyle(
  76 + fontSize: 25,
80 ), 77 ),
81 - TextButton(  
82 - onPressed: () {  
83 - Get.back(result: 'djsoidjsoidj');  
84 - },  
85 - child: Text('back'))  
86 - ],  
87 - )),  
88 - ), 78 + ),
  79 + Text(
  80 + '${country.totalRecovered}',
  81 + style:
  82 + const TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
  83 + ),
  84 + TextButton(
  85 + onPressed: () {
  86 + Get.back(result: 'djsoidjsoidj');
  87 + },
  88 + child: const Text('back'))
  89 + ],
  90 + )),
89 ), 91 ),
90 ), 92 ),
91 ); 93 );
@@ -9,7 +9,7 @@ class HomeView extends GetView<HomeController> { @@ -9,7 +9,7 @@ class HomeView extends GetView<HomeController> {
9 @override 9 @override
10 Widget build(BuildContext context) { 10 Widget build(BuildContext context) {
11 return Container( 11 return Container(
12 - decoration: BoxDecoration( 12 + decoration: const BoxDecoration(
13 color: Colors.white, 13 color: Colors.white,
14 image: DecorationImage( 14 image: DecorationImage(
15 fit: BoxFit.cover, 15 fit: BoxFit.cover,
@@ -22,7 +22,7 @@ class HomeView extends GetView<HomeController> { @@ -22,7 +22,7 @@ class HomeView extends GetView<HomeController> {
22 backgroundColor: Colors.transparent, 22 backgroundColor: Colors.transparent,
23 appBar: AppBar( 23 appBar: AppBar(
24 leading: IconButton( 24 leading: IconButton(
25 - icon: Icon(Icons.add), 25 + icon: const Icon(Icons.add),
26 onPressed: () { 26 onPressed: () {
27 Get.snackbar('title', 'message'); 27 Get.snackbar('title', 'message');
28 }, 28 },
@@ -38,43 +38,45 @@ class HomeView extends GetView<HomeController> { @@ -38,43 +38,45 @@ class HomeView extends GetView<HomeController> {
38 return Column( 38 return Column(
39 mainAxisAlignment: MainAxisAlignment.center, 39 mainAxisAlignment: MainAxisAlignment.center,
40 children: [ 40 children: [
41 - SizedBox( 41 + const SizedBox(
42 height: 100, 42 height: 100,
43 ), 43 ),
44 Text( 44 Text(
45 'total_confirmed'.tr, 45 'total_confirmed'.tr,
46 - style: TextStyle( 46 + style: const TextStyle(
47 fontSize: 30, 47 fontSize: 30,
48 ), 48 ),
49 ), 49 ),
50 Text( 50 Text(
51 '${state!.global.totalConfirmed}', 51 '${state!.global.totalConfirmed}',
52 - style: TextStyle(fontSize: 45, fontWeight: FontWeight.bold), 52 + style: const TextStyle(
  53 + fontSize: 45, fontWeight: FontWeight.bold),
53 ), 54 ),
54 - SizedBox( 55 + const SizedBox(
55 height: 10, 56 height: 10,
56 ), 57 ),
57 Text( 58 Text(
58 'total_deaths'.tr, 59 'total_deaths'.tr,
59 - style: TextStyle( 60 + style: const TextStyle(
60 fontSize: 30, 61 fontSize: 30,
61 ), 62 ),
62 ), 63 ),
63 Text( 64 Text(
64 '${state.global.totalDeaths}', 65 '${state.global.totalDeaths}',
65 - style: TextStyle(fontSize: 45, fontWeight: FontWeight.bold), 66 + style: const TextStyle(
  67 + fontSize: 45, fontWeight: FontWeight.bold),
66 ), 68 ),
67 - SizedBox( 69 + const SizedBox(
68 height: 10, 70 height: 10,
69 ), 71 ),
70 OutlinedButton( 72 OutlinedButton(
71 style: OutlinedButton.styleFrom( 73 style: OutlinedButton.styleFrom(
72 - textStyle: TextStyle(color: Colors.black),  
73 - side: BorderSide( 74 + textStyle: const TextStyle(color: Colors.black),
  75 + side: const BorderSide(
74 color: Colors.deepPurple, 76 color: Colors.deepPurple,
75 width: 3, 77 width: 3,
76 ), 78 ),
77 - shape: StadiumBorder(), 79 + shape: const StadiumBorder(),
78 ), 80 ),
79 onPressed: () async { 81 onPressed: () async {
80 //await Navigation Get.rootDelegate.toNamed('/home/country'); 82 //await Navigation Get.rootDelegate.toNamed('/home/country');
@@ -82,7 +84,7 @@ class HomeView extends GetView<HomeController> { @@ -82,7 +84,7 @@ class HomeView extends GetView<HomeController> {
82 }, 84 },
83 child: Text( 85 child: Text(
84 'fetch_country'.tr, 86 'fetch_country'.tr,
85 - style: TextStyle( 87 + style: const TextStyle(
86 fontWeight: FontWeight.bold, 88 fontWeight: FontWeight.bold,
87 color: Colors.black, 89 color: Colors.black,
88 ), 90 ),
@@ -90,17 +92,17 @@ class HomeView extends GetView<HomeController> { @@ -90,17 +92,17 @@ class HomeView extends GetView<HomeController> {
90 ), 92 ),
91 OutlinedButton( 93 OutlinedButton(
92 style: OutlinedButton.styleFrom( 94 style: OutlinedButton.styleFrom(
93 - textStyle: TextStyle(color: Colors.black),  
94 - side: BorderSide( 95 + textStyle: const TextStyle(color: Colors.black),
  96 + side: const BorderSide(
95 color: Colors.deepPurple, 97 color: Colors.deepPurple,
96 width: 3, 98 width: 3,
97 ), 99 ),
98 - shape: StadiumBorder(), 100 + shape: const StadiumBorder(),
99 ), 101 ),
100 onPressed: () { 102 onPressed: () {
101 - Get.updateLocale(Locale('pt', 'BR')); 103 + Get.updateLocale(const Locale('pt', 'BR'));
102 }, 104 },
103 - child: Text( 105 + child: const Text(
104 'Update language to Portuguese', 106 'Update language to Portuguese',
105 style: TextStyle( 107 style: TextStyle(
106 fontWeight: FontWeight.bold, 108 fontWeight: FontWeight.bold,
@@ -14,16 +14,16 @@ class AppPages { @@ -14,16 +14,16 @@ class AppPages {
14 static final routes = [ 14 static final routes = [
15 GetPage( 15 GetPage(
16 name: Routes.HOME, 16 name: Routes.HOME,
17 - page: () => HomeView(), 17 + page: () => const HomeView(),
18 binding: HomeBinding(), 18 binding: HomeBinding(),
19 children: [ 19 children: [
20 GetPage( 20 GetPage(
21 name: Routes.COUNTRY, 21 name: Routes.COUNTRY,
22 - page: () => CountryView(), 22 + page: () => const CountryView(),
23 children: [ 23 children: [
24 GetPage( 24 GetPage(
25 name: Routes.DETAILS, 25 name: Routes.DETAILS,
26 - page: () => DetailsView(), 26 + page: () => const DetailsView(),
27 ), 27 ),
28 ], 28 ],
29 ), 29 ),
1 mixin Logger { 1 mixin Logger {
2 // Sample of abstract logging function 2 // Sample of abstract logging function
3 static void write(String text, {bool isError = false}) { 3 static void write(String text, {bool isError = false}) {
  4 + // ignore: avoid_print
4 Future.microtask(() => print('** $text. isError: [$isError]')); 5 Future.microtask(() => print('** $text. isError: [$isError]'));
5 } 6 }
6 } 7 }
@@ -38,6 +38,7 @@ dev_dependencies: @@ -38,6 +38,7 @@ dev_dependencies:
38 flutter_test: 38 flutter_test:
39 sdk: flutter 39 sdk: flutter
40 get_test: 4.0.1 40 get_test: 4.0.1
  41 + flutter_lints: ^2.0.1
41 42
42 # For information on the generic Dart part of this file, see the 43 # For information on the generic Dart part of this file, see the
43 # following page: https://dart.dev/tools/pub/pubspec 44 # following page: https://dart.dev/tools/pub/pubspec
@@ -3,13 +3,11 @@ import 'dart:io'; @@ -3,13 +3,11 @@ import 'dart:io';
3 import 'package:flutter/material.dart'; 3 import 'package:flutter/material.dart';
4 import 'package:flutter_test/flutter_test.dart'; 4 import 'package:flutter_test/flutter_test.dart';
5 import 'package:get/get.dart'; 5 import 'package:get/get.dart';
  6 +import 'package:get_demo/pages/home/domain/adapters/repository_adapter.dart';
  7 +import 'package:get_demo/pages/home/domain/entity/cases_model.dart';
  8 +import 'package:get_demo/pages/home/presentation/controllers/home_controller.dart';
6 // import 'package:get_demo/routes/app_pages.dart'; 9 // import 'package:get_demo/routes/app_pages.dart';
7 // import 'package:get_test/get_test.dart'; 10 // import 'package:get_test/get_test.dart';
8 -import 'package:matcher/matcher.dart' as m;  
9 -  
10 -import '../lib/pages/home/domain/adapters/repository_adapter.dart';  
11 -import '../lib/pages/home/domain/entity/cases_model.dart';  
12 -import '../lib/pages/home/presentation/controllers/home_controller.dart';  
13 11
14 class MockRepositorySuccess implements IHomeRepository { 12 class MockRepositorySuccess implements IHomeRepository {
15 @override 13 @override
@@ -57,7 +55,7 @@ void main() { @@ -57,7 +55,7 @@ void main() {
57 test('Test Controller', () async { 55 test('Test Controller', () async {
58 /// Controller can't be on memory 56 /// Controller can't be on memory
59 expect(() => Get.find<HomeController>(tag: 'success'), 57 expect(() => Get.find<HomeController>(tag: 'success'),
60 - throwsA(m.TypeMatcher<String>())); 58 + throwsA(const TypeMatcher<String>()));
61 59
62 /// binding will put the controller on memory 60 /// binding will put the controller on memory
63 binding.dependencies(); 61 binding.dependencies();
@@ -72,7 +70,7 @@ void main() { @@ -72,7 +70,7 @@ void main() {
72 expect(controller.status.isLoading, true); 70 expect(controller.status.isLoading, true);
73 71
74 /// await time request 72 /// await time request
75 - await Future.delayed(Duration(milliseconds: 100)); 73 + await Future.delayed(const Duration(milliseconds: 100));
76 74
77 /// test if status is success 75 /// test if status is success
78 expect(controller.status.isSuccess, true); 76 expect(controller.status.isSuccess, true);
1 // This is a generated file; do not edit or check into version control. 1 // This is a generated file; do not edit or check into version control.
2 FLUTTER_ROOT=/Users/jonatasborges/flutter 2 FLUTTER_ROOT=/Users/jonatasborges/flutter
3 -FLUTTER_APPLICATION_PATH=/Users/jonatasborges/consertar/getx/example_nav2 3 +FLUTTER_APPLICATION_PATH=/Users/jonatasborges/getx-parse/getx/example_nav2
4 COCOAPODS_PARALLEL_CODE_SIGN=true 4 COCOAPODS_PARALLEL_CODE_SIGN=true
5 -FLUTTER_TARGET=/Users/jonatasborges/consertar/getx/example_nav2/lib/main.dart 5 +FLUTTER_TARGET=lib/main.dart
6 FLUTTER_BUILD_DIR=build 6 FLUTTER_BUILD_DIR=build
7 FLUTTER_BUILD_NAME=1.0.0 7 FLUTTER_BUILD_NAME=1.0.0
8 FLUTTER_BUILD_NUMBER=1 8 FLUTTER_BUILD_NUMBER=1
9 EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386 9 EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386
10 EXCLUDED_ARCHS[sdk=iphoneos*]=armv7 10 EXCLUDED_ARCHS[sdk=iphoneos*]=armv7
11 -DART_DEFINES=RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==  
12 DART_OBFUSCATION=false 11 DART_OBFUSCATION=false
13 TRACK_WIDGET_CREATION=true 12 TRACK_WIDGET_CREATION=true
14 TREE_SHAKE_ICONS=false 13 TREE_SHAKE_ICONS=false
15 -PACKAGE_CONFIG=/Users/jonatasborges/consertar/getx/example_nav2/.dart_tool/package_config.json 14 +PACKAGE_CONFIG=.dart_tool/package_config.json
1 #!/bin/sh 1 #!/bin/sh
2 # This is a generated file; do not edit or check into version control. 2 # This is a generated file; do not edit or check into version control.
3 export "FLUTTER_ROOT=/Users/jonatasborges/flutter" 3 export "FLUTTER_ROOT=/Users/jonatasborges/flutter"
4 -export "FLUTTER_APPLICATION_PATH=/Users/jonatasborges/consertar/getx/example_nav2" 4 +export "FLUTTER_APPLICATION_PATH=/Users/jonatasborges/getx-parse/getx/example_nav2"
5 export "COCOAPODS_PARALLEL_CODE_SIGN=true" 5 export "COCOAPODS_PARALLEL_CODE_SIGN=true"
6 -export "FLUTTER_TARGET=/Users/jonatasborges/consertar/getx/example_nav2/lib/main.dart" 6 +export "FLUTTER_TARGET=lib/main.dart"
7 export "FLUTTER_BUILD_DIR=build" 7 export "FLUTTER_BUILD_DIR=build"
8 export "FLUTTER_BUILD_NAME=1.0.0" 8 export "FLUTTER_BUILD_NAME=1.0.0"
9 export "FLUTTER_BUILD_NUMBER=1" 9 export "FLUTTER_BUILD_NUMBER=1"
10 -export "DART_DEFINES=RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ=="  
11 export "DART_OBFUSCATION=false" 10 export "DART_OBFUSCATION=false"
12 export "TRACK_WIDGET_CREATION=true" 11 export "TRACK_WIDGET_CREATION=true"
13 export "TREE_SHAKE_ICONS=false" 12 export "TREE_SHAKE_ICONS=false"
14 -export "PACKAGE_CONFIG=/Users/jonatasborges/consertar/getx/example_nav2/.dart_tool/package_config.json" 13 +export "PACKAGE_CONFIG=.dart_tool/package_config.json"
@@ -8,7 +8,7 @@ class DashboardController extends GetxController { @@ -8,7 +8,7 @@ class DashboardController extends GetxController {
8 void onReady() { 8 void onReady() {
9 super.onReady(); 9 super.onReady();
10 Timer.periodic( 10 Timer.periodic(
11 - Duration(seconds: 1), 11 + const Duration(seconds: 1),
12 (timer) { 12 (timer) {
13 now.value = DateTime.now(); 13 now.value = DateTime.now();
14 }, 14 },
@@ -4,6 +4,8 @@ import 'package:get/get.dart'; @@ -4,6 +4,8 @@ import 'package:get/get.dart';
4 import '../controllers/dashboard_controller.dart'; 4 import '../controllers/dashboard_controller.dart';
5 5
6 class DashboardView extends GetView<DashboardController> { 6 class DashboardView extends GetView<DashboardController> {
  7 + const DashboardView({super.key});
  8 +
7 @override 9 @override
8 Widget build(BuildContext context) { 10 Widget build(BuildContext context) {
9 return Scaffold( 11 return Scaffold(
@@ -12,7 +14,7 @@ class DashboardView extends GetView<DashboardController> { @@ -12,7 +14,7 @@ class DashboardView extends GetView<DashboardController> {
12 () => Column( 14 () => Column(
13 mainAxisSize: MainAxisSize.min, 15 mainAxisSize: MainAxisSize.min,
14 children: [ 16 children: [
15 - Text( 17 + const Text(
16 'DashboardView is working', 18 'DashboardView is working',
17 style: TextStyle(fontSize: 20), 19 style: TextStyle(fontSize: 20),
18 ), 20 ),
@@ -14,7 +14,6 @@ class HomeView extends GetView<HomeController> { @@ -14,7 +14,6 @@ class HomeView extends GetView<HomeController> {
14 final delegate = context.navigation; 14 final delegate = context.navigation;
15 //This router outlet handles the appbar and the bottom navigation bar 15 //This router outlet handles the appbar and the bottom navigation bar
16 final currentLocation = context.location; 16 final currentLocation = context.location;
17 - print(currentLocation);  
18 var currentIndex = 0; 17 var currentIndex = 0;
19 if (currentLocation.startsWith(Routes.products) == true) { 18 if (currentLocation.startsWith(Routes.products) == true) {
20 currentIndex = 2; 19 currentIndex = 2;
@@ -46,7 +45,7 @@ class HomeView extends GetView<HomeController> { @@ -46,7 +45,7 @@ class HomeView extends GetView<HomeController> {
46 default: 45 default:
47 } 46 }
48 }, 47 },
49 - items: [ 48 + items: const [
50 // _Paths.HOME + [Empty] 49 // _Paths.HOME + [Empty]
51 BottomNavigationBarItem( 50 BottomNavigationBarItem(
52 icon: Icon(Icons.home), 51 icon: Icon(Icons.home),
@@ -6,6 +6,8 @@ import '../../../routes/app_pages.dart'; @@ -6,6 +6,8 @@ import '../../../routes/app_pages.dart';
6 import '../controllers/login_controller.dart'; 6 import '../controllers/login_controller.dart';
7 7
8 class LoginView extends GetView<LoginController> { 8 class LoginView extends GetView<LoginController> {
  9 + const LoginView({super.key});
  10 +
9 @override 11 @override
10 Widget build(BuildContext context) { 12 Widget build(BuildContext context) {
11 return Scaffold( 13 return Scaffold(
@@ -25,7 +27,7 @@ class LoginView extends GetView<LoginController> { @@ -25,7 +27,7 @@ class LoginView extends GetView<LoginController> {
25 }, 27 },
26 ), 28 ),
27 MaterialButton( 29 MaterialButton(
28 - child: Text( 30 + child: const Text(
29 'Do LOGIN !!', 31 'Do LOGIN !!',
30 style: TextStyle(color: Colors.blue, fontSize: 20), 32 style: TextStyle(color: Colors.blue, fontSize: 20),
31 ), 33 ),
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 -  
3 import 'package:get/get.dart'; 2 import 'package:get/get.dart';
4 3
5 import '../controllers/product_details_controller.dart'; 4 import '../controllers/product_details_controller.dart';
6 5
7 class ProductDetailsView extends GetWidget<ProductDetailsController> { 6 class ProductDetailsView extends GetWidget<ProductDetailsController> {
  7 + const ProductDetailsView({super.key});
  8 +
8 @override 9 @override
9 Widget build(BuildContext context) { 10 Widget build(BuildContext context) {
10 return Scaffold( 11 return Scaffold(
@@ -12,7 +13,7 @@ class ProductDetailsView extends GetWidget<ProductDetailsController> { @@ -12,7 +13,7 @@ class ProductDetailsView extends GetWidget<ProductDetailsController> {
12 child: Column( 13 child: Column(
13 mainAxisSize: MainAxisSize.min, 14 mainAxisSize: MainAxisSize.min,
14 children: [ 15 children: [
15 - Text( 16 + const Text(
16 'ProductDetailsView is working', 17 'ProductDetailsView is working',
17 style: TextStyle(fontSize: 20), 18 style: TextStyle(fontSize: 20),
18 ), 19 ),
@@ -11,13 +11,13 @@ class ProductsView extends GetView<ProductsController> { @@ -11,13 +11,13 @@ class ProductsView extends GetView<ProductsController> {
11 return Scaffold( 11 return Scaffold(
12 floatingActionButton: FloatingActionButton.extended( 12 floatingActionButton: FloatingActionButton.extended(
13 onPressed: () => controller.loadDemoProductsFromSomeWhere(), 13 onPressed: () => controller.loadDemoProductsFromSomeWhere(),
14 - label: Text('Add'), 14 + label: const Text('Add'),
15 ), 15 ),
16 body: Column( 16 body: Column(
17 children: [ 17 children: [
18 - Hero( 18 + const Hero(
19 tag: 'heroLogo', 19 tag: 'heroLogo',
20 - child: const FlutterLogo(), 20 + child: FlutterLogo(),
21 ), 21 ),
22 Expanded( 22 Expanded(
23 child: Obx( 23 child: Obx(
@@ -5,6 +5,8 @@ import '../../../routes/app_pages.dart'; @@ -5,6 +5,8 @@ import '../../../routes/app_pages.dart';
5 import '../controllers/profile_controller.dart'; 5 import '../controllers/profile_controller.dart';
6 6
7 class ProfileView extends GetView<ProfileController> { 7 class ProfileView extends GetView<ProfileController> {
  8 + const ProfileView({super.key});
  9 +
8 @override 10 @override
9 Widget build(BuildContext context) { 11 Widget build(BuildContext context) {
10 return Scaffold( 12 return Scaffold(
@@ -13,16 +15,16 @@ class ProfileView extends GetView<ProfileController> { @@ -13,16 +15,16 @@ class ProfileView extends GetView<ProfileController> {
13 child: Column( 15 child: Column(
14 mainAxisSize: MainAxisSize.min, 16 mainAxisSize: MainAxisSize.min,
15 children: [ 17 children: [
16 - Text( 18 + const Text(
17 'ProfileView is working', 19 'ProfileView is working',
18 style: TextStyle(fontSize: 20), 20 style: TextStyle(fontSize: 20),
19 ), 21 ),
20 - Hero( 22 + const Hero(
21 tag: 'heroLogo', 23 tag: 'heroLogo',
22 - child: const FlutterLogo(), 24 + child: FlutterLogo(),
23 ), 25 ),
24 MaterialButton( 26 MaterialButton(
25 - child: Text('Show a test dialog'), 27 + child: const Text('Show a test dialog'),
26 onPressed: () { 28 onPressed: () {
27 //shows a dialog 29 //shows a dialog
28 Get.defaultDialog( 30 Get.defaultDialog(
@@ -32,7 +34,7 @@ class ProfileView extends GetView<ProfileController> { @@ -32,7 +34,7 @@ class ProfileView extends GetView<ProfileController> {
32 }, 34 },
33 ), 35 ),
34 MaterialButton( 36 MaterialButton(
35 - child: Text('Show a test dialog in Home router outlet'), 37 + child: const Text('Show a test dialog in Home router outlet'),
36 onPressed: () { 38 onPressed: () {
37 //shows a dialog 39 //shows a dialog
38 40
@@ -10,11 +10,6 @@ class RootController extends GetxController { @@ -10,11 +10,6 @@ class RootController extends GetxController {
10 } 10 }
11 11
12 @override 12 @override
13 - void onReady() {  
14 - super.onReady();  
15 - }  
16 -  
17 - @override  
18 void onClose() {} 13 void onClose() {}
19 void increment() => count.value++; 14 void increment() => count.value++;
20 } 15 }
@@ -19,7 +19,7 @@ class DrawerWidget extends StatelessWidget { @@ -19,7 +19,7 @@ class DrawerWidget extends StatelessWidget {
19 color: Colors.red, 19 color: Colors.red,
20 ), 20 ),
21 ListTile( 21 ListTile(
22 - title: Text('Home'), 22 + title: const Text('Home'),
23 onTap: () { 23 onTap: () {
24 Get.toNamed(Routes.home); 24 Get.toNamed(Routes.home);
25 //to close the drawer 25 //to close the drawer
@@ -28,7 +28,7 @@ class DrawerWidget extends StatelessWidget { @@ -28,7 +28,7 @@ class DrawerWidget extends StatelessWidget {
28 }, 28 },
29 ), 29 ),
30 ListTile( 30 ListTile(
31 - title: Text('Settings'), 31 + title: const Text('Settings'),
32 onTap: () { 32 onTap: () {
33 Get.toNamed(Routes.settings); 33 Get.toNamed(Routes.settings);
34 //to close the drawer 34 //to close the drawer
@@ -38,7 +38,7 @@ class DrawerWidget extends StatelessWidget { @@ -38,7 +38,7 @@ class DrawerWidget extends StatelessWidget {
38 ), 38 ),
39 if (AuthService.to.isLoggedInValue) 39 if (AuthService.to.isLoggedInValue)
40 ListTile( 40 ListTile(
41 - title: Text( 41 + title: const Text(
42 'Logout', 42 'Logout',
43 style: TextStyle( 43 style: TextStyle(
44 color: Colors.red, 44 color: Colors.red,
@@ -54,7 +54,7 @@ class DrawerWidget extends StatelessWidget { @@ -54,7 +54,7 @@ class DrawerWidget extends StatelessWidget {
54 ), 54 ),
55 if (!AuthService.to.isLoggedInValue) 55 if (!AuthService.to.isLoggedInValue)
56 ListTile( 56 ListTile(
57 - title: Text( 57 + title: const Text(
58 'Login', 58 'Login',
59 style: TextStyle( 59 style: TextStyle(
60 color: Colors.blue, 60 color: Colors.blue,
@@ -6,6 +6,8 @@ import '../controllers/root_controller.dart'; @@ -6,6 +6,8 @@ import '../controllers/root_controller.dart';
6 import 'drawer.dart'; 6 import 'drawer.dart';
7 7
8 class RootView extends GetView<RootController> { 8 class RootView extends GetView<RootController> {
  9 + const RootView({super.key});
  10 +
9 @override 11 @override
10 Widget build(BuildContext context) { 12 Widget build(BuildContext context) {
11 return RouterOutlet.builder( 13 return RouterOutlet.builder(
@@ -13,7 +15,7 @@ class RootView extends GetView<RootController> { @@ -13,7 +15,7 @@ class RootView extends GetView<RootController> {
13 builder: (context) { 15 builder: (context) {
14 final title = context.location; 16 final title = context.location;
15 return Scaffold( 17 return Scaffold(
16 - drawer: DrawerWidget(), 18 + drawer: const DrawerWidget(),
17 appBar: AppBar( 19 appBar: AppBar(
18 title: Text(title), 20 title: Text(title),
19 centerTitle: true, 21 centerTitle: true,
@@ -10,11 +10,6 @@ class SettingsController extends GetxController { @@ -10,11 +10,6 @@ class SettingsController extends GetxController {
10 } 10 }
11 11
12 @override 12 @override
13 - void onReady() {  
14 - super.onReady();  
15 - }  
16 -  
17 - @override  
18 void onClose() {} 13 void onClose() {}
19 void increment() => count.value++; 14 void increment() => count.value++;
20 } 15 }
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 -  
3 import 'package:get/get.dart'; 2 import 'package:get/get.dart';
4 3
5 import '../controllers/settings_controller.dart'; 4 import '../controllers/settings_controller.dart';
6 5
7 class SettingsView extends GetView<SettingsController> { 6 class SettingsView extends GetView<SettingsController> {
  7 + const SettingsView({super.key});
  8 +
8 @override 9 @override
9 Widget build(BuildContext context) { 10 Widget build(BuildContext context) {
10 - return Scaffold( 11 + return const Scaffold(
11 body: Center( 12 body: Center(
12 child: Text( 13 child: Text(
13 'SettingsView is working', 14 'SettingsView is working',
@@ -18,11 +18,11 @@ class SplashService extends GetxService { @@ -18,11 +18,11 @@ class SplashService extends GetxService {
18 18
19 Future<void> _initFunction() async { 19 Future<void> _initFunction() async {
20 final t = Timer.periodic( 20 final t = Timer.periodic(
21 - Duration(milliseconds: 500), 21 + const Duration(milliseconds: 500),
22 (t) => _changeActiveString(), 22 (t) => _changeActiveString(),
23 ); 23 );
24 //simulate some long running operation 24 //simulate some long running operation
25 - await Future.delayed(Duration(seconds: 5)); 25 + await Future.delayed(const Duration(seconds: 5));
26 //cancel the timer once we are done 26 //cancel the timer once we are done
27 t.cancel(); 27 t.cancel();
28 } 28 }
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 -  
3 import 'package:get/get.dart'; 2 import 'package:get/get.dart';
4 3
5 import '../controllers/splash_service.dart'; 4 import '../controllers/splash_service.dart';
6 5
7 class SplashView extends GetView<SplashService> { 6 class SplashView extends GetView<SplashService> {
  7 + const SplashView({super.key});
  8 +
8 @override 9 @override
9 Widget build(BuildContext context) { 10 Widget build(BuildContext context) {
10 return Scaffold( 11 return Scaffold(
@@ -15,10 +16,10 @@ class SplashView extends GetView<SplashService> { @@ -15,10 +16,10 @@ class SplashView extends GetView<SplashService> {
15 Obx( 16 Obx(
16 () => Text( 17 () => Text(
17 controller.welcomeStr[controller.activeStr.value], 18 controller.welcomeStr[controller.activeStr.value],
18 - style: TextStyle(fontSize: 20), 19 + style: const TextStyle(fontSize: 20),
19 ), 20 ),
20 ), 21 ),
21 - CircularProgressIndicator(), 22 + const CircularProgressIndicator(),
22 ], 23 ],
23 ), 24 ),
24 ), 25 ),
@@ -28,7 +28,7 @@ class AppPages { @@ -28,7 +28,7 @@ class AppPages {
28 static final routes = [ 28 static final routes = [
29 GetPage( 29 GetPage(
30 name: '/', 30 name: '/',
31 - page: () => RootView(), 31 + page: () => const RootView(),
32 bindings: [RootBinding()], 32 bindings: [RootBinding()],
33 participatesInRootNavigator: true, 33 participatesInRootNavigator: true,
34 preventDuplicates: true, 34 preventDuplicates: true,
@@ -39,7 +39,7 @@ class AppPages { @@ -39,7 +39,7 @@ class AppPages {
39 EnsureNotAuthedMiddleware(), 39 EnsureNotAuthedMiddleware(),
40 ], 40 ],
41 name: _Paths.login, 41 name: _Paths.login,
42 - page: () => LoginView(), 42 + page: () => const LoginView(),
43 bindings: [LoginBinding()], 43 bindings: [LoginBinding()],
44 ), 44 ),
45 GetPage( 45 GetPage(
@@ -53,7 +53,7 @@ class AppPages { @@ -53,7 +53,7 @@ class AppPages {
53 children: [ 53 children: [
54 GetPage( 54 GetPage(
55 name: _Paths.dashboard, 55 name: _Paths.dashboard,
56 - page: () => DashboardView(), 56 + page: () => const DashboardView(),
57 bindings: [ 57 bindings: [
58 DashboardBinding(), 58 DashboardBinding(),
59 ], 59 ],
@@ -64,7 +64,7 @@ class AppPages { @@ -64,7 +64,7 @@ class AppPages {
64 EnsureAuthMiddleware(), 64 EnsureAuthMiddleware(),
65 ], 65 ],
66 name: _Paths.profile, 66 name: _Paths.profile,
67 - page: () => ProfileView(), 67 + page: () => const ProfileView(),
68 title: 'Profile', 68 title: 'Profile',
69 transition: Transition.size, 69 transition: Transition.size,
70 bindings: [ProfileBinding()], 70 bindings: [ProfileBinding()],
@@ -82,8 +82,8 @@ class AppPages { @@ -82,8 +82,8 @@ class AppPages {
82 name: _Paths.productDetails, 82 name: _Paths.productDetails,
83 transition: Transition.cupertino, 83 transition: Transition.cupertino,
84 showCupertinoParallax: true, 84 showCupertinoParallax: true,
85 - page: () => ProductDetailsView(),  
86 - bindings: [], 85 + page: () => const ProductDetailsView(),
  86 + bindings: const [],
87 middlewares: [ 87 middlewares: [
88 //only enter this route when authed 88 //only enter this route when authed
89 EnsureAuthMiddleware(), 89 EnsureAuthMiddleware(),
@@ -95,7 +95,7 @@ class AppPages { @@ -95,7 +95,7 @@ class AppPages {
95 ), 95 ),
96 GetPage( 96 GetPage(
97 name: _Paths.settings, 97 name: _Paths.settings,
98 - page: () => SettingsView(), 98 + page: () => const SettingsView(),
99 bindings: [ 99 bindings: [
100 SettingsBinding(), 100 SettingsBinding(),
101 ], 101 ],
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 /// injection, and route management in a quick and practical way. 3 /// injection, and route management in a quick and practical way.
4 library get; 4 library get;
5 5
  6 +export 'get_animations/index.dart';
6 export 'get_common/get_reset.dart'; 7 export 'get_common/get_reset.dart';
7 export 'get_connect/connect.dart'; 8 export 'get_connect/connect.dart';
8 export 'get_core/get_core.dart'; 9 export 'get_core/get_core.dart';
  1 +import 'dart:math';
  2 +import 'dart:ui';
  3 +
  4 +import 'package:flutter/widgets.dart';
  5 +
  6 +import 'get_animated_builder.dart';
  7 +
  8 +typedef OffsetBuilder = Offset Function(BuildContext, double);
  9 +
  10 +class FadeInAnimation extends OpacityAnimation {
  11 + FadeInAnimation({
  12 + super.key,
  13 + required super.duration,
  14 + required super.delay,
  15 + required super.child,
  16 + super.onComplete,
  17 + super.begin = 0,
  18 + super.end = 1,
  19 + super.idleValue = 0,
  20 + });
  21 +}
  22 +
  23 +class FadeOutAnimation extends OpacityAnimation {
  24 + FadeOutAnimation({
  25 + super.key,
  26 + required super.duration,
  27 + required super.delay,
  28 + required super.child,
  29 + super.onComplete,
  30 + super.begin = 1,
  31 + super.end = 0,
  32 + super.idleValue = 1,
  33 + });
  34 +}
  35 +
  36 +class OpacityAnimation extends GetAnimatedBuilder<double> {
  37 + OpacityAnimation({
  38 + super.key,
  39 + required super.duration,
  40 + required super.delay,
  41 + required super.child,
  42 + required super.onComplete,
  43 + required double begin,
  44 + required double end,
  45 + required super.idleValue,
  46 + }) : super(
  47 + tween: Tween<double>(begin: begin, end: end),
  48 + builder: (context, value, child) {
  49 + return Opacity(
  50 + opacity: value,
  51 + child: child!,
  52 + );
  53 + },
  54 + );
  55 +}
  56 +
  57 +class RotateAnimation extends GetAnimatedBuilder<double> {
  58 + RotateAnimation({
  59 + super.key,
  60 + required super.duration,
  61 + required super.delay,
  62 + required super.child,
  63 + super.onComplete,
  64 + required double begin,
  65 + required double end,
  66 + super.idleValue = 0,
  67 + }) : super(
  68 + builder: (context, value, child) => Transform.rotate(
  69 + angle: value,
  70 + child: child,
  71 + ),
  72 + tween: Tween<double>(begin: begin, end: end),
  73 + );
  74 +}
  75 +
  76 +class ScaleAnimation extends GetAnimatedBuilder<double> {
  77 + ScaleAnimation({
  78 + super.key,
  79 + required super.duration,
  80 + required super.delay,
  81 + required super.child,
  82 + super.onComplete,
  83 + required double begin,
  84 + required double end,
  85 + super.idleValue = 0,
  86 + }) : super(
  87 + builder: (context, value, child) => Transform.scale(
  88 + scale: value,
  89 + child: child,
  90 + ),
  91 + tween: Tween<double>(begin: begin, end: end),
  92 + );
  93 +}
  94 +
  95 +// class SlideAnimation extends GetAnimatedBuilder<Offset> {
  96 +// SlideAnimation({
  97 +// super.key,
  98 +// required super.duration,
  99 +// required super.delay,
  100 +// required super.child,
  101 +// super.onComplete,
  102 +// required Offset begin,
  103 +// required Offset end,
  104 +// super.idleValue = const Offset(0, 0),
  105 +// }) : super(
  106 +// builder: (context, value, child) => Transform.translate(
  107 +// offset: value,
  108 +// child: child,
  109 +// ),
  110 +// tween: Tween(begin: begin, end: end),
  111 +// );
  112 +// }
  113 +
  114 +class BounceAnimation extends GetAnimatedBuilder<double> {
  115 + BounceAnimation({
  116 + super.key,
  117 + required super.duration,
  118 + required super.delay,
  119 + required super.child,
  120 + super.onComplete,
  121 + super.curve = Curves.bounceOut,
  122 + required double begin,
  123 + required double end,
  124 + super.idleValue = 0,
  125 + }) : super(
  126 + builder: (context, value, child) => Transform.scale(
  127 + scale: 1 + value.abs(),
  128 + child: child,
  129 + ),
  130 + tween: Tween<double>(begin: begin, end: end),
  131 + );
  132 +}
  133 +
  134 +class SpinAnimation extends GetAnimatedBuilder<double> {
  135 + SpinAnimation({
  136 + super.key,
  137 + required super.duration,
  138 + required super.delay,
  139 + required super.child,
  140 + super.onComplete,
  141 + super.idleValue = 0,
  142 + }) : super(
  143 + builder: (context, value, child) => Transform.rotate(
  144 + angle: value * pi / 180.0,
  145 + child: child,
  146 + ),
  147 + tween: Tween<double>(begin: 0, end: 360),
  148 + );
  149 +}
  150 +
  151 +class SizeAnimation extends GetAnimatedBuilder<double> {
  152 + SizeAnimation({
  153 + super.key,
  154 + required super.duration,
  155 + required super.delay,
  156 + required super.child,
  157 + super.onComplete,
  158 + super.idleValue = 0,
  159 + required double begin,
  160 + required double end,
  161 + }) : super(
  162 + builder: (context, value, child) => Transform.scale(
  163 + scale: value,
  164 + child: child,
  165 + ),
  166 + tween: Tween<double>(begin: begin, end: end),
  167 + );
  168 +}
  169 +
  170 +class BlurAnimation extends GetAnimatedBuilder<double> {
  171 + BlurAnimation({
  172 + super.key,
  173 + required super.duration,
  174 + required super.delay,
  175 + required super.child,
  176 + super.onComplete,
  177 + required double begin,
  178 + required double end,
  179 + super.idleValue = 0,
  180 + }) : super(
  181 + builder: (context, value, child) => BackdropFilter(
  182 + filter: ImageFilter.blur(
  183 + sigmaX: value,
  184 + sigmaY: value,
  185 + ),
  186 + child: child,
  187 + ),
  188 + tween: Tween<double>(begin: begin, end: end),
  189 + );
  190 +}
  191 +
  192 +class FlipAnimation extends GetAnimatedBuilder<double> {
  193 + FlipAnimation({
  194 + super.key,
  195 + required super.duration,
  196 + required super.delay,
  197 + required super.child,
  198 + super.onComplete,
  199 + required double begin,
  200 + required double end,
  201 + super.idleValue = 0,
  202 + }) : super(
  203 + builder: (context, value, child) {
  204 + final radians = value * pi;
  205 + return Transform(
  206 + transform: Matrix4.rotationY(radians),
  207 + alignment: Alignment.center,
  208 + child: child,
  209 + );
  210 + },
  211 + tween: Tween<double>(begin: begin, end: end),
  212 + );
  213 +}
  214 +
  215 +class WaveAnimation extends GetAnimatedBuilder<double> {
  216 + WaveAnimation({
  217 + super.key,
  218 + required super.duration,
  219 + required super.delay,
  220 + required super.child,
  221 + super.onComplete,
  222 + required double begin,
  223 + required double end,
  224 + super.idleValue = 0,
  225 + }) : super(
  226 + builder: (context, value, child) => Transform(
  227 + transform: Matrix4.translationValues(
  228 + 0.0,
  229 + 20.0 * sin(value * pi * 2),
  230 + 0.0,
  231 + ),
  232 + child: child,
  233 + ),
  234 + tween: Tween<double>(begin: begin, end: end),
  235 + );
  236 +}
  237 +
  238 +class WobbleAnimation extends GetAnimatedBuilder<double> {
  239 + WobbleAnimation({
  240 + super.key,
  241 + required super.duration,
  242 + required super.delay,
  243 + required super.child,
  244 + super.onComplete,
  245 + required double begin,
  246 + required double end,
  247 + super.idleValue = 0,
  248 + }) : super(
  249 + builder: (context, value, child) => Transform(
  250 + transform: Matrix4.identity()
  251 + ..setEntry(3, 2, 0.001)
  252 + ..rotateZ(sin(value * pi * 2) * 0.1),
  253 + alignment: Alignment.center,
  254 + child: child,
  255 + ),
  256 + tween: Tween<double>(begin: begin, end: end),
  257 + );
  258 +}
  259 +
  260 +class SlideInLeftAnimation extends SlideAnimation {
  261 + SlideInLeftAnimation({
  262 + super.key,
  263 + required super.duration,
  264 + required super.delay,
  265 + required super.child,
  266 + super.onComplete,
  267 + required super.begin,
  268 + required super.end,
  269 + super.idleValue = 0,
  270 + }) : super(
  271 + offsetBuild: (context, value) =>
  272 + Offset(value * MediaQuery.of(context).size.width, 0),
  273 + );
  274 +}
  275 +
  276 +class SlideInRightAnimation extends SlideAnimation {
  277 + SlideInRightAnimation({
  278 + super.key,
  279 + required super.duration,
  280 + required super.delay,
  281 + required super.child,
  282 + super.onComplete,
  283 + required super.begin,
  284 + required super.end,
  285 + super.idleValue = 0,
  286 + }) : super(
  287 + offsetBuild: (context, value) =>
  288 + Offset((1 - value) * MediaQuery.of(context).size.width, 0),
  289 + );
  290 +}
  291 +
  292 +class SlideInUpAnimation extends SlideAnimation {
  293 + SlideInUpAnimation({
  294 + super.key,
  295 + required super.duration,
  296 + required super.delay,
  297 + required super.child,
  298 + super.onComplete,
  299 + required super.begin,
  300 + required super.end,
  301 + super.idleValue = 0,
  302 + }) : super(
  303 + offsetBuild: (context, value) =>
  304 + Offset(0, value * MediaQuery.of(context).size.height),
  305 + );
  306 +}
  307 +
  308 +class SlideInDownAnimation extends SlideAnimation {
  309 + SlideInDownAnimation({
  310 + super.key,
  311 + required super.duration,
  312 + required super.delay,
  313 + required super.child,
  314 + super.onComplete,
  315 + required super.begin,
  316 + required super.end,
  317 + super.idleValue = 0,
  318 + }) : super(
  319 + offsetBuild: (context, value) =>
  320 + Offset(0, (1 - value) * MediaQuery.of(context).size.height),
  321 + );
  322 +}
  323 +
  324 +class SlideAnimation extends GetAnimatedBuilder<double> {
  325 + SlideAnimation({
  326 + super.key,
  327 + required super.duration,
  328 + required super.delay,
  329 + required super.child,
  330 + required double begin,
  331 + required double end,
  332 + required OffsetBuilder offsetBuild,
  333 + super.onComplete,
  334 + super.idleValue = 0,
  335 + }) : super(
  336 + builder: (context, value, child) => Transform.translate(
  337 + offset: offsetBuild(context, value),
  338 + child: child,
  339 + ),
  340 + tween: Tween<double>(begin: begin, end: end),
  341 + );
  342 +}
  343 +
  344 +// class ZoomAnimation extends GetAnimatedBuilder<double> {
  345 +// ZoomAnimation({
  346 +// super.key,
  347 +// required super.duration,
  348 +// required super.delay,
  349 +// required super.child,
  350 +// super.onComplete,
  351 +// required double begin,
  352 +// required double end,
  353 +// super.idleValue = 0,
  354 +// }) : super(
  355 +// builder: (context, value, child) => Transform.scale(
  356 +// scale: lerpDouble(1, end, value)!,
  357 +// child: child,
  358 +// ),
  359 +// tween: Tween<double>(begin: begin, end: end),
  360 +// );
  361 +// }
  362 +
  363 +class ColorAnimation extends GetAnimatedBuilder<Color?> {
  364 + ColorAnimation({
  365 + super.key,
  366 + required super.duration,
  367 + required super.delay,
  368 + required super.child,
  369 + super.onComplete,
  370 + required Color begin,
  371 + required Color end,
  372 + Color? idleColor,
  373 + }) : super(
  374 + builder: (context, value, child) => ColorFiltered(
  375 + colorFilter: ColorFilter.mode(
  376 + Color.lerp(begin, end, value!.value.toDouble())!,
  377 + BlendMode.srcIn,
  378 + ),
  379 + child: child,
  380 + ),
  381 + idleValue: idleColor ?? begin,
  382 + tween: ColorTween(begin: begin, end: end),
  383 + );
  384 +}
  1 +import 'package:flutter/material.dart';
  2 +
  3 +import 'animations.dart';
  4 +import 'get_animated_builder.dart';
  5 +
  6 +const _defaultDuration = Duration(seconds: 2);
  7 +const _defaultDelay = Duration.zero;
  8 +
  9 +extension AnimationExtension on Widget {
  10 + GetAnimatedBuilder? get _currentAnimation =>
  11 + (this is GetAnimatedBuilder) ? this as GetAnimatedBuilder : null;
  12 +
  13 + GetAnimatedBuilder fadeIn({
  14 + Duration duration = _defaultDuration,
  15 + Duration delay = _defaultDelay,
  16 + ValueSetter<AnimationController>? onComplete,
  17 + bool isSequential = false,
  18 + }) {
  19 + assert(isSequential || this is! FadeOutAnimation,
  20 + 'Can not use fadeOut + fadeIn when isSequential is false');
  21 +
  22 + return FadeInAnimation(
  23 + duration: duration,
  24 + delay: _getDelay(isSequential, delay),
  25 + onComplete: onComplete,
  26 + child: this,
  27 + );
  28 + }
  29 +
  30 + GetAnimatedBuilder fadeOut({
  31 + Duration duration = _defaultDuration,
  32 + Duration delay = _defaultDelay,
  33 + ValueSetter<AnimationController>? onComplete,
  34 + bool isSequential = false,
  35 + }) {
  36 + assert(isSequential || this is! FadeInAnimation,
  37 + 'Can not use fadeOut() + fadeIn when isSequential is false');
  38 +
  39 + return FadeOutAnimation(
  40 + duration: duration,
  41 + delay: _getDelay(isSequential, delay),
  42 + onComplete: onComplete,
  43 + child: this,
  44 + );
  45 + }
  46 +
  47 + GetAnimatedBuilder rotate({
  48 + required double begin,
  49 + required double end,
  50 + Duration duration = _defaultDuration,
  51 + Duration delay = _defaultDelay,
  52 + ValueSetter<AnimationController>? onComplete,
  53 + bool isSequential = false,
  54 + }) {
  55 + return RotateAnimation(
  56 + duration: duration,
  57 + delay: _getDelay(isSequential, delay),
  58 + begin: begin,
  59 + end: end,
  60 + onComplete: onComplete,
  61 + child: this,
  62 + );
  63 + }
  64 +
  65 + GetAnimatedBuilder scale({
  66 + required double begin,
  67 + required double end,
  68 + Duration duration = _defaultDuration,
  69 + Duration delay = _defaultDelay,
  70 + ValueSetter<AnimationController>? onComplete,
  71 + bool isSequential = false,
  72 + }) {
  73 + return ScaleAnimation(
  74 + duration: duration,
  75 + delay: _getDelay(isSequential, delay),
  76 + begin: begin,
  77 + end: end,
  78 + onComplete: onComplete,
  79 + child: this,
  80 + );
  81 + }
  82 +
  83 + GetAnimatedBuilder slide({
  84 + required OffsetBuilder offset,
  85 + double begin = 0,
  86 + double end = 1,
  87 + Duration duration = _defaultDuration,
  88 + Duration delay = _defaultDelay,
  89 + ValueSetter<AnimationController>? onComplete,
  90 + bool isSequential = false,
  91 + }) {
  92 + return SlideAnimation(
  93 + duration: duration,
  94 + delay: _getDelay(isSequential, delay),
  95 + begin: begin,
  96 + end: end,
  97 + onComplete: onComplete,
  98 + offsetBuild: offset,
  99 + child: this,
  100 + );
  101 + }
  102 +
  103 + GetAnimatedBuilder bounce({
  104 + required double begin,
  105 + required double end,
  106 + Duration duration = _defaultDuration,
  107 + Duration delay = _defaultDelay,
  108 + ValueSetter<AnimationController>? onComplete,
  109 + bool isSequential = false,
  110 + }) {
  111 + return BounceAnimation(
  112 + duration: duration,
  113 + delay: _getDelay(isSequential, delay),
  114 + begin: begin,
  115 + end: end,
  116 + onComplete: onComplete,
  117 + child: this,
  118 + );
  119 + }
  120 +
  121 + GetAnimatedBuilder spin({
  122 + Duration duration = _defaultDuration,
  123 + Duration delay = _defaultDelay,
  124 + ValueSetter<AnimationController>? onComplete,
  125 + bool isSequential = false,
  126 + }) {
  127 + return SpinAnimation(
  128 + duration: duration,
  129 + delay: _getDelay(isSequential, delay),
  130 + onComplete: onComplete,
  131 + child: this,
  132 + );
  133 + }
  134 +
  135 + GetAnimatedBuilder size({
  136 + required double begin,
  137 + required double end,
  138 + Duration duration = _defaultDuration,
  139 + Duration delay = _defaultDelay,
  140 + ValueSetter<AnimationController>? onComplete,
  141 + bool isSequential = false,
  142 + }) {
  143 + return SizeAnimation(
  144 + duration: duration,
  145 + delay: _getDelay(isSequential, delay),
  146 + begin: begin,
  147 + end: end,
  148 + onComplete: onComplete,
  149 + child: this,
  150 + );
  151 + }
  152 +
  153 + GetAnimatedBuilder blur({
  154 + double begin = 0,
  155 + double end = 15,
  156 + Duration duration = _defaultDuration,
  157 + Duration delay = _defaultDelay,
  158 + ValueSetter<AnimationController>? onComplete,
  159 + bool isSequential = false,
  160 + }) {
  161 + return BlurAnimation(
  162 + duration: duration,
  163 + delay: _getDelay(isSequential, delay),
  164 + begin: begin,
  165 + end: end,
  166 + onComplete: onComplete,
  167 + child: this,
  168 + );
  169 + }
  170 +
  171 + GetAnimatedBuilder flip({
  172 + double begin = 0,
  173 + double end = 1,
  174 + Duration duration = _defaultDuration,
  175 + Duration delay = _defaultDelay,
  176 + ValueSetter<AnimationController>? onComplete,
  177 + bool isSequential = false,
  178 + }) {
  179 + return FlipAnimation(
  180 + duration: duration,
  181 + delay: _getDelay(isSequential, delay),
  182 + begin: begin,
  183 + end: end,
  184 + onComplete: onComplete,
  185 + child: this,
  186 + );
  187 + }
  188 +
  189 + GetAnimatedBuilder wave({
  190 + double begin = 0,
  191 + double end = 1,
  192 + Duration duration = _defaultDuration,
  193 + Duration delay = _defaultDelay,
  194 + ValueSetter<AnimationController>? onComplete,
  195 + bool isSequential = false,
  196 + }) {
  197 + return WaveAnimation(
  198 + duration: duration,
  199 + delay: _getDelay(isSequential, delay),
  200 + begin: begin,
  201 + end: end,
  202 + onComplete: onComplete,
  203 + child: this,
  204 + );
  205 + }
  206 +
  207 + Duration _getDelay(bool isSequential, Duration delay) {
  208 + assert(!(isSequential && delay != Duration.zero),
  209 + "Error: When isSequential is true, delay must be non-zero. Context: isSequential: $isSequential delay: $delay");
  210 +
  211 + return isSequential
  212 + ? (_currentAnimation?.totalDuration ?? Duration.zero)
  213 + : delay;
  214 + }
  215 +}
  1 +import 'package:flutter/material.dart';
  2 +
  3 +import 'animations.dart';
  4 +
  5 +class GetAnimatedBuilder<T> extends StatefulWidget {
  6 + final Duration duration;
  7 + final Duration delay;
  8 + final Widget child;
  9 + final ValueSetter<AnimationController>? onComplete;
  10 + final ValueSetter<AnimationController>? onStart;
  11 + final Tween<T> tween;
  12 + final T idleValue;
  13 + final ValueWidgetBuilder<T> builder;
  14 + final Curve curve;
  15 +
  16 + Duration get totalDuration => duration + delay;
  17 +
  18 + const GetAnimatedBuilder({
  19 + super.key,
  20 + this.curve = Curves.linear,
  21 + this.onComplete,
  22 + this.onStart,
  23 + required this.duration,
  24 + required this.tween,
  25 + required this.idleValue,
  26 + required this.builder,
  27 + required this.child,
  28 + required this.delay,
  29 + });
  30 + @override
  31 + GetAnimatedBuilderState<T> createState() => GetAnimatedBuilderState<T>();
  32 +}
  33 +
  34 +class GetAnimatedBuilderState<T> extends State<GetAnimatedBuilder<T>>
  35 + with SingleTickerProviderStateMixin {
  36 + late final AnimationController _controller;
  37 + late final Animation<T> _animation;
  38 +
  39 + // AnimationController get controller => _controller;
  40 + // Animation<T> get animation => _animation;
  41 +
  42 + bool _wasStarted = false;
  43 + // bool get wasStarted => _wasStarted;
  44 +
  45 + late T _idleValue;
  46 +
  47 + bool _willResetOnDispose = false;
  48 +
  49 + bool get willResetOnDispose => _willResetOnDispose;
  50 +
  51 + void _listener(AnimationStatus status) {
  52 + switch (status) {
  53 + case AnimationStatus.completed:
  54 + widget.onComplete?.call(_controller);
  55 + if (_willResetOnDispose) {
  56 + _controller.reset();
  57 + }
  58 + break;
  59 + // case AnimationStatus.dismissed:
  60 + case AnimationStatus.forward:
  61 + widget.onStart?.call(_controller);
  62 + break;
  63 + // case AnimationStatus.reverse:
  64 + default:
  65 + break;
  66 + }
  67 + }
  68 +
  69 + @override
  70 + void initState() {
  71 + super.initState();
  72 +
  73 + if (widget is OpacityAnimation) {
  74 + final current =
  75 + context.findRootAncestorStateOfType<GetAnimatedBuilderState>();
  76 + final isLast = current == null;
  77 +
  78 + if (widget is FadeInAnimation) {
  79 + _idleValue = 1.0 as dynamic;
  80 + } else {
  81 + if (isLast) {
  82 + _willResetOnDispose = false;
  83 + } else {
  84 + _willResetOnDispose = true;
  85 + }
  86 + _idleValue = widget.idleValue;
  87 + }
  88 + } else {
  89 + _idleValue = widget.idleValue;
  90 + }
  91 +
  92 + _controller = AnimationController(
  93 + vsync: this,
  94 + duration: widget.duration,
  95 + );
  96 +
  97 + _controller.addStatusListener(_listener);
  98 +
  99 + _animation = widget.tween.animate(
  100 + CurvedAnimation(
  101 + parent: _controller,
  102 + curve: widget.curve,
  103 + ),
  104 + );
  105 +
  106 + Future.delayed(widget.delay, () {
  107 + if (mounted) {
  108 + setState(() {
  109 + _wasStarted = true;
  110 + _controller.forward();
  111 + });
  112 + }
  113 + });
  114 + }
  115 +
  116 + @override
  117 + void dispose() {
  118 + _controller.removeStatusListener(_listener);
  119 + _controller.dispose();
  120 + super.dispose();
  121 + }
  122 +
  123 + @override
  124 + Widget build(BuildContext context) {
  125 + return AnimatedBuilder(
  126 + animation: _animation,
  127 + builder: (context, child) {
  128 + final value = _wasStarted ? _animation.value : _idleValue;
  129 + return widget.builder(context, value, child);
  130 + },
  131 + child: widget.child,
  132 + );
  133 + }
  134 +}
  1 +export './animations.dart';
  2 +export './extensions.dart';
  3 +export './get_animated_builder.dart';
@@ -268,9 +268,9 @@ class GetConnect extends GetConnectInterface { @@ -268,9 +268,9 @@ class GetConnect extends GetConnectInterface {
268 }) { 268 }) {
269 _checkIfDisposed(isHttp: false); 269 _checkIfDisposed(isHttp: false);
270 270
271 - final _socket = GetSocket(_concatUrl(url)!, ping: ping);  
272 - sockets.add(_socket);  
273 - return _socket; 271 + final newSocket = GetSocket(_concatUrl(url)!, ping: ping);
  272 + sockets.add(newSocket);
  273 + return newSocket;
274 } 274 }
275 275
276 String? _concatUrl(String? url) { 276 String? _concatUrl(String? url) {
@@ -16,7 +16,8 @@ typedef Decoder<T> = T Function(dynamic data); @@ -16,7 +16,8 @@ typedef Decoder<T> = T Function(dynamic data);
16 16
17 typedef Progress = Function(double percent); 17 typedef Progress = Function(double percent);
18 18
19 -typedef ResponseInterceptor<T> = Future<Response<T>?> Function(Request<T> request, Type targetType, HttpClientResponse response); 19 +typedef ResponseInterceptor<T> = Future<Response<T>?> Function(
  20 + Request<T> request, Type targetType, HttpClientResponse response);
20 21
21 class GetHttpClient { 22 class GetHttpClient {
22 String userAgent; 23 String userAgent;
@@ -38,7 +39,7 @@ class GetHttpClient { @@ -38,7 +39,7 @@ class GetHttpClient {
38 39
39 bool errorSafety = true; 40 bool errorSafety = true;
40 41
41 - final HttpRequestBase _httpClient; 42 + final IClient _httpClient;
42 43
43 final GetModifier _modifier; 44 final GetModifier _modifier;
44 45
@@ -57,12 +58,14 @@ class GetHttpClient { @@ -57,12 +58,14 @@ class GetHttpClient {
57 List<TrustedCertificate>? trustedCertificates, 58 List<TrustedCertificate>? trustedCertificates,
58 bool withCredentials = false, 59 bool withCredentials = false,
59 String Function(Uri url)? findProxy, 60 String Function(Uri url)? findProxy,
60 - }) : _httpClient = createHttp(  
61 - allowAutoSignedCert: allowAutoSignedCert,  
62 - trustedCertificates: trustedCertificates,  
63 - withCredentials: withCredentials,  
64 - findProxy: findProxy,  
65 - ), 61 + IClient? customClient,
  62 + }) : _httpClient = customClient ??
  63 + createHttp(
  64 + allowAutoSignedCert: allowAutoSignedCert,
  65 + trustedCertificates: trustedCertificates,
  66 + withCredentials: withCredentials,
  67 + findProxy: findProxy,
  68 + ),
66 _modifier = GetModifier(); 69 _modifier = GetModifier();
67 70
68 void addAuthenticator<T>(RequestModifier<T> auth) { 71 void addAuthenticator<T>(RequestModifier<T> auth) {
@@ -85,7 +88,7 @@ class GetHttpClient { @@ -85,7 +88,7 @@ class GetHttpClient {
85 _modifier.removeResponseModifier<T>(interceptor); 88 _modifier.removeResponseModifier<T>(interceptor);
86 } 89 }
87 90
88 - Uri _createUri(String? url, Map<String, dynamic>? query) { 91 + Uri createUri(String? url, Map<String, dynamic>? query) {
89 if (baseUrl != null) { 92 if (baseUrl != null) {
90 url = baseUrl! + url!; 93 url = baseUrl! + url!;
91 } 94 }
@@ -154,18 +157,17 @@ class GetHttpClient { @@ -154,18 +157,17 @@ class GetHttpClient {
154 bodyStream = _trackProgress(bodyBytes, uploadProgress); 157 bodyStream = _trackProgress(bodyBytes, uploadProgress);
155 } 158 }
156 159
157 - final uri = _createUri(url, query); 160 + final uri = createUri(url, query);
158 return Request<T>( 161 return Request<T>(
159 - method: method,  
160 - url: uri,  
161 - headers: headers,  
162 - bodyBytes: bodyStream,  
163 - contentLength: bodyBytes?.length ?? 0,  
164 - followRedirects: followRedirects,  
165 - maxRedirects: maxRedirects,  
166 - decoder: decoder,  
167 - responseInterceptor: responseInterceptor  
168 - ); 162 + method: method,
  163 + url: uri,
  164 + headers: headers,
  165 + bodyBytes: bodyStream,
  166 + contentLength: bodyBytes?.length ?? 0,
  167 + followRedirects: followRedirects,
  168 + maxRedirects: maxRedirects,
  169 + decoder: decoder,
  170 + responseInterceptor: responseInterceptor);
169 } 171 }
170 172
171 void _setContentLenght(Map<String, String> headers, int contentLength) { 173 void _setContentLenght(Map<String, String> headers, int contentLength) {
@@ -277,7 +279,7 @@ class GetHttpClient { @@ -277,7 +279,7 @@ class GetHttpClient {
277 ) { 279 ) {
278 final headers = <String, String>{}; 280 final headers = <String, String>{};
279 _setSimpleHeaders(headers, contentType); 281 _setSimpleHeaders(headers, contentType);
280 - final uri = _createUri(url, query); 282 + final uri = createUri(url, query);
281 283
282 return Future.value(Request<T>( 284 return Future.value(Request<T>(
283 method: 'get', 285 method: 'get',
@@ -291,11 +293,14 @@ class GetHttpClient { @@ -291,11 +293,14 @@ class GetHttpClient {
291 )); 293 ));
292 } 294 }
293 295
294 - ResponseInterceptor<T>? _responseInterceptor<T>(ResponseInterceptor<T>? actual) {  
295 - if(actual != null) return actual; 296 + ResponseInterceptor<T>? _responseInterceptor<T>(
  297 + ResponseInterceptor<T>? actual) {
  298 + if (actual != null) return actual;
296 final defaultInterceptor = defaultResponseInterceptor; 299 final defaultInterceptor = defaultResponseInterceptor;
297 return defaultInterceptor != null 300 return defaultInterceptor != null
298 - ? (request, targetType, response) async => await defaultInterceptor(request, targetType, response) as Response<T>? 301 + ? (request, targetType, response) async =>
  302 + await defaultInterceptor(request, targetType, response)
  303 + as Response<T>?
299 : null; 304 : null;
300 } 305 }
301 306
@@ -330,7 +335,7 @@ class GetHttpClient { @@ -330,7 +335,7 @@ class GetHttpClient {
330 ) { 335 ) {
331 final headers = <String, String>{}; 336 final headers = <String, String>{};
332 _setSimpleHeaders(headers, contentType); 337 _setSimpleHeaders(headers, contentType);
333 - final uri = _createUri(url, query); 338 + final uri = createUri(url, query);
334 339
335 return Request<T>( 340 return Request<T>(
336 method: 'delete', 341 method: 'delete',
@@ -340,6 +345,7 @@ class GetHttpClient { @@ -340,6 +345,7 @@ class GetHttpClient {
340 responseInterceptor: _responseInterceptor(responseInterceptor), 345 responseInterceptor: _responseInterceptor(responseInterceptor),
341 ); 346 );
342 } 347 }
  348 +
343 Future<Response<T>> send<T>(Request<T> request) async { 349 Future<Response<T>> send<T>(Request<T> request) async {
344 try { 350 try {
345 var response = await _performRequest<T>(() => Future.value(request)); 351 var response = await _performRequest<T>(() => Future.value(request));
@@ -521,78 +527,16 @@ class GetHttpClient { @@ -521,78 +527,16 @@ class GetHttpClient {
521 } 527 }
522 } 528 }
523 529
524 - // Future<Response<T>> download<T>(  
525 - // String url,  
526 - // String path, {  
527 - // Map<String, String> headers,  
528 - // String contentType = 'application/octet-stream',  
529 - // Map<String, dynamic> query,  
530 - // }) async {  
531 - // try {  
532 - // var response = await _performRequest<T>(  
533 - // () => _get<T>(url, contentType, query, null),  
534 - // headers: headers,  
535 - // );  
536 - // response.bodyBytes.listen((value) {});  
537 - // return response;  
538 - // } on Exception catch (e) {  
539 - // if (!errorSafety) {  
540 - // throw GetHttpException(e.toString());  
541 - // }  
542 - // return Future.value(Response<T>(  
543 - // statusText: 'Can not connect to server. Reason: $e',  
544 - // ));  
545 - // }  
546 -  
547 - // int byteCount = 0;  
548 - // int totalBytes = httpResponse.contentLength;  
549 -  
550 - // Directory appDocDir = await getApplicationDocumentsDirectory();  
551 - // String appDocPath = appDocDir.path;  
552 -  
553 - // File file = File(path);  
554 -  
555 - // var raf = file.openSync(mode: FileMode.write);  
556 -  
557 - // Completer completer = Completer<String>();  
558 -  
559 - // httpResponse.listen(  
560 - // (data) {  
561 - // byteCount += data.length;  
562 -  
563 - // raf.writeFromSync(data);  
564 -  
565 - // if (onDownloadProgress != null) {  
566 - // onDownloadProgress(byteCount, totalBytes);  
567 - // }  
568 - // },  
569 - // onDone: () {  
570 - // raf.closeSync();  
571 -  
572 - // completer.complete(file.path);  
573 - // },  
574 - // onError: (e) {  
575 - // raf.closeSync();  
576 - // file.deleteSync();  
577 - // completer.completeError(e);  
578 - // },  
579 - // cancelOnError: true,  
580 - // );  
581 -  
582 - // return completer.future;  
583 - // }  
584 -  
585 - Future<Response<T>> delete<T>(  
586 - String url, {  
587 - Map<String, String>? headers,  
588 - String? contentType,  
589 - Map<String, dynamic>? query,  
590 - Decoder<T>? decoder,  
591 - ResponseInterceptor<T>? responseInterceptor  
592 - }) async { 530 + Future<Response<T>> delete<T>(String url,
  531 + {Map<String, String>? headers,
  532 + String? contentType,
  533 + Map<String, dynamic>? query,
  534 + Decoder<T>? decoder,
  535 + ResponseInterceptor<T>? responseInterceptor}) async {
593 try { 536 try {
594 var response = await _performRequest<T>( 537 var response = await _performRequest<T>(
595 - () async => _delete<T>(url, contentType, query, decoder, responseInterceptor), 538 + () async =>
  539 + _delete<T>(url, contentType, query, decoder, responseInterceptor),
596 headers: headers, 540 headers: headers,
597 ); 541 );
598 return response; 542 return response;
@@ -4,7 +4,8 @@ List<int> fileToBytes(dynamic data) { @@ -4,7 +4,8 @@ List<int> fileToBytes(dynamic data) {
4 if (data is List<int>) { 4 if (data is List<int>) {
5 return data; 5 return data;
6 } else { 6 } else {
7 - throw FormatException('File is not "File" or "String" or "List<int>"'); 7 + throw const FormatException(
  8 + 'File is not "File" or "String" or "List<int>"');
8 } 9 }
9 } 10 }
10 11
@@ -9,8 +9,8 @@ import '../../response/response.dart'; @@ -9,8 +9,8 @@ import '../../response/response.dart';
9 import '../interface/request_base.dart'; 9 import '../interface/request_base.dart';
10 import '../utils/body_decoder.dart'; 10 import '../utils/body_decoder.dart';
11 11
12 -/// A `dart:html` implementation of `HttpRequestBase`.  
13 -class HttpRequestImpl implements HttpRequestBase { 12 +/// A `dart:html` implementation of `IClient`.
  13 +class HttpRequestImpl implements IClient {
14 HttpRequestImpl({ 14 HttpRequestImpl({
15 bool allowAutoSignedCert = true, 15 bool allowAutoSignedCert = true,
16 List<TrustedCertificate>? trustedCertificates, 16 List<TrustedCertificate>? trustedCertificates,
@@ -51,7 +51,7 @@ class HttpRequestImpl implements HttpRequestBase { @@ -51,7 +51,7 @@ class HttpRequestImpl implements HttpRequestBase {
51 var reader = FileReader(); 51 var reader = FileReader();
52 52
53 reader.onLoad.first.then((_) async { 53 reader.onLoad.first.then((_) async {
54 - var bodyBytes = BodyBytesStream.fromBytes(reader.result as List<int>); 54 + var bodyBytes = (reader.result as List<int>).toStream();
55 55
56 final stringBody = 56 final stringBody =
57 await bodyBytesToString(bodyBytes, xhr.responseHeaders); 57 await bodyBytesToString(bodyBytes, xhr.responseHeaders);
@@ -2,7 +2,7 @@ import '../../request/request.dart'; @@ -2,7 +2,7 @@ import '../../request/request.dart';
2 import '../../response/response.dart'; 2 import '../../response/response.dart';
3 3
4 /// Abstract interface of [HttpRequestImpl]. 4 /// Abstract interface of [HttpRequestImpl].
5 -abstract class HttpRequestBase { 5 +abstract class IClient {
6 /// Sends an HTTP [Request]. 6 /// Sends an HTTP [Request].
7 Future<Response<T>> send<T>(Request<T> request); 7 Future<Response<T>> send<T>(Request<T> request);
8 8
@@ -12,7 +12,8 @@ List<int> fileToBytes(dynamic data) { @@ -12,7 +12,8 @@ List<int> fileToBytes(dynamic data) {
12 } else if (data is List<int>) { 12 } else if (data is List<int>) {
13 return data; 13 return data;
14 } else { 14 } else {
15 - throw FormatException('File is not "File" or "String" or "List<int>"'); 15 + throw const FormatException(
  16 + 'File is not "File" or "String" or "List<int>"');
16 } 17 }
17 } 18 }
18 19
@@ -8,9 +8,8 @@ import '../../response/response.dart'; @@ -8,9 +8,8 @@ import '../../response/response.dart';
8 import '../interface/request_base.dart'; 8 import '../interface/request_base.dart';
9 import '../utils/body_decoder.dart'; 9 import '../utils/body_decoder.dart';
10 10
11 -  
12 -/// A `dart:io` implementation of `HttpRequestBase`.  
13 -class HttpRequestImpl extends HttpRequestBase { 11 +/// A `dart:io` implementation of `IClient`.
  12 +class HttpRequestImpl extends IClient {
14 io.HttpClient? _httpClient; 13 io.HttpClient? _httpClient;
15 io.SecurityContext? _securityContext; 14 io.SecurityContext? _securityContext;
16 15
@@ -58,10 +57,11 @@ class HttpRequestImpl extends HttpRequestBase { @@ -58,10 +57,11 @@ class HttpRequestImpl extends HttpRequestBase {
58 }); 57 });
59 58
60 final bodyBytes = (response); 59 final bodyBytes = (response);
61 -  
62 - final interceptionResponse = await request.responseInterceptor?.call(request, T, response);  
63 - if(interceptionResponse != null) return interceptionResponse;  
64 - 60 +
  61 + final interceptionResponse =
  62 + await request.responseInterceptor?.call(request, T, response);
  63 + if (interceptionResponse != null) return interceptionResponse;
  64 +
65 final stringBody = await bodyBytesToString(bodyBytes, headers); 65 final stringBody = await bodyBytesToString(bodyBytes, headers);
66 66
67 final body = bodyDecoded<T>( 67 final body = bodyDecoded<T>(
@@ -5,7 +5,7 @@ import '../utils/body_decoder.dart'; @@ -5,7 +5,7 @@ import '../utils/body_decoder.dart';
5 5
6 typedef MockClientHandler = Future<Response> Function(Request request); 6 typedef MockClientHandler = Future<Response> Function(Request request);
7 7
8 -class MockClient extends HttpRequestBase { 8 +class MockClient extends IClient {
9 /// The handler for than transforms request on response 9 /// The handler for than transforms request on response
10 final MockClientHandler _handler; 10 final MockClientHandler _handler;
11 11
@@ -16,7 +16,7 @@ class MockClient extends HttpRequestBase { @@ -16,7 +16,7 @@ class MockClient extends HttpRequestBase {
16 @override 16 @override
17 Future<Response<T>> send<T>(Request<T> request) async { 17 Future<Response<T>> send<T>(Request<T> request) async {
18 var requestBody = await request.bodyBytes.toBytes(); 18 var requestBody = await request.bodyBytes.toBytes();
19 - var bodyBytes = BodyBytesStream.fromBytes(requestBody); 19 + var bodyBytes = requestBody.toStream();
20 20
21 var response = await _handler(request); 21 var response = await _handler(request);
22 22
@@ -3,7 +3,7 @@ import '../../request/request.dart'; @@ -3,7 +3,7 @@ import '../../request/request.dart';
3 import '../../response/response.dart'; 3 import '../../response/response.dart';
4 import '../interface/request_base.dart'; 4 import '../interface/request_base.dart';
5 5
6 -class HttpRequestImpl extends HttpRequestBase { 6 +class HttpRequestImpl extends IClient {
7 HttpRequestImpl({ 7 HttpRequestImpl({
8 bool allowAutoSignedCert = true, 8 bool allowAutoSignedCert = true,
9 List<TrustedCertificate>? trustedCertificates, 9 List<TrustedCertificate>? trustedCertificates,
@@ -25,9 +25,9 @@ class FormData { @@ -25,9 +25,9 @@ class FormData {
25 static const int _maxBoundaryLength = 70; 25 static const int _maxBoundaryLength = 70;
26 26
27 static String _getBoundary() { 27 static String _getBoundary() {
28 - final _random = Random(); 28 + final newRandom = Random();
29 var list = List<int>.generate(_maxBoundaryLength - GET_BOUNDARY.length, 29 var list = List<int>.generate(_maxBoundaryLength - GET_BOUNDARY.length,
30 - (_) => boundaryCharacters[_random.nextInt(boundaryCharacters.length)], 30 + (_) => boundaryCharacters[newRandom.nextInt(boundaryCharacters.length)],
31 growable: false); 31 growable: false);
32 return '$GET_BOUNDARY${String.fromCharCodes(list)}'; 32 return '$GET_BOUNDARY${String.fromCharCodes(list)}';
33 } 33 }
1 import '../http/stub/file_decoder_stub.dart' 1 import '../http/stub/file_decoder_stub.dart'
2 if (dart.library.html) '../http/html/file_decoder_html.dart' 2 if (dart.library.html) '../http/html/file_decoder_html.dart'
3 if (dart.library.io) '../http/io/file_decoder_io.dart'; 3 if (dart.library.io) '../http/io/file_decoder_io.dart';
4 -  
5 import '../request/request.dart'; 4 import '../request/request.dart';
6 5
7 class MultipartFile { 6 class MultipartFile {
@@ -11,7 +10,7 @@ class MultipartFile { @@ -11,7 +10,7 @@ class MultipartFile {
11 this.contentType = 'application/octet-stream', 10 this.contentType = 'application/octet-stream',
12 }) : _bytes = fileToBytes(data) { 11 }) : _bytes = fileToBytes(data) {
13 _length = _bytes.length; 12 _length = _bytes.length;
14 - _stream = BodyBytesStream.fromBytes(_bytes); 13 + _stream = _bytes.toStream();
15 } 14 }
16 15
17 final List<int> _bytes; 16 final List<int> _bytes;
@@ -68,7 +68,7 @@ class Request<T> { @@ -68,7 +68,7 @@ class Request<T> {
68 return Request._( 68 return Request._(
69 url: url, 69 url: url,
70 method: method, 70 method: method,
71 - bodyBytes: bodyBytes ??= BodyBytesStream.fromBytes(const []), 71 + bodyBytes: bodyBytes ??= <int>[].toStream(),
72 headers: Map.from(headers), 72 headers: Map.from(headers),
73 followRedirects: followRedirects, 73 followRedirects: followRedirects,
74 maxRedirects: maxRedirects, 74 maxRedirects: maxRedirects,
@@ -113,9 +113,11 @@ class Request<T> { @@ -113,9 +113,11 @@ class Request<T> {
113 } 113 }
114 } 114 }
115 115
116 -extension BodyBytesStream on Stream<List<int>> {  
117 - static Stream<List<int>> fromBytes(List<int> bytes) => Stream.value(bytes); 116 +extension StreamExt on List<int> {
  117 + Stream<List<int>> toStream() => Stream.value(this).asBroadcastStream();
  118 +}
118 119
  120 +extension BodyBytesStream on Stream<List<int>> {
119 Future<Uint8List> toBytes() { 121 Future<Uint8List> toBytes() {
120 var completer = Completer<Uint8List>(); 122 var completer = Completer<Uint8List>();
121 var sink = ByteConversionSink.withCallback( 123 var sink = ByteConversionSink.withCallback(
1 import 'package:flutter/widgets.dart'; 1 import 'package:flutter/widgets.dart';
2 2
3 -class Engine{  
4 - static WidgetsBinding get instance { 3 +class Engine {
  4 + static WidgetsBinding get instance {
5 return WidgetsFlutterBinding.ensureInitialized(); 5 return WidgetsFlutterBinding.ensureInitialized();
6 } 6 }
7 -}  
  7 +}
@@ -27,6 +27,24 @@ class InstanceInfo { @@ -27,6 +27,24 @@ class InstanceInfo {
27 } 27 }
28 } 28 }
29 29
  30 +extension ResetInstance on GetInterface {
  31 + /// Clears all registered instances (and/or tags).
  32 + /// Even the persistent ones.
  33 + /// This should be used at the end or tearDown of unit tests.
  34 + ///
  35 + /// `clearFactory` clears the callbacks registered by [lazyPut]
  36 + /// `clearRouteBindings` clears Instances associated with routes.
  37 + ///
  38 + bool resetInstance({bool clearRouteBindings = true}) {
  39 + // if (clearFactory) _factory.clear();
  40 + // deleteAll(force: true);
  41 + if (clearRouteBindings) RouterReportManager.instance.clearRouteKeys();
  42 + Inst._singl.clear();
  43 +
  44 + return true;
  45 + }
  46 +}
  47 +
30 extension Inst on GetInterface { 48 extension Inst on GetInterface {
31 T call<T>() => find<T>(); 49 T call<T>() => find<T>();
32 50
@@ -143,11 +161,11 @@ extension Inst on GetInterface { @@ -143,11 +161,11 @@ extension Inst on GetInterface {
143 161
144 _InstanceBuilderFactory<S>? dep; 162 _InstanceBuilderFactory<S>? dep;
145 if (_singl.containsKey(key)) { 163 if (_singl.containsKey(key)) {
146 - final _dep = _singl[key];  
147 - if (_dep == null || !_dep.isDirty) { 164 + final newDep = _singl[key];
  165 + if (newDep == null || !newDep.isDirty) {
148 return; 166 return;
149 } else { 167 } else {
150 - dep = _dep as _InstanceBuilderFactory<S>; 168 + dep = newDep as _InstanceBuilderFactory<S>;
151 } 169 }
152 } 170 }
153 _singl[key] = _InstanceBuilderFactory<S>( 171 _singl[key] = _InstanceBuilderFactory<S>(
@@ -311,22 +329,6 @@ extension Inst on GetInterface { @@ -311,22 +329,6 @@ extension Inst on GetInterface {
311 return name == null ? type.toString() : type.toString() + name; 329 return name == null ? type.toString() : type.toString() + name;
312 } 330 }
313 331
314 - /// Clears all registered instances (and/or tags).  
315 - /// Even the persistent ones.  
316 - /// This should be used at the end or tearDown of unit tests.  
317 - ///  
318 - /// `clearFactory` clears the callbacks registered by [lazyPut]  
319 - /// `clearRouteBindings` clears Instances associated with routes.  
320 - ///  
321 - bool resetInstance({bool clearRouteBindings = true}) {  
322 - // if (clearFactory) _factory.clear();  
323 - // deleteAll(force: true);  
324 - if (clearRouteBindings) RouterReportManager.instance.clearRouteKeys();  
325 - _singl.clear();  
326 -  
327 - return true;  
328 - }  
329 -  
330 /// Delete registered Class Instance [S] (or [tag]) and, closes any open 332 /// Delete registered Class Instance [S] (or [tag]) and, closes any open
331 /// controllers `DisposableInterface`, cleans up the memory 333 /// controllers `DisposableInterface`, cleans up the memory
332 /// 334 ///
@@ -5,7 +5,6 @@ export 'src/extension_navigation.dart'; @@ -5,7 +5,6 @@ export 'src/extension_navigation.dart';
5 export 'src/root/get_cupertino_app.dart'; 5 export 'src/root/get_cupertino_app.dart';
6 export 'src/root/get_material_app.dart'; 6 export 'src/root/get_material_app.dart';
7 export 'src/root/internacionalization.dart'; 7 export 'src/root/internacionalization.dart';
8 -export 'src/root/root_controller.dart';  
9 export 'src/routes/custom_transition.dart'; 8 export 'src/routes/custom_transition.dart';
10 export 'src/routes/default_route.dart'; 9 export 'src/routes/default_route.dart';
11 export 'src/routes/get_route.dart'; 10 export 'src/routes/get_route.dart';
@@ -21,6 +21,7 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> { @@ -21,6 +21,7 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> {
21 RouteSettings? settings, 21 RouteSettings? settings,
22 this.enterBottomSheetDuration = const Duration(milliseconds: 250), 22 this.enterBottomSheetDuration = const Duration(milliseconds: 250),
23 this.exitBottomSheetDuration = const Duration(milliseconds: 200), 23 this.exitBottomSheetDuration = const Duration(milliseconds: 200),
  24 + this.curve,
24 }) : super(settings: settings) { 25 }) : super(settings: settings) {
25 RouterReportManager.instance.reportCurrentRoute(this); 26 RouterReportManager.instance.reportCurrentRoute(this);
26 } 27 }
@@ -38,11 +39,12 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> { @@ -38,11 +39,12 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> {
38 // final String name; 39 // final String name;
39 final Duration enterBottomSheetDuration; 40 final Duration enterBottomSheetDuration;
40 final Duration exitBottomSheetDuration; 41 final Duration exitBottomSheetDuration;
  42 + final Curve? curve;
41 // remove safearea from top 43 // remove safearea from top
42 final bool removeTop; 44 final bool removeTop;
43 45
44 @override 46 @override
45 - Duration get transitionDuration => Duration(milliseconds: 700); 47 + Duration get transitionDuration => const Duration(milliseconds: 700);
46 48
47 @override 49 @override
48 bool get barrierDismissible => isDismissible; 50 bool get barrierDismissible => isDismissible;
@@ -62,6 +64,14 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> { @@ -62,6 +64,14 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> {
62 } 64 }
63 65
64 @override 66 @override
  67 + Animation<double> createAnimation() {
  68 + if (curve != null) {
  69 + return CurvedAnimation(curve: curve!, parent: _animationController!.view);
  70 + }
  71 + return _animationController!.view;
  72 + }
  73 +
  74 + @override
65 AnimationController createAnimationController() { 75 AnimationController createAnimationController() {
66 assert(_animationController == null); 76 assert(_animationController == null);
67 _animationController = 77 _animationController =
@@ -51,9 +51,9 @@ class GetDialogRoute<T> extends PopupRoute<T> { @@ -51,9 +51,9 @@ class GetDialogRoute<T> extends PopupRoute<T> {
51 Widget buildPage(BuildContext context, Animation<double> animation, 51 Widget buildPage(BuildContext context, Animation<double> animation,
52 Animation<double> secondaryAnimation) { 52 Animation<double> secondaryAnimation) {
53 return Semantics( 53 return Semantics(
54 - child: widget(context, animation, secondaryAnimation),  
55 scopesRoute: true, 54 scopesRoute: true,
56 explicitChildNodes: true, 55 explicitChildNodes: true,
  56 + child: widget(context, animation, secondaryAnimation),
57 ); 57 );
58 } 58 }
59 59
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; @@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
4 4
5 import '../../get.dart'; 5 import '../../get.dart';
6 import 'dialog/dialog_route.dart'; 6 import 'dialog/dialog_route.dart';
  7 +import 'root/get_root.dart';
7 8
8 /// It replaces the Flutter Navigator, but needs no context. 9 /// It replaces the Flutter Navigator, but needs no context.
9 /// You can to use navigator.push(YourRoute()) rather 10 /// You can to use navigator.push(YourRoute()) rather
@@ -27,6 +28,7 @@ extension ExtensionBottomSheet on GetInterface { @@ -27,6 +28,7 @@ extension ExtensionBottomSheet on GetInterface {
27 RouteSettings? settings, 28 RouteSettings? settings,
28 Duration? enterBottomSheetDuration, 29 Duration? enterBottomSheetDuration,
29 Duration? exitBottomSheetDuration, 30 Duration? exitBottomSheetDuration,
  31 + Curve? curve,
30 }) { 32 }) {
31 return Navigator.of(overlayContext!, rootNavigator: useRootNavigator) 33 return Navigator.of(overlayContext!, rootNavigator: useRootNavigator)
32 .push(GetModalBottomSheetRoute<T>( 34 .push(GetModalBottomSheetRoute<T>(
@@ -52,6 +54,7 @@ extension ExtensionBottomSheet on GetInterface { @@ -52,6 +54,7 @@ extension ExtensionBottomSheet on GetInterface {
52 enterBottomSheetDuration ?? const Duration(milliseconds: 250), 54 enterBottomSheetDuration ?? const Duration(milliseconds: 250),
53 exitBottomSheetDuration: 55 exitBottomSheetDuration:
54 exitBottomSheetDuration ?? const Duration(milliseconds: 200), 56 exitBottomSheetDuration ?? const Duration(milliseconds: 200),
  57 + curve: curve,
55 )); 58 ));
56 } 59 }
57 } 60 }
@@ -184,7 +187,7 @@ extension ExtensionDialog on GetInterface { @@ -184,7 +187,7 @@ extension ExtensionDialog on GetInterface {
184 actions.add(TextButton( 187 actions.add(TextButton(
185 style: TextButton.styleFrom( 188 style: TextButton.styleFrom(
186 tapTargetSize: MaterialTapTargetSize.shrinkWrap, 189 tapTargetSize: MaterialTapTargetSize.shrinkWrap,
187 - padding: EdgeInsets.symmetric(horizontal: 10, vertical: 8), 190 + padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
188 shape: RoundedRectangleBorder( 191 shape: RoundedRectangleBorder(
189 side: BorderSide( 192 side: BorderSide(
190 color: buttonColor ?? theme.colorScheme.secondary, 193 color: buttonColor ?? theme.colorScheme.secondary,
@@ -217,8 +220,8 @@ extension ExtensionDialog on GetInterface { @@ -217,8 +220,8 @@ extension ExtensionDialog on GetInterface {
217 ), 220 ),
218 child: Text( 221 child: Text(
219 textConfirm ?? "Ok", 222 textConfirm ?? "Ok",
220 - style:  
221 - TextStyle(color: confirmTextColor ?? theme.backgroundColor), 223 + style: TextStyle(
  224 + color: confirmTextColor ?? theme.colorScheme.background),
222 ), 225 ),
223 onPressed: () { 226 onPressed: () {
224 onConfirm?.call(); 227 onConfirm?.call();
@@ -227,8 +230,8 @@ extension ExtensionDialog on GetInterface { @@ -227,8 +230,8 @@ extension ExtensionDialog on GetInterface {
227 } 230 }
228 231
229 Widget baseAlertDialog = AlertDialog( 232 Widget baseAlertDialog = AlertDialog(
230 - titlePadding: titlePadding ?? EdgeInsets.all(8),  
231 - contentPadding: contentPadding ?? EdgeInsets.all(8), 233 + titlePadding: titlePadding ?? const EdgeInsets.all(8),
  234 + contentPadding: contentPadding ?? const EdgeInsets.all(8),
232 235
233 backgroundColor: backgroundColor ?? theme.dialogBackgroundColor, 236 backgroundColor: backgroundColor ?? theme.dialogBackgroundColor,
234 shape: RoundedRectangleBorder( 237 shape: RoundedRectangleBorder(
@@ -241,7 +244,7 @@ extension ExtensionDialog on GetInterface { @@ -241,7 +244,7 @@ extension ExtensionDialog on GetInterface {
241 content ?? 244 content ??
242 Text(middleText, 245 Text(middleText,
243 textAlign: TextAlign.center, style: middleTextStyle), 246 textAlign: TextAlign.center, style: middleTextStyle),
244 - SizedBox(height: 16), 247 + const SizedBox(height: 16),
245 ButtonTheme( 248 ButtonTheme(
246 minWidth: 78.0, 249 minWidth: 78.0,
247 height: 34.0, 250 height: 34.0,
@@ -431,14 +434,14 @@ extension ExtensionSnackbar on GetInterface { @@ -431,14 +434,14 @@ extension ExtensionSnackbar on GetInterface {
431 ), 434 ),
432 snackPosition: snackPosition ?? SnackPosition.top, 435 snackPosition: snackPosition ?? SnackPosition.top,
433 borderRadius: borderRadius ?? 15, 436 borderRadius: borderRadius ?? 15,
434 - margin: margin ?? EdgeInsets.symmetric(horizontal: 10), 437 + margin: margin ?? const EdgeInsets.symmetric(horizontal: 10),
435 duration: duration, 438 duration: duration,
436 barBlur: barBlur ?? 7.0, 439 barBlur: barBlur ?? 7.0,
437 backgroundColor: backgroundColor ?? Colors.grey.withOpacity(0.2), 440 backgroundColor: backgroundColor ?? Colors.grey.withOpacity(0.2),
438 icon: icon, 441 icon: icon,
439 shouldIconPulse: shouldIconPulse ?? true, 442 shouldIconPulse: shouldIconPulse ?? true,
440 maxWidth: maxWidth, 443 maxWidth: maxWidth,
441 - padding: padding ?? EdgeInsets.all(16), 444 + padding: padding ?? const EdgeInsets.all(16),
442 borderColor: borderColor, 445 borderColor: borderColor,
443 borderWidth: borderWidth, 446 borderWidth: borderWidth,
444 leftBarIndicatorColor: leftBarIndicatorColor, 447 leftBarIndicatorColor: leftBarIndicatorColor,
@@ -456,7 +459,7 @@ extension ExtensionSnackbar on GetInterface { @@ -456,7 +459,7 @@ extension ExtensionSnackbar on GetInterface {
456 snackStyle: snackStyle ?? SnackStyle.floating, 459 snackStyle: snackStyle ?? SnackStyle.floating,
457 forwardAnimationCurve: forwardAnimationCurve ?? Curves.easeOutCirc, 460 forwardAnimationCurve: forwardAnimationCurve ?? Curves.easeOutCirc,
458 reverseAnimationCurve: reverseAnimationCurve ?? Curves.easeOutCirc, 461 reverseAnimationCurve: reverseAnimationCurve ?? Curves.easeOutCirc,
459 - animationDuration: animationDuration ?? Duration(seconds: 1), 462 + animationDuration: animationDuration ?? const Duration(seconds: 1),
460 overlayBlur: overlayBlur ?? 0.0, 463 overlayBlur: overlayBlur ?? 0.0,
461 overlayColor: overlayColor ?? Colors.transparent, 464 overlayColor: overlayColor ?? Colors.transparent,
462 userInputForm: userInputForm); 465 userInputForm: userInputForm);
@@ -1009,36 +1012,36 @@ extension GetNavigationExt on GetInterface { @@ -1009,36 +1012,36 @@ extension GetNavigationExt on GetInterface {
1009 } 1012 }
1010 return Uri.tryParse(name)?.toString() ?? name; 1013 return Uri.tryParse(name)?.toString() ?? name;
1011 } 1014 }
1012 -  
1013 - /// change default config of Get  
1014 - void config(  
1015 - {bool? enableLog,  
1016 - LogWriterCallback? logWriterCallback,  
1017 - bool? defaultPopGesture,  
1018 - bool? defaultOpaqueRoute,  
1019 - Duration? defaultDurationTransition,  
1020 - bool? defaultGlobalState,  
1021 - Transition? defaultTransition}) {  
1022 - if (enableLog != null) {  
1023 - Get.isLogEnable = enableLog;  
1024 - }  
1025 - if (logWriterCallback != null) {  
1026 - Get.log = logWriterCallback;  
1027 - }  
1028 - if (defaultPopGesture != null) {  
1029 - _getxController.defaultPopGesture = defaultPopGesture;  
1030 - }  
1031 - if (defaultOpaqueRoute != null) {  
1032 - _getxController.defaultOpaqueRoute = defaultOpaqueRoute;  
1033 - }  
1034 - if (defaultTransition != null) {  
1035 - _getxController.defaultTransition = defaultTransition;  
1036 - }  
1037 -  
1038 - if (defaultDurationTransition != null) {  
1039 - _getxController.defaultTransitionDuration = defaultDurationTransition;  
1040 - }  
1041 - } 1015 + //TODO: Deprecated
  1016 + // /// change default config of Get
  1017 + // void config(
  1018 + // {bool? enableLog,
  1019 + // LogWriterCallback? logWriterCallback,
  1020 + // bool? defaultPopGesture,
  1021 + // bool? defaultOpaqueRoute,
  1022 + // Duration? defaultDurationTransition,
  1023 + // bool? defaultGlobalState,
  1024 + // Transition? defaultTransition}) {
  1025 + // if (enableLog != null) {
  1026 + // Get.isLogEnable = enableLog;
  1027 + // }
  1028 + // if (logWriterCallback != null) {
  1029 + // Get.log = logWriterCallback;
  1030 + // }
  1031 + // if (defaultPopGesture != null) {
  1032 + // _getxController.defaultPopGesture = defaultPopGesture;
  1033 + // }
  1034 + // if (defaultOpaqueRoute != null) {
  1035 + // _getxController.defaultOpaqueRoute = defaultOpaqueRoute;
  1036 + // }
  1037 + // if (defaultTransition != null) {
  1038 + // _getxController.defaultTransition = defaultTransition;
  1039 + // }
  1040 +
  1041 + // if (defaultDurationTransition != null) {
  1042 + // _getxController.defaultTransitionDuration = defaultDurationTransition;
  1043 + // }
  1044 + // }
1042 1045
1043 Future<void> updateLocale(Locale l) async { 1046 Future<void> updateLocale(Locale l) async {
1044 Get.locale = l; 1047 Get.locale = l;
@@ -1062,33 +1065,33 @@ extension GetNavigationExt on GetInterface { @@ -1062,33 +1065,33 @@ extension GetNavigationExt on GetInterface {
1062 await engine.performReassemble(); 1065 await engine.performReassemble();
1063 } 1066 }
1064 1067
1065 - void appUpdate() => _getxController.update(); 1068 + void appUpdate() => rootController.update();
1066 1069
1067 void changeTheme(ThemeData theme) { 1070 void changeTheme(ThemeData theme) {
1068 - _getxController.setTheme(theme); 1071 + rootController.setTheme(theme);
1069 } 1072 }
1070 1073
1071 void changeThemeMode(ThemeMode themeMode) { 1074 void changeThemeMode(ThemeMode themeMode) {
1072 - _getxController.setThemeMode(themeMode); 1075 + rootController.setThemeMode(themeMode);
1073 } 1076 }
1074 1077
1075 GlobalKey<NavigatorState>? addKey(GlobalKey<NavigatorState> newKey) { 1078 GlobalKey<NavigatorState>? addKey(GlobalKey<NavigatorState> newKey) {
1076 - return _getxController.addKey(newKey); 1079 + return rootController.addKey(newKey);
1077 } 1080 }
1078 1081
1079 GetDelegate? nestedKey(String? key) { 1082 GetDelegate? nestedKey(String? key) {
1080 - return _getxController.nestedKey(key); 1083 + return rootController.nestedKey(key);
1081 } 1084 }
1082 1085
1083 GetDelegate searchDelegate(dynamic k) { 1086 GetDelegate searchDelegate(dynamic k) {
1084 - GetDelegate _key; 1087 + GetDelegate key;
1085 if (k == null) { 1088 if (k == null) {
1086 - _key = Get.rootController.rootDelegate; 1089 + key = Get.rootController.rootDelegate;
1087 } else { 1090 } else {
1088 if (!keys.containsKey(k)) { 1091 if (!keys.containsKey(k)) {
1089 throw 'Route id ($k) not found'; 1092 throw 'Route id ($k) not found';
1090 } 1093 }
1091 - _key = keys[k]!; 1094 + key = keys[k]!;
1092 } 1095 }
1093 1096
1094 // if (_key.listenersLength == 0 && !testMode) { 1097 // if (_key.listenersLength == 0 && !testMode) {
@@ -1101,12 +1104,12 @@ extension GetNavigationExt on GetInterface { @@ -1101,12 +1104,12 @@ extension GetNavigationExt on GetInterface {
1101 // """; 1104 // """;
1102 // } 1105 // }
1103 1106
1104 - return _key; 1107 + return key;
1105 } 1108 }
1106 1109
1107 /// give current arguments 1110 /// give current arguments
1108 //dynamic get arguments => routing.args; 1111 //dynamic get arguments => routing.args;
1109 - dynamic get arguments => _getxController.rootDelegate.arguments(); 1112 + dynamic get arguments => rootController.rootDelegate.arguments();
1110 1113
1111 /// give name from current route 1114 /// give name from current route
1112 String get currentRoute => routing.current; 1115 String get currentRoute => routing.current;
@@ -1155,11 +1158,11 @@ extension GetNavigationExt on GetInterface { @@ -1155,11 +1158,11 @@ extension GetNavigationExt on GetInterface {
1155 1158
1156 /// give access to Theme.of(context) 1159 /// give access to Theme.of(context)
1157 ThemeData get theme { 1160 ThemeData get theme {
1158 - var _theme = ThemeData.fallback(); 1161 + var theme = ThemeData.fallback();
1159 if (context != null) { 1162 if (context != null) {
1160 - _theme = Theme.of(context!); 1163 + theme = Theme.of(context!);
1161 } 1164 }
1162 - return _theme; 1165 + return theme;
1163 } 1166 }
1164 1167
1165 /// The current null safe [WidgetsBinding] 1168 /// The current null safe [WidgetsBinding]
@@ -1219,11 +1222,13 @@ extension GetNavigationExt on GetInterface { @@ -1219,11 +1222,13 @@ extension GetNavigationExt on GetInterface {
1219 // /// give access to Immutable MediaQuery.of(context).size.width 1222 // /// give access to Immutable MediaQuery.of(context).size.width
1220 // double get width => MediaQuery.of(context).size.width; 1223 // double get width => MediaQuery.of(context).size.width;
1221 1224
1222 - GlobalKey<NavigatorState> get key => _getxController.key; 1225 + GlobalKey<NavigatorState> get key => rootController.key;
1223 1226
1224 - Map<dynamic, GetDelegate> get keys => _getxController.keys; 1227 + Map<dynamic, GetDelegate> get keys => rootController.keys;
1225 1228
1226 - GetMaterialController get rootController => _getxController; 1229 + GetRootState get rootController => GetRootState.controller;
  1230 +
  1231 + ConfigData get _getxController => GetRootState.controller.config;
1227 1232
1228 bool get defaultPopGesture => _getxController.defaultPopGesture; 1233 bool get defaultPopGesture => _getxController.defaultPopGesture;
1229 bool get defaultOpaqueRoute => _getxController.defaultOpaqueRoute; 1234 bool get defaultOpaqueRoute => _getxController.defaultOpaqueRoute;
@@ -1246,20 +1251,18 @@ extension GetNavigationExt on GetInterface { @@ -1246,20 +1251,18 @@ extension GetNavigationExt on GetInterface {
1246 1251
1247 Routing get routing => _getxController.routing; 1252 Routing get routing => _getxController.routing;
1248 1253
1249 - Map<String, String?> get parameters =>  
1250 - _getxController.rootDelegate.parameters;  
1251 set parameters(Map<String, String?> newParameters) => 1254 set parameters(Map<String, String?> newParameters) =>
1252 - _getxController.parameters = newParameters; 1255 + rootController.parameters = newParameters;
  1256 +
  1257 + set testMode(bool isTest) => rootController.testMode = isTest;
1253 1258
1254 bool get testMode => _getxController.testMode; 1259 bool get testMode => _getxController.testMode;
1255 - set testMode(bool isTest) => _getxController.testMode = isTest; 1260 +
  1261 + Map<String, String?> get parameters => rootController.rootDelegate.parameters;
1256 1262
1257 /// Casts the stored router delegate to a desired type 1263 /// Casts the stored router delegate to a desired type
1258 TDelegate? delegate<TDelegate extends RouterDelegate<TPage>, TPage>() => 1264 TDelegate? delegate<TDelegate extends RouterDelegate<TPage>, TPage>() =>
1259 _getxController.routerDelegate as TDelegate?; 1265 _getxController.routerDelegate as TDelegate?;
1260 -  
1261 - static final GetMaterialController _getxController =  
1262 - Get.find<GetMaterialController>();  
1263 } 1266 }
1264 1267
1265 extension OverlayExt on GetInterface { 1268 extension OverlayExt on GetInterface {
@@ -1282,8 +1285,8 @@ extension OverlayExt on GetInterface { @@ -1282,8 +1285,8 @@ extension OverlayExt on GetInterface {
1282 }); 1285 });
1283 final overlayEntryLoader = OverlayEntry(builder: (context) { 1286 final overlayEntryLoader = OverlayEntry(builder: (context) {
1284 return loadingWidget ?? 1287 return loadingWidget ??
1285 - Center(  
1286 - child: Container( 1288 + const Center(
  1289 + child: SizedBox(
1287 height: 90, 1290 height: 90,
1288 width: 90, 1291 width: 90,
1289 child: Text('Loading...'), 1292 child: Text('Loading...'),
@@ -7,11 +7,10 @@ import '../../../get_instance/get_instance.dart'; @@ -7,11 +7,10 @@ import '../../../get_instance/get_instance.dart';
7 import '../../../get_state_manager/get_state_manager.dart'; 7 import '../../../get_state_manager/get_state_manager.dart';
8 import '../../../get_utils/get_utils.dart'; 8 import '../../../get_utils/get_utils.dart';
9 import '../../get_navigation.dart'; 9 import '../../get_navigation.dart';
10 -import '../router_report.dart'; 10 +import 'get_root.dart';
11 11
12 class GetCupertinoApp extends StatelessWidget { 12 class GetCupertinoApp extends StatelessWidget {
13 final GlobalKey<NavigatorState>? navigatorKey; 13 final GlobalKey<NavigatorState>? navigatorKey;
14 -  
15 final Widget? home; 14 final Widget? home;
16 final Map<String, WidgetBuilder>? routes; 15 final Map<String, WidgetBuilder>? routes;
17 final String? initialRoute; 16 final String? initialRoute;
@@ -66,7 +65,7 @@ class GetCupertinoApp extends StatelessWidget { @@ -66,7 +65,7 @@ class GetCupertinoApp extends StatelessWidget {
66 final List<Bind> binds; 65 final List<Bind> binds;
67 final ScrollBehavior? scrollBehavior; 66 final ScrollBehavior? scrollBehavior;
68 67
69 - GetCupertinoApp({ 68 + const GetCupertinoApp({
70 Key? key, 69 Key? key,
71 this.theme, 70 this.theme,
72 this.navigatorKey, 71 this.navigatorKey,
@@ -126,18 +125,7 @@ class GetCupertinoApp extends StatelessWidget { @@ -126,18 +125,7 @@ class GetCupertinoApp extends StatelessWidget {
126 routerDelegate = null, 125 routerDelegate = null,
127 super(key: key); 126 super(key: key);
128 127
129 - static String _cleanRouteName(String name) {  
130 - name = name.replaceAll('() => ', '');  
131 -  
132 - /// uncommonent for URL styling.  
133 - // name = name.paramCase!;  
134 - if (!name.startsWith('/')) {  
135 - name = '/$name';  
136 - }  
137 - return Uri.tryParse(name)?.toString() ?? name;  
138 - }  
139 -  
140 - GetCupertinoApp.router({ 128 + const GetCupertinoApp.router({
141 Key? key, 129 Key? key,
142 this.theme, 130 this.theme,
143 this.routeInformationProvider, 131 this.routeInformationProvider,
@@ -197,66 +185,52 @@ class GetCupertinoApp extends StatelessWidget { @@ -197,66 +185,52 @@ class GetCupertinoApp extends StatelessWidget {
197 185
198 @override 186 @override
199 Widget build(BuildContext context) { 187 Widget build(BuildContext context) {
200 - return Binds(  
201 - binds: [  
202 - Bind.lazyPut<GetMaterialController>(  
203 - () => GetMaterialController(  
204 - ConfigData(  
205 - backButtonDispatcher: backButtonDispatcher,  
206 - binds: binds,  
207 - customTransition: customTransition,  
208 - defaultGlobalState: defaultGlobalState,  
209 - defaultTransition: defaultTransition,  
210 - enableLog: enableLog,  
211 - fallbackLocale: fallbackLocale,  
212 - getPages: getPages,  
213 - home: home,  
214 - initialRoute: initialRoute,  
215 - locale: locale,  
216 - logWriterCallback: logWriterCallback,  
217 - navigatorKey: navigatorKey,  
218 - navigatorObservers: navigatorObservers,  
219 - onDispose: onDispose,  
220 - onInit: onInit,  
221 - onReady: onReady,  
222 - opaqueRoute: opaqueRoute,  
223 - popGesture: popGesture,  
224 - routeInformationParser: routeInformationParser,  
225 - routeInformationProvider: routeInformationProvider,  
226 - routerDelegate: routerDelegate,  
227 - routingCallback: routingCallback,  
228 - scaffoldMessengerKey: GlobalKey<ScaffoldMessengerState>(),  
229 - smartManagement: smartManagement,  
230 - transitionDuration: transitionDuration,  
231 - translations: translations,  
232 - translationsKeys: translationsKeys,  
233 - unknownRoute: unknownRoute,  
234 - ),  
235 - ),  
236 - onClose: () {  
237 - Get.clearTranslations();  
238 - RouterReportManager.dispose();  
239 - Get.resetInstance(clearRouteBindings: true);  
240 - },  
241 - ),  
242 - ...binds,  
243 - ], 188 + return GetRoot(
  189 + config: ConfigData(
  190 + backButtonDispatcher: backButtonDispatcher,
  191 + binds: binds,
  192 + customTransition: customTransition,
  193 + defaultGlobalState: defaultGlobalState,
  194 + defaultTransition: defaultTransition,
  195 + enableLog: enableLog,
  196 + fallbackLocale: fallbackLocale,
  197 + getPages: getPages,
  198 + home: home,
  199 + initialRoute: initialRoute,
  200 + locale: locale,
  201 + logWriterCallback: logWriterCallback,
  202 + navigatorKey: navigatorKey,
  203 + navigatorObservers: navigatorObservers,
  204 + onDispose: onDispose,
  205 + onInit: onInit,
  206 + onReady: onReady,
  207 + routeInformationParser: routeInformationParser,
  208 + routeInformationProvider: routeInformationProvider,
  209 + routerDelegate: routerDelegate,
  210 + routingCallback: routingCallback,
  211 + scaffoldMessengerKey: GlobalKey<ScaffoldMessengerState>(),
  212 + smartManagement: smartManagement,
  213 + transitionDuration: transitionDuration,
  214 + translations: translations,
  215 + translationsKeys: translationsKeys,
  216 + unknownRoute: unknownRoute,
  217 + ),
244 child: Builder(builder: (context) { 218 child: Builder(builder: (context) {
245 - final controller = context.listen<GetMaterialController>(); 219 + final controller = GetRoot.of(context);
246 return CupertinoApp.router( 220 return CupertinoApp.router(
247 - routerDelegate: controller.routerDelegate,  
248 - routeInformationParser: controller.routeInformationParser, 221 + routerDelegate: controller.config.routerDelegate,
  222 + routeInformationParser: controller.config.routeInformationParser,
249 backButtonDispatcher: backButtonDispatcher, 223 backButtonDispatcher: backButtonDispatcher,
250 routeInformationProvider: routeInformationProvider, 224 routeInformationProvider: routeInformationProvider,
251 - key: controller.unikey, 225 + key: controller.config.unikey,
252 builder: (context, child) => Directionality( 226 builder: (context, child) => Directionality(
253 textDirection: textDirection ?? 227 textDirection: textDirection ??
254 (rtlLanguages.contains(Get.locale?.languageCode) 228 (rtlLanguages.contains(Get.locale?.languageCode)
255 ? TextDirection.rtl 229 ? TextDirection.rtl
256 : TextDirection.ltr), 230 : TextDirection.ltr),
257 child: builder == null 231 child: builder == null
258 - ? (child ?? Material())  
259 - : builder!(context, child ?? Material()), 232 + ? (child ?? const Material())
  233 + : builder!(context, child ?? const Material()),
260 ), 234 ),
261 title: title, 235 title: title,
262 onGenerateTitle: onGenerateTitle, 236 onGenerateTitle: onGenerateTitle,
1 import 'package:flutter/foundation.dart'; 1 import 'package:flutter/foundation.dart';
2 import 'package:flutter/material.dart'; 2 import 'package:flutter/material.dart';
  3 +import 'package:get/instance_manager.dart';
3 4
4 -import '../../../get_core/get_core.dart';  
5 -import '../../../get_instance/get_instance.dart';  
6 import '../../../get_state_manager/get_state_manager.dart'; 5 import '../../../get_state_manager/get_state_manager.dart';
7 import '../../../get_utils/get_utils.dart'; 6 import '../../../get_utils/get_utils.dart';
8 import '../../get_navigation.dart'; 7 import '../../get_navigation.dart';
9 -import '../router_report.dart'; 8 +import 'get_root.dart';
10 9
11 class GetMaterialApp extends StatelessWidget { 10 class GetMaterialApp extends StatelessWidget {
12 final GlobalKey<NavigatorState>? navigatorKey; 11 final GlobalKey<NavigatorState>? navigatorKey;
@@ -130,7 +129,7 @@ class GetMaterialApp extends StatelessWidget { @@ -130,7 +129,7 @@ class GetMaterialApp extends StatelessWidget {
130 routerDelegate = null, 129 routerDelegate = null,
131 super(key: key); 130 super(key: key);
132 131
133 - GetMaterialApp.router({ 132 + const GetMaterialApp.router({
134 Key? key, 133 Key? key,
135 this.routeInformationProvider, 134 this.routeInformationProvider,
136 this.scaffoldMessengerKey, 135 this.scaffoldMessengerKey,
@@ -193,79 +192,79 @@ class GetMaterialApp extends StatelessWidget { @@ -193,79 +192,79 @@ class GetMaterialApp extends StatelessWidget {
193 192
194 @override 193 @override
195 Widget build(BuildContext context) { 194 Widget build(BuildContext context) {
196 - return Binds(  
197 - binds: [  
198 - Bind.lazyPut<GetMaterialController>(  
199 - () => GetMaterialController(  
200 - ConfigData(  
201 - backButtonDispatcher: backButtonDispatcher,  
202 - binds: binds,  
203 - customTransition: customTransition,  
204 - defaultGlobalState: defaultGlobalState,  
205 - defaultTransition: defaultTransition,  
206 - enableLog: enableLog,  
207 - fallbackLocale: fallbackLocale,  
208 - getPages: getPages,  
209 - home: home,  
210 - initialRoute: initialRoute,  
211 - locale: locale,  
212 - logWriterCallback: logWriterCallback,  
213 - navigatorKey: navigatorKey,  
214 - navigatorObservers: navigatorObservers,  
215 - onDispose: onDispose,  
216 - onInit: onInit,  
217 - onReady: onReady,  
218 - opaqueRoute: opaqueRoute,  
219 - popGesture: popGesture,  
220 - routeInformationParser: routeInformationParser,  
221 - routeInformationProvider: routeInformationProvider,  
222 - routerDelegate: routerDelegate,  
223 - routingCallback: routingCallback,  
224 - scaffoldMessengerKey: scaffoldMessengerKey,  
225 - smartManagement: smartManagement,  
226 - transitionDuration: transitionDuration,  
227 - translations: translations,  
228 - translationsKeys: translationsKeys,  
229 - unknownRoute: unknownRoute,  
230 - ),  
231 - ),  
232 - onClose: () {  
233 - Get.clearTranslations();  
234 - RouterReportManager.dispose();  
235 - Get.resetInstance(clearRouteBindings: true);  
236 - },  
237 - ),  
238 - ...binds,  
239 - ], 195 + return GetRoot(
  196 + config: ConfigData(
  197 + backButtonDispatcher: backButtonDispatcher,
  198 + binds: binds,
  199 + customTransition: customTransition,
  200 + defaultGlobalState: defaultGlobalState,
  201 + defaultTransition: defaultTransition,
  202 + enableLog: enableLog,
  203 + fallbackLocale: fallbackLocale,
  204 + getPages: getPages,
  205 + home: home,
  206 + initialRoute: initialRoute,
  207 + locale: locale,
  208 + logWriterCallback: logWriterCallback,
  209 + navigatorKey: navigatorKey,
  210 + navigatorObservers: navigatorObservers,
  211 + onDispose: onDispose,
  212 + onInit: onInit,
  213 + onReady: onReady,
  214 + routeInformationParser: routeInformationParser,
  215 + routeInformationProvider: routeInformationProvider,
  216 + routerDelegate: routerDelegate,
  217 + routingCallback: routingCallback,
  218 + scaffoldMessengerKey: scaffoldMessengerKey,
  219 + smartManagement: smartManagement,
  220 + transitionDuration: transitionDuration,
  221 + translations: translations,
  222 + translationsKeys: translationsKeys,
  223 + unknownRoute: unknownRoute,
  224 + theme: theme,
  225 + darkTheme: darkTheme,
  226 + themeMode: themeMode,
  227 + ),
  228 + // binds: [
  229 + // Bind.lazyPut<GetMaterialController>(
  230 + // () => GetMaterialController(
  231 +
  232 + // ),
  233 + // onClose: () {
  234 + // Get.clearTranslations();
  235 + // RouterReportManager.dispose();
  236 + // Get.resetInstance(clearRouteBindings: true);
  237 + // },
  238 + // ),
  239 + // ...binds,
  240 + // ],
240 child: Builder(builder: (context) { 241 child: Builder(builder: (context) {
241 - final controller = context.listen<GetMaterialController>(); 242 + final controller = GetRoot.of(context);
242 return MaterialApp.router( 243 return MaterialApp.router(
243 - routerDelegate: controller.routerDelegate,  
244 - routeInformationParser: controller.routeInformationParser, 244 + routerDelegate: controller.config.routerDelegate,
  245 + routeInformationParser: controller.config.routeInformationParser,
245 backButtonDispatcher: backButtonDispatcher, 246 backButtonDispatcher: backButtonDispatcher,
246 routeInformationProvider: routeInformationProvider, 247 routeInformationProvider: routeInformationProvider,
247 - key: controller.unikey, 248 + key: controller.config.unikey,
248 builder: (context, child) => Directionality( 249 builder: (context, child) => Directionality(
249 textDirection: textDirection ?? 250 textDirection: textDirection ??
250 (rtlLanguages.contains(Get.locale?.languageCode) 251 (rtlLanguages.contains(Get.locale?.languageCode)
251 ? TextDirection.rtl 252 ? TextDirection.rtl
252 : TextDirection.ltr), 253 : TextDirection.ltr),
253 child: builder == null 254 child: builder == null
254 - ? (child ?? Material())  
255 - : builder!(context, child ?? Material()), 255 + ? (child ?? const Material())
  256 + : builder!(context, child ?? const Material()),
256 ), 257 ),
257 title: title, 258 title: title,
258 onGenerateTitle: onGenerateTitle, 259 onGenerateTitle: onGenerateTitle,
259 color: color, 260 color: color,
260 - theme: controller.theme ?? theme ?? ThemeData.fallback(),  
261 - darkTheme: controller.darkTheme ??  
262 - darkTheme ??  
263 - theme ?? 261 + theme: controller.config.theme ?? ThemeData.fallback(),
  262 + darkTheme: controller.config.darkTheme ??
  263 + controller.config.theme ??
264 ThemeData.fallback(), 264 ThemeData.fallback(),
265 - themeMode: controller.themeMode ?? themeMode, 265 + themeMode: controller.config.themeMode,
266 locale: Get.locale ?? locale, 266 locale: Get.locale ?? locale,
267 - scaffoldMessengerKey:  
268 - scaffoldMessengerKey ?? controller.scaffoldMessengerKey, 267 + scaffoldMessengerKey: controller.config.scaffoldMessengerKey,
269 localizationsDelegates: localizationsDelegates, 268 localizationsDelegates: localizationsDelegates,
270 localeListResolutionCallback: localeListResolutionCallback, 269 localeListResolutionCallback: localeListResolutionCallback,
271 localeResolutionCallback: localeResolutionCallback, 270 localeResolutionCallback: localeResolutionCallback,
  1 +import 'package:flutter/foundation.dart';
  2 +import 'package:flutter/material.dart';
  3 +
  4 +import '../../../get.dart';
  5 +import '../router_report.dart';
  6 +
  7 +class ConfigData {
  8 + final ValueChanged<Routing?>? routingCallback;
  9 + final Transition? defaultTransition;
  10 + final VoidCallback? onInit;
  11 + final VoidCallback? onReady;
  12 + final VoidCallback? onDispose;
  13 + final bool? enableLog;
  14 + final LogWriterCallback? logWriterCallback;
  15 + final SmartManagement smartManagement;
  16 + final List<Bind> binds;
  17 + final Duration? transitionDuration;
  18 + final bool? defaultGlobalState;
  19 + final List<GetPage>? getPages;
  20 + final GetPage? unknownRoute;
  21 + final RouteInformationProvider? routeInformationProvider;
  22 + final RouteInformationParser<Object>? routeInformationParser;
  23 + final RouterDelegate<Object>? routerDelegate;
  24 + final BackButtonDispatcher? backButtonDispatcher;
  25 + final List<NavigatorObserver>? navigatorObservers;
  26 + final GlobalKey<NavigatorState>? navigatorKey;
  27 + final GlobalKey<ScaffoldMessengerState>? scaffoldMessengerKey;
  28 + final Map<String, Map<String, String>>? translationsKeys;
  29 + final Translations? translations;
  30 + final Locale? locale;
  31 + final Locale? fallbackLocale;
  32 + final String? initialRoute;
  33 + final CustomTransition? customTransition;
  34 + final Widget? home;
  35 + final bool testMode;
  36 + final Key? unikey;
  37 + final ThemeData? theme;
  38 + final ThemeData? darkTheme;
  39 + final ThemeMode? themeMode;
  40 + final bool defaultPopGesture;
  41 + final bool defaultOpaqueRoute;
  42 + final Duration defaultTransitionDuration;
  43 + final Curve defaultTransitionCurve;
  44 + final Curve defaultDialogTransitionCurve;
  45 + final Duration defaultDialogTransitionDuration;
  46 + final Routing routing;
  47 + final Map<String, String?> parameters;
  48 +
  49 + ConfigData({
  50 + required this.routingCallback,
  51 + required this.defaultTransition,
  52 + required this.onInit,
  53 + required this.onReady,
  54 + required this.onDispose,
  55 + required this.enableLog,
  56 + required this.logWriterCallback,
  57 + required this.smartManagement,
  58 + required this.binds,
  59 + required this.transitionDuration,
  60 + required this.defaultGlobalState,
  61 + required this.getPages,
  62 + required this.unknownRoute,
  63 + required this.routeInformationProvider,
  64 + required this.routeInformationParser,
  65 + required this.routerDelegate,
  66 + required this.backButtonDispatcher,
  67 + required this.navigatorObservers,
  68 + required this.navigatorKey,
  69 + required this.scaffoldMessengerKey,
  70 + required this.translationsKeys,
  71 + required this.translations,
  72 + required this.locale,
  73 + required this.fallbackLocale,
  74 + required this.initialRoute,
  75 + required this.customTransition,
  76 + required this.home,
  77 + this.theme,
  78 + this.darkTheme,
  79 + this.themeMode,
  80 + this.unikey,
  81 + this.testMode = false,
  82 + this.defaultOpaqueRoute = true,
  83 + this.defaultTransitionDuration = const Duration(milliseconds: 300),
  84 + this.defaultTransitionCurve = Curves.easeOutQuad,
  85 + this.defaultDialogTransitionCurve = Curves.easeOutQuad,
  86 + this.defaultDialogTransitionDuration = const Duration(milliseconds: 300),
  87 + this.parameters = const {},
  88 + Routing? routing,
  89 + bool? defaultPopGesture,
  90 + }) : defaultPopGesture = defaultPopGesture ?? GetPlatform.isIOS,
  91 + routing = routing ?? Routing();
  92 +
  93 + ConfigData copyWith({
  94 + ValueChanged<Routing?>? routingCallback,
  95 + Transition? defaultTransition,
  96 + VoidCallback? onInit,
  97 + VoidCallback? onReady,
  98 + VoidCallback? onDispose,
  99 + bool? enableLog,
  100 + LogWriterCallback? logWriterCallback,
  101 + SmartManagement? smartManagement,
  102 + List<Bind>? binds,
  103 + Duration? transitionDuration,
  104 + bool? defaultGlobalState,
  105 + List<GetPage>? getPages,
  106 + GetPage? unknownRoute,
  107 + RouteInformationProvider? routeInformationProvider,
  108 + RouteInformationParser<Object>? routeInformationParser,
  109 + RouterDelegate<Object>? routerDelegate,
  110 + BackButtonDispatcher? backButtonDispatcher,
  111 + List<NavigatorObserver>? navigatorObservers,
  112 + GlobalKey<NavigatorState>? navigatorKey,
  113 + GlobalKey<ScaffoldMessengerState>? scaffoldMessengerKey,
  114 + Map<String, Map<String, String>>? translationsKeys,
  115 + Translations? translations,
  116 + Locale? locale,
  117 + Locale? fallbackLocale,
  118 + String? initialRoute,
  119 + CustomTransition? customTransition,
  120 + Widget? home,
  121 + bool? testMode,
  122 + Key? unikey,
  123 + ThemeData? theme,
  124 + ThemeData? darkTheme,
  125 + ThemeMode? themeMode,
  126 + bool? defaultPopGesture,
  127 + bool? defaultOpaqueRoute,
  128 + Duration? defaultTransitionDuration,
  129 + Curve? defaultTransitionCurve,
  130 + Curve? defaultDialogTransitionCurve,
  131 + Duration? defaultDialogTransitionDuration,
  132 + Routing? routing,
  133 + Map<String, String?>? parameters,
  134 + }) {
  135 + return ConfigData(
  136 + routingCallback: routingCallback ?? this.routingCallback,
  137 + defaultTransition: defaultTransition ?? this.defaultTransition,
  138 + onInit: onInit ?? this.onInit,
  139 + onReady: onReady ?? this.onReady,
  140 + onDispose: onDispose ?? this.onDispose,
  141 + enableLog: enableLog ?? this.enableLog,
  142 + logWriterCallback: logWriterCallback ?? this.logWriterCallback,
  143 + smartManagement: smartManagement ?? this.smartManagement,
  144 + binds: binds ?? this.binds,
  145 + transitionDuration: transitionDuration ?? this.transitionDuration,
  146 + defaultGlobalState: defaultGlobalState ?? this.defaultGlobalState,
  147 + getPages: getPages ?? this.getPages,
  148 + unknownRoute: unknownRoute ?? this.unknownRoute,
  149 + routeInformationProvider:
  150 + routeInformationProvider ?? this.routeInformationProvider,
  151 + routeInformationParser:
  152 + routeInformationParser ?? this.routeInformationParser,
  153 + routerDelegate: routerDelegate ?? this.routerDelegate,
  154 + backButtonDispatcher: backButtonDispatcher ?? this.backButtonDispatcher,
  155 + navigatorObservers: navigatorObservers ?? this.navigatorObservers,
  156 + navigatorKey: navigatorKey ?? this.navigatorKey,
  157 + scaffoldMessengerKey: scaffoldMessengerKey ?? this.scaffoldMessengerKey,
  158 + translationsKeys: translationsKeys ?? this.translationsKeys,
  159 + translations: translations ?? this.translations,
  160 + locale: locale ?? this.locale,
  161 + fallbackLocale: fallbackLocale ?? this.fallbackLocale,
  162 + initialRoute: initialRoute ?? this.initialRoute,
  163 + customTransition: customTransition ?? this.customTransition,
  164 + home: home ?? this.home,
  165 + testMode: testMode ?? this.testMode,
  166 + unikey: unikey ?? this.unikey,
  167 + theme: theme ?? this.theme,
  168 + darkTheme: darkTheme ?? this.darkTheme,
  169 + themeMode: themeMode ?? this.themeMode,
  170 + defaultPopGesture: defaultPopGesture ?? this.defaultPopGesture,
  171 + defaultOpaqueRoute: defaultOpaqueRoute ?? this.defaultOpaqueRoute,
  172 + defaultTransitionDuration:
  173 + defaultTransitionDuration ?? this.defaultTransitionDuration,
  174 + defaultTransitionCurve:
  175 + defaultTransitionCurve ?? this.defaultTransitionCurve,
  176 + defaultDialogTransitionCurve:
  177 + defaultDialogTransitionCurve ?? this.defaultDialogTransitionCurve,
  178 + defaultDialogTransitionDuration: defaultDialogTransitionDuration ??
  179 + this.defaultDialogTransitionDuration,
  180 + routing: routing ?? this.routing,
  181 + parameters: parameters ?? this.parameters,
  182 + );
  183 + }
  184 +
  185 + @override
  186 + bool operator ==(Object other) {
  187 + if (identical(this, other)) return true;
  188 +
  189 + return other is ConfigData &&
  190 + other.routingCallback == routingCallback &&
  191 + other.defaultTransition == defaultTransition &&
  192 + other.onInit == onInit &&
  193 + other.onReady == onReady &&
  194 + other.onDispose == onDispose &&
  195 + other.enableLog == enableLog &&
  196 + other.logWriterCallback == logWriterCallback &&
  197 + other.smartManagement == smartManagement &&
  198 + listEquals(other.binds, binds) &&
  199 + other.transitionDuration == transitionDuration &&
  200 + other.defaultGlobalState == defaultGlobalState &&
  201 + listEquals(other.getPages, getPages) &&
  202 + other.unknownRoute == unknownRoute &&
  203 + other.routeInformationProvider == routeInformationProvider &&
  204 + other.routeInformationParser == routeInformationParser &&
  205 + other.routerDelegate == routerDelegate &&
  206 + other.backButtonDispatcher == backButtonDispatcher &&
  207 + listEquals(other.navigatorObservers, navigatorObservers) &&
  208 + other.navigatorKey == navigatorKey &&
  209 + other.scaffoldMessengerKey == scaffoldMessengerKey &&
  210 + mapEquals(other.translationsKeys, translationsKeys) &&
  211 + other.translations == translations &&
  212 + other.locale == locale &&
  213 + other.fallbackLocale == fallbackLocale &&
  214 + other.initialRoute == initialRoute &&
  215 + other.customTransition == customTransition &&
  216 + other.home == home &&
  217 + other.testMode == testMode &&
  218 + other.unikey == unikey &&
  219 + other.theme == theme &&
  220 + other.darkTheme == darkTheme &&
  221 + other.themeMode == themeMode &&
  222 + other.defaultPopGesture == defaultPopGesture &&
  223 + other.defaultOpaqueRoute == defaultOpaqueRoute &&
  224 + other.defaultTransitionDuration == defaultTransitionDuration &&
  225 + other.defaultTransitionCurve == defaultTransitionCurve &&
  226 + other.defaultDialogTransitionCurve == defaultDialogTransitionCurve &&
  227 + other.defaultDialogTransitionDuration ==
  228 + defaultDialogTransitionDuration &&
  229 + other.routing == routing &&
  230 + mapEquals(other.parameters, parameters);
  231 + }
  232 +
  233 + @override
  234 + int get hashCode {
  235 + return routingCallback.hashCode ^
  236 + defaultTransition.hashCode ^
  237 + onInit.hashCode ^
  238 + onReady.hashCode ^
  239 + onDispose.hashCode ^
  240 + enableLog.hashCode ^
  241 + logWriterCallback.hashCode ^
  242 + smartManagement.hashCode ^
  243 + binds.hashCode ^
  244 + transitionDuration.hashCode ^
  245 + defaultGlobalState.hashCode ^
  246 + getPages.hashCode ^
  247 + unknownRoute.hashCode ^
  248 + routeInformationProvider.hashCode ^
  249 + routeInformationParser.hashCode ^
  250 + routerDelegate.hashCode ^
  251 + backButtonDispatcher.hashCode ^
  252 + navigatorObservers.hashCode ^
  253 + navigatorKey.hashCode ^
  254 + scaffoldMessengerKey.hashCode ^
  255 + translationsKeys.hashCode ^
  256 + translations.hashCode ^
  257 + locale.hashCode ^
  258 + fallbackLocale.hashCode ^
  259 + initialRoute.hashCode ^
  260 + customTransition.hashCode ^
  261 + home.hashCode ^
  262 + testMode.hashCode ^
  263 + unikey.hashCode ^
  264 + theme.hashCode ^
  265 + darkTheme.hashCode ^
  266 + themeMode.hashCode ^
  267 + defaultPopGesture.hashCode ^
  268 + defaultOpaqueRoute.hashCode ^
  269 + defaultTransitionDuration.hashCode ^
  270 + defaultTransitionCurve.hashCode ^
  271 + defaultDialogTransitionCurve.hashCode ^
  272 + defaultDialogTransitionDuration.hashCode ^
  273 + routing.hashCode ^
  274 + parameters.hashCode;
  275 + }
  276 +}
  277 +
  278 +class GetRoot extends StatefulWidget {
  279 + const GetRoot({
  280 + Key? key,
  281 + required this.config,
  282 + required this.child,
  283 + }) : super(key: key);
  284 + final ConfigData config;
  285 + final Widget child;
  286 + @override
  287 + State<GetRoot> createState() => GetRootState();
  288 +
  289 + static GetRootState of(BuildContext context) {
  290 + // Handles the case where the input context is a navigator element.
  291 + GetRootState? root;
  292 + if (context is StatefulElement && context.state is GetRootState) {
  293 + root = context.state as GetRootState;
  294 + }
  295 + root = context.findRootAncestorStateOfType<GetRootState>() ?? root;
  296 + assert(() {
  297 + if (root == null) {
  298 + throw FlutterError(
  299 + 'GetRoot operation requested with a context that does not include a GetRoot.\n'
  300 + 'The context used must be that of a '
  301 + 'widget that is a descendant of a GetRoot widget.',
  302 + );
  303 + }
  304 + return true;
  305 + }());
  306 + return root!;
  307 + }
  308 +}
  309 +
  310 +class GetRootState extends State<GetRoot> with WidgetsBindingObserver {
  311 + static GetRootState? _controller;
  312 + static GetRootState get controller {
  313 + if (_controller == null) {
  314 + throw Exception('GetRoot is not part of the three');
  315 + } else {
  316 + return _controller!;
  317 + }
  318 + }
  319 +
  320 + late ConfigData config;
  321 +
  322 + @override
  323 + void initState() {
  324 + config = widget.config;
  325 + GetRootState._controller = this;
  326 + ambiguate(Engine.instance)!.addObserver(this);
  327 + onInit();
  328 + super.initState();
  329 + }
  330 +
  331 + // @override
  332 + // void didUpdateWidget(covariant GetRoot oldWidget) {
  333 + // if (oldWidget.config != widget.config) {
  334 + // config = widget.config;
  335 + // }
  336 +
  337 + // super.didUpdateWidget(oldWidget);
  338 + // }
  339 +
  340 + void onClose() {
  341 + config.onDispose?.call();
  342 + Get.clearTranslations();
  343 + RouterReportManager.instance.clearRouteKeys();
  344 + RouterReportManager.dispose();
  345 + Get.resetInstance(clearRouteBindings: true);
  346 + _controller = null;
  347 + ambiguate(Engine.instance)!.removeObserver(this);
  348 + }
  349 +
  350 + @override
  351 + void dispose() {
  352 + onClose();
  353 + super.dispose();
  354 + }
  355 +
  356 + void onInit() {
  357 + if (config.getPages == null && config.home == null) {
  358 + throw 'You need add pages or home';
  359 + }
  360 +
  361 + if (config.routerDelegate == null) {
  362 + final newDelegate = GetDelegate.createDelegate(
  363 + pages: config.getPages ??
  364 + [
  365 + GetPage(
  366 + name: cleanRouteName("/${config.home.runtimeType}"),
  367 + page: () => config.home!,
  368 + ),
  369 + ],
  370 + notFoundRoute: config.unknownRoute,
  371 + navigatorKey: config.navigatorKey,
  372 + navigatorObservers: (config.navigatorObservers == null
  373 + ? <NavigatorObserver>[
  374 + GetObserver(config.routingCallback, Get.routing)
  375 + ]
  376 + : <NavigatorObserver>[
  377 + GetObserver(config.routingCallback, config.routing),
  378 + ...config.navigatorObservers!
  379 + ]),
  380 + );
  381 + config = config.copyWith(routerDelegate: newDelegate);
  382 + }
  383 +
  384 + if (config.routeInformationParser == null) {
  385 + final newRouteInformationParser =
  386 + GetInformationParser.createInformationParser(
  387 + initialRoute: config.initialRoute ??
  388 + config.getPages?.first.name ??
  389 + cleanRouteName("/${config.home.runtimeType}"),
  390 + );
  391 +
  392 + config =
  393 + config.copyWith(routeInformationParser: newRouteInformationParser);
  394 + }
  395 +
  396 + if (config.locale != null) Get.locale = config.locale;
  397 +
  398 + if (config.fallbackLocale != null) {
  399 + Get.fallbackLocale = config.fallbackLocale;
  400 + }
  401 +
  402 + if (config.translations != null) {
  403 + Get.addTranslations(config.translations!.keys);
  404 + } else if (config.translationsKeys != null) {
  405 + Get.addTranslations(config.translationsKeys!);
  406 + }
  407 +
  408 + Get.smartManagement = config.smartManagement;
  409 + config.onInit?.call();
  410 +
  411 + Get.isLogEnable = config.enableLog ?? kDebugMode;
  412 + Get.log = config.logWriterCallback ?? defaultLogWriterCallback;
  413 +
  414 + if (config.defaultTransition == null) {
  415 + config = config.copyWith(defaultTransition: getThemeTransition());
  416 + }
  417 +
  418 + // defaultOpaqueRoute = config.opaqueRoute ?? true;
  419 + // defaultPopGesture = config.popGesture ?? GetPlatform.isIOS;
  420 + // defaultTransitionDuration =
  421 + // config.transitionDuration ?? Duration(milliseconds: 300);
  422 +
  423 + Future(() => onReady());
  424 + }
  425 +
  426 + set parameters(Map<String, String?> newParameters) {
  427 + // rootController.parameters = newParameters;
  428 + config = config.copyWith(parameters: newParameters);
  429 + }
  430 +
  431 + set testMode(bool isTest) {
  432 + config = config.copyWith(testMode: isTest);
  433 + // _getxController.testMode = isTest;
  434 + }
  435 +
  436 + void onReady() {
  437 + config.onReady?.call();
  438 + }
  439 +
  440 + Transition? getThemeTransition() {
  441 + final platform = Get.theme.platform;
  442 + final matchingTransition =
  443 + Get.theme.pageTransitionsTheme.builders[platform];
  444 + switch (matchingTransition) {
  445 + case CupertinoPageTransitionsBuilder():
  446 + return Transition.cupertino;
  447 + case ZoomPageTransitionsBuilder():
  448 + return Transition.zoom;
  449 + case FadeUpwardsPageTransitionsBuilder():
  450 + return Transition.fade;
  451 + case OpenUpwardsPageTransitionsBuilder():
  452 + return Transition.native;
  453 + default:
  454 + return null;
  455 + }
  456 + }
  457 +
  458 + @override
  459 + void didChangeLocales(List<Locale>? locales) {
  460 + Get.asap(() {
  461 + final locale = Get.deviceLocale;
  462 + if (locale != null) {
  463 + Get.updateLocale(locale);
  464 + }
  465 + });
  466 + }
  467 +
  468 + void setTheme(ThemeData value) {
  469 + if (config.darkTheme == null) {
  470 + config = config.copyWith(theme: value);
  471 + } else {
  472 + if (value.brightness == Brightness.light) {
  473 + config = config.copyWith(theme: value);
  474 + } else {
  475 + config = config.copyWith(darkTheme: value);
  476 + }
  477 + }
  478 + update();
  479 + }
  480 +
  481 + void setThemeMode(ThemeMode value) {
  482 + config = config.copyWith(themeMode: value);
  483 + update();
  484 + }
  485 +
  486 + void restartApp() {
  487 + config = config.copyWith(unikey: UniqueKey());
  488 + update();
  489 + }
  490 +
  491 + void update() {
  492 + setState(() {});
  493 + }
  494 +
  495 + GlobalKey<NavigatorState> get key => rootDelegate.navigatorKey;
  496 +
  497 + GetDelegate get rootDelegate => config.routerDelegate as GetDelegate;
  498 +
  499 + RouteInformationParser<Object> get informationParser =>
  500 + config.routeInformationParser!;
  501 +
  502 + GlobalKey<NavigatorState>? addKey(GlobalKey<NavigatorState> newKey) {
  503 + rootDelegate.navigatorKey = newKey;
  504 + return key;
  505 + }
  506 +
  507 + Map<dynamic, GetDelegate> keys = {};
  508 +
  509 + GetDelegate? nestedKey(String? key) {
  510 + if (key == null) {
  511 + return rootDelegate;
  512 + }
  513 + keys.putIfAbsent(
  514 + key,
  515 + () => GetDelegate(
  516 + showHashOnUrl: true,
  517 + //debugLabel: 'Getx nested key: ${key.toString()}',
  518 + pages: RouteDecoder.fromRoute(key).currentChildrens ?? [],
  519 + ),
  520 + );
  521 + return keys[key];
  522 + }
  523 +
  524 + @override
  525 + Widget build(BuildContext context) {
  526 + return widget.child;
  527 + }
  528 +
  529 + String cleanRouteName(String name) {
  530 + name = name.replaceAll('() => ', '');
  531 +
  532 + /// uncommonent for URL styling.
  533 + // name = name.paramCase!;
  534 + if (!name.startsWith('/')) {
  535 + name = '/$name';
  536 + }
  537 + return Uri.tryParse(name)?.toString() ?? name;
  538 + }
  539 +}
1 -import 'package:flutter/foundation.dart';  
2 -import 'package:flutter/material.dart';  
3 -  
4 -import '../../../get.dart';  
5 -  
6 -class ConfigData {  
7 - final ValueChanged<Routing?>? routingCallback;  
8 - final Transition? defaultTransition;  
9 - final bool? opaqueRoute;  
10 - final VoidCallback? onInit;  
11 - final VoidCallback? onReady;  
12 - final VoidCallback? onDispose;  
13 - final bool? enableLog;  
14 - final LogWriterCallback? logWriterCallback;  
15 - final bool? popGesture;  
16 - final SmartManagement smartManagement;  
17 - final List<Bind> binds;  
18 - final Duration? transitionDuration;  
19 - final bool? defaultGlobalState;  
20 - final List<GetPage>? getPages;  
21 - final GetPage? unknownRoute;  
22 - final RouteInformationProvider? routeInformationProvider;  
23 - final RouteInformationParser<Object>? routeInformationParser;  
24 - final RouterDelegate<Object>? routerDelegate;  
25 - final BackButtonDispatcher? backButtonDispatcher;  
26 - final List<NavigatorObserver>? navigatorObservers;  
27 - final GlobalKey<NavigatorState>? navigatorKey;  
28 - final GlobalKey<ScaffoldMessengerState>? scaffoldMessengerKey;  
29 - final Map<String, Map<String, String>>? translationsKeys;  
30 - final Translations? translations;  
31 - final Locale? locale;  
32 - final Locale? fallbackLocale;  
33 - final String? initialRoute;  
34 - final CustomTransition? customTransition;  
35 - final Widget? home;  
36 -  
37 - ConfigData({  
38 - required this.routingCallback,  
39 - required this.defaultTransition,  
40 - required this.opaqueRoute,  
41 - required this.onInit,  
42 - required this.onReady,  
43 - required this.onDispose,  
44 - required this.enableLog,  
45 - required this.logWriterCallback,  
46 - required this.popGesture,  
47 - required this.smartManagement,  
48 - required this.binds,  
49 - required this.transitionDuration,  
50 - required this.defaultGlobalState,  
51 - required this.getPages,  
52 - required this.unknownRoute,  
53 - required this.routeInformationProvider,  
54 - required this.routeInformationParser,  
55 - required this.routerDelegate,  
56 - required this.backButtonDispatcher,  
57 - required this.navigatorObservers,  
58 - required this.navigatorKey,  
59 - required this.scaffoldMessengerKey,  
60 - required this.translationsKeys,  
61 - required this.translations,  
62 - required this.locale,  
63 - required this.fallbackLocale,  
64 - required this.initialRoute,  
65 - required this.customTransition,  
66 - required this.home,  
67 - });  
68 -}  
69 -  
70 -class GetMaterialController extends FullLifeCycleController {  
71 - GetMaterialController(this.config);  
72 -  
73 - late final RouterDelegate<Object> routerDelegate;  
74 - late final RouteInformationParser<Object> routeInformationParser;  
75 - final ConfigData config;  
76 -  
77 - @override  
78 - void onReady() {  
79 - config.onReady?.call();  
80 - super.onReady();  
81 - }  
82 -  
83 - @override  
84 - void onInit() {  
85 - super.onInit();  
86 -  
87 - if (config.getPages == null && config.home == null) {  
88 - throw 'You need add pages or home';  
89 - }  
90 - print('route delefate from onInit');  
91 - routerDelegate = config.routerDelegate ??  
92 - createDelegate(  
93 - pages: config.getPages ??  
94 - [  
95 - GetPage(  
96 - name: cleanRouteName("/${config.home.runtimeType}"),  
97 - page: () => config.home!,  
98 - ),  
99 - ],  
100 - notFoundRoute: config.unknownRoute,  
101 - navigatorKey: config.navigatorKey,  
102 - navigatorObservers: (config.navigatorObservers == null  
103 - ? <NavigatorObserver>[  
104 - GetObserver(config.routingCallback, Get.routing)  
105 - ]  
106 - : <NavigatorObserver>[  
107 - GetObserver(config.routingCallback, routing),  
108 - ...config.navigatorObservers!  
109 - ]),  
110 - );  
111 -  
112 - routeInformationParser = config.routeInformationParser ??  
113 - createInformationParser(  
114 - initialRoute: config.initialRoute ??  
115 - config.getPages?.first.name ??  
116 - cleanRouteName("/${config.home.runtimeType}"),  
117 - );  
118 -  
119 - if (config.locale != null) Get.locale = config.locale;  
120 -  
121 - if (config.fallbackLocale != null) {  
122 - Get.fallbackLocale = config.fallbackLocale;  
123 - }  
124 -  
125 - if (config.translations != null) {  
126 - Get.addTranslations(config.translations!.keys);  
127 - } else if (config.translationsKeys != null) {  
128 - Get.addTranslations(config.translationsKeys!);  
129 - }  
130 -  
131 - customTransition = config.customTransition;  
132 -  
133 - Get.smartManagement = config.smartManagement;  
134 - config.onInit?.call();  
135 -  
136 - Get.isLogEnable = config.enableLog ?? kDebugMode;  
137 - Get.log = config.logWriterCallback ?? defaultLogWriterCallback;  
138 - defaultTransition = config.defaultTransition ?? getThemeTransition();  
139 - defaultOpaqueRoute = config.opaqueRoute ?? true;  
140 - defaultPopGesture = config.popGesture ?? GetPlatform.isIOS;  
141 - defaultTransitionDuration =  
142 - config.transitionDuration ?? Duration(milliseconds: 300);  
143 - }  
144 -  
145 - Transition? getThemeTransition() {  
146 - final platform = Get.theme.platform;  
147 - final matchingTransition =  
148 - Get.theme.pageTransitionsTheme.builders[platform];  
149 - switch (matchingTransition) {  
150 - case CupertinoPageTransitionsBuilder():  
151 - return Transition.cupertino;  
152 - case ZoomPageTransitionsBuilder():  
153 - return Transition.zoom;  
154 - case FadeUpwardsPageTransitionsBuilder():  
155 - return Transition.fade;  
156 - case OpenUpwardsPageTransitionsBuilder():  
157 - return Transition.native;  
158 - default:  
159 - return null;  
160 - }  
161 - }  
162 -  
163 - String cleanRouteName(String name) {  
164 - name = name.replaceAll('() => ', '');  
165 -  
166 - /// uncommonent for URL styling.  
167 - // name = name.paramCase!;  
168 - if (!name.startsWith('/')) {  
169 - name = '/$name';  
170 - }  
171 - return Uri.tryParse(name)?.toString() ?? name;  
172 - }  
173 -  
174 - bool testMode = false;  
175 - Key? unikey;  
176 - ThemeData? theme;  
177 - ThemeData? darkTheme;  
178 - ThemeMode? themeMode;  
179 -  
180 - final scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();  
181 -  
182 - bool defaultPopGesture = GetPlatform.isIOS;  
183 - bool defaultOpaqueRoute = true;  
184 - Transition? defaultTransition;  
185 - Duration defaultTransitionDuration = Duration(milliseconds: 300);  
186 - Curve defaultTransitionCurve = Curves.easeOutQuad;  
187 - Curve defaultDialogTransitionCurve = Curves.easeOutQuad;  
188 - Duration defaultDialogTransitionDuration = Duration(milliseconds: 300);  
189 -  
190 - final routing = Routing();  
191 -  
192 - Map<String, String?> parameters = {};  
193 - CustomTransition? customTransition;  
194 -  
195 - Map<dynamic, GetDelegate> keys = {};  
196 -  
197 - GlobalKey<NavigatorState> get key => rootDelegate.navigatorKey;  
198 -  
199 - GetDelegate get rootDelegate => routerDelegate as GetDelegate;  
200 -  
201 - GlobalKey<NavigatorState>? addKey(GlobalKey<NavigatorState> newKey) {  
202 - rootDelegate.navigatorKey = newKey;  
203 - return key;  
204 - }  
205 -  
206 - @override  
207 - void didChangeLocales(List<Locale>? locales) {  
208 - Get.asap(() {  
209 - final locale = Get.deviceLocale;  
210 - if (locale != null) {  
211 - Get.updateLocale(locale);  
212 - }  
213 - });  
214 - }  
215 -  
216 - void restartApp() {  
217 - unikey = UniqueKey();  
218 - update();  
219 - }  
220 -  
221 - void setTheme(ThemeData value) {  
222 - if (darkTheme == null) {  
223 - theme = value;  
224 - } else {  
225 - if (value.brightness == Brightness.light) {  
226 - theme = value;  
227 - } else {  
228 - darkTheme = value;  
229 - }  
230 - }  
231 - update();  
232 - }  
233 -  
234 - void setThemeMode(ThemeMode value) {  
235 - themeMode = value;  
236 - update();  
237 - }  
238 -  
239 - GetDelegate? nestedKey(String? key) {  
240 - if (key == null) {  
241 - return routerDelegate as GetDelegate;  
242 - }  
243 - keys.putIfAbsent(  
244 - key,  
245 - () => GetDelegate(  
246 - showHashOnUrl: true,  
247 - //debugLabel: 'Getx nested key: ${key.toString()}',  
248 - pages: RouteDecoder.fromRoute(key).currentChildrens ?? [],  
249 - ),  
250 - );  
251 - return keys[key];  
252 - }  
253 -  
254 - GetInformationParser createInformationParser({String initialRoute = '/'}) {  
255 - return GetInformationParser(  
256 - initialRoute: initialRoute,  
257 - );  
258 - }  
259 -  
260 - GetDelegate createDelegate({  
261 - GetPage<dynamic>? notFoundRoute,  
262 - List<GetPage> pages = const [],  
263 - List<NavigatorObserver>? navigatorObservers,  
264 - TransitionDelegate<dynamic>? transitionDelegate,  
265 - PopMode backButtonPopMode = PopMode.history,  
266 - PreventDuplicateHandlingMode preventDuplicateHandlingMode =  
267 - PreventDuplicateHandlingMode.reorderRoutes,  
268 - GlobalKey<NavigatorState>? navigatorKey,  
269 - }) {  
270 - return GetDelegate(  
271 - notFoundRoute: notFoundRoute,  
272 - navigatorObservers: navigatorObservers,  
273 - transitionDelegate: transitionDelegate,  
274 - backButtonPopMode: backButtonPopMode,  
275 - preventDuplicateHandlingMode: preventDuplicateHandlingMode,  
276 - pages: pages,  
277 - navigatorKey: navigatorKey,  
278 - );  
279 - }  
280 -}  
1 import 'dart:collection'; 1 import 'dart:collection';
2 2
3 -import 'package:flutter/widgets.dart';  
4 -  
5 import '../../get.dart'; 3 import '../../get.dart';
6 4
7 class RouterReportManager<T> { 5 class RouterReportManager<T> {
@@ -132,15 +132,15 @@ class GetPageRoute<T> extends PageRoute<T> @@ -132,15 +132,15 @@ class GetPageRoute<T> extends PageRoute<T>
132 final dep = item.dependencies(); 132 final dep = item.dependencies();
133 if (dep is List<Bind>) { 133 if (dep is List<Bind>) {
134 _child = Binds( 134 _child = Binds(
135 - child: middlewareRunner.runOnPageBuilt(pageToBuild()),  
136 binds: dep, 135 binds: dep,
  136 + child: middlewareRunner.runOnPageBuilt(pageToBuild()),
137 ); 137 );
138 } 138 }
139 } 139 }
140 } else if (bindingsToBind is List<Bind>) { 140 } else if (bindingsToBind is List<Bind>) {
141 _child = Binds( 141 _child = Binds(
142 - child: middlewareRunner.runOnPageBuilt(pageToBuild()),  
143 binds: bindingsToBind, 142 binds: bindingsToBind,
  143 + child: middlewareRunner.runOnPageBuilt(pageToBuild()),
144 ); 144 );
145 } 145 }
146 } 146 }
@@ -89,7 +89,7 @@ class SlideDownTransition { @@ -89,7 +89,7 @@ class SlideDownTransition {
89 Widget child) { 89 Widget child) {
90 return SlideTransition( 90 return SlideTransition(
91 position: Tween<Offset>( 91 position: Tween<Offset>(
92 - begin: Offset(0.0, 1.0), 92 + begin: const Offset(0.0, 1.0),
93 end: Offset.zero, 93 end: Offset.zero,
94 ).animate(animation), 94 ).animate(animation),
95 child: child, 95 child: child,
@@ -107,7 +107,7 @@ class SlideLeftTransition { @@ -107,7 +107,7 @@ class SlideLeftTransition {
107 Widget child) { 107 Widget child) {
108 return SlideTransition( 108 return SlideTransition(
109 position: Tween<Offset>( 109 position: Tween<Offset>(
110 - begin: Offset(-1.0, 0.0), 110 + begin: const Offset(-1.0, 0.0),
111 end: Offset.zero, 111 end: Offset.zero,
112 ).animate(animation), 112 ).animate(animation),
113 child: child, 113 child: child,
@@ -125,7 +125,7 @@ class SlideRightTransition { @@ -125,7 +125,7 @@ class SlideRightTransition {
125 Widget child) { 125 Widget child) {
126 return SlideTransition( 126 return SlideTransition(
127 position: Tween<Offset>( 127 position: Tween<Offset>(
128 - begin: Offset(1.0, 0.0), 128 + begin: const Offset(1.0, 0.0),
129 end: Offset.zero, 129 end: Offset.zero,
130 ).animate(animation), 130 ).animate(animation),
131 child: child, 131 child: child,
@@ -143,7 +143,7 @@ class SlideTopTransition { @@ -143,7 +143,7 @@ class SlideTopTransition {
143 Widget child) { 143 Widget child) {
144 return SlideTransition( 144 return SlideTransition(
145 position: Tween<Offset>( 145 position: Tween<Offset>(
146 - begin: Offset(0.0, -1.0), 146 + begin: const Offset(0.0, -1.0),
147 end: Offset.zero, 147 end: Offset.zero,
148 ).animate(animation), 148 ).animate(animation),
149 child: child, 149 child: child,
@@ -4,6 +4,11 @@ import 'package:flutter/widgets.dart'; @@ -4,6 +4,11 @@ import 'package:flutter/widgets.dart';
4 import '../../../get.dart'; 4 import '../../../get.dart';
5 5
6 class GetInformationParser extends RouteInformationParser<RouteDecoder> { 6 class GetInformationParser extends RouteInformationParser<RouteDecoder> {
  7 + factory GetInformationParser.createInformationParser(
  8 + {String initialRoute = '/'}) {
  9 + return GetInformationParser(initialRoute: initialRoute);
  10 + }
  11 +
7 final String initialRoute; 12 final String initialRoute;
8 13
9 GetInformationParser({ 14 GetInformationParser({
@@ -19,7 +24,7 @@ class GetInformationParser extends RouteInformationParser<RouteDecoder> { @@ -19,7 +24,7 @@ class GetInformationParser extends RouteInformationParser<RouteDecoder> {
19 if (location == '/') { 24 if (location == '/') {
20 //check if there is a corresponding page 25 //check if there is a corresponding page
21 //if not, relocate to initialRoute 26 //if not, relocate to initialRoute
22 - if (!(Get.rootController.routerDelegate as GetDelegate) 27 + if (!(Get.rootController.rootDelegate)
23 .registeredRoutes 28 .registeredRoutes
24 .any((element) => element.name == '/')) { 29 .any((element) => element.name == '/')) {
25 location = initialRoute; 30 location = initialRoute;
@@ -48,7 +48,7 @@ class GetNavigator extends Navigator { @@ -48,7 +48,7 @@ class GetNavigator extends Navigator {
48 ); 48 );
49 49
50 GetNavigator({ 50 GetNavigator({
51 - GlobalKey<NavigatorState>? key, 51 + Key? key,
52 bool Function(Route<dynamic>, dynamic)? onPopPage, 52 bool Function(Route<dynamic>, dynamic)? onPopPage,
53 required List<GetPage> pages, 53 required List<GetPage> pages,
54 List<NavigatorObserver>? observers, 54 List<NavigatorObserver>? observers,
@@ -43,8 +43,10 @@ class GetPage<T> extends Page<T> { @@ -43,8 +43,10 @@ class GetPage<T> extends Page<T> {
43 @override 43 @override
44 final String name; 44 final String name;
45 45
  46 + final bool inheritParentPath;
  47 +
46 final List<GetPage> children; 48 final List<GetPage> children;
47 - final List<GetMiddleware>? middlewares; 49 + final List<GetMiddleware> middlewares;
48 final PathDecoded path; 50 final PathDecoded path;
49 final GetPage? unknownRoute; 51 final GetPage? unknownRoute;
50 final bool showCupertinoParallax; 52 final bool showCupertinoParallax;
@@ -73,7 +75,7 @@ class GetPage<T> extends Page<T> { @@ -73,7 +75,7 @@ class GetPage<T> extends Page<T> {
73 this.customTransition, 75 this.customTransition,
74 this.fullscreenDialog = false, 76 this.fullscreenDialog = false,
75 this.children = const <GetPage>[], 77 this.children = const <GetPage>[],
76 - this.middlewares, 78 + this.middlewares = const [],
77 this.unknownRoute, 79 this.unknownRoute,
78 this.arguments, 80 this.arguments,
79 this.showCupertinoParallax = true, 81 this.showCupertinoParallax = true,
@@ -81,6 +83,7 @@ class GetPage<T> extends Page<T> { @@ -81,6 +83,7 @@ class GetPage<T> extends Page<T> {
81 this.preventDuplicateHandlingMode = 83 this.preventDuplicateHandlingMode =
82 PreventDuplicateHandlingMode.reorderRoutes, 84 PreventDuplicateHandlingMode.reorderRoutes,
83 this.completer, 85 this.completer,
  86 + this.inheritParentPath = true,
84 LocalKey? key, 87 LocalKey? key,
85 }) : path = _nameToRegex(name), 88 }) : path = _nameToRegex(name),
86 assert(name.startsWith('/'), 89 assert(name.startsWith('/'),
@@ -92,7 +95,7 @@ class GetPage<T> extends Page<T> { @@ -92,7 +95,7 @@ class GetPage<T> extends Page<T> {
92 ); 95 );
93 // settings = RouteSettings(name: name, arguments: Get.arguments); 96 // settings = RouteSettings(name: name, arguments: Get.arguments);
94 97
95 - GetPage<T> copy({ 98 + GetPage<T> copyWith({
96 LocalKey? key, 99 LocalKey? key,
97 String? name, 100 String? name,
98 GetPageBuilder? page, 101 GetPageBuilder? page,
@@ -121,6 +124,7 @@ class GetPage<T> extends Page<T> { @@ -121,6 +124,7 @@ class GetPage<T> extends Page<T> {
121 Object? arguments, 124 Object? arguments,
122 bool? showCupertinoParallax, 125 bool? showCupertinoParallax,
123 Completer<T?>? completer, 126 Completer<T?>? completer,
  127 + bool? inheritParentPath,
124 }) { 128 }) {
125 return GetPage( 129 return GetPage(
126 key: key ?? this.key, 130 key: key ?? this.key,
@@ -153,25 +157,26 @@ class GetPage<T> extends Page<T> { @@ -153,25 +157,26 @@ class GetPage<T> extends Page<T> {
153 showCupertinoParallax: 157 showCupertinoParallax:
154 showCupertinoParallax ?? this.showCupertinoParallax, 158 showCupertinoParallax ?? this.showCupertinoParallax,
155 completer: completer ?? this.completer, 159 completer: completer ?? this.completer,
  160 + inheritParentPath: inheritParentPath ?? this.inheritParentPath,
156 ); 161 );
157 } 162 }
158 163
159 @override 164 @override
160 Route<T> createRoute(BuildContext context) { 165 Route<T> createRoute(BuildContext context) {
161 // return GetPageRoute<T>(settings: this, page: page); 166 // return GetPageRoute<T>(settings: this, page: page);
162 - final _page = PageRedirect( 167 + final page = PageRedirect(
163 route: this, 168 route: this,
164 settings: this, 169 settings: this,
165 unknownRoute: unknownRoute, 170 unknownRoute: unknownRoute,
166 ).getPageToRoute<T>(this, unknownRoute, context); 171 ).getPageToRoute<T>(this, unknownRoute, context);
167 172
168 - return _page; 173 + return page;
169 } 174 }
170 175
171 static PathDecoded _nameToRegex(String path) { 176 static PathDecoded _nameToRegex(String path) {
172 var keys = <String?>[]; 177 var keys = <String?>[];
173 178
174 - String _replace(Match pattern) { 179 + String recursiveReplace(Match pattern) {
175 var buffer = StringBuffer('(?:'); 180 var buffer = StringBuffer('(?:');
176 181
177 if (pattern[1] != null) buffer.write('.'); 182 if (pattern[1] != null) buffer.write('.');
@@ -183,7 +188,7 @@ class GetPage<T> extends Page<T> { @@ -183,7 +188,7 @@ class GetPage<T> extends Page<T> {
183 } 188 }
184 189
185 var stringPath = '$path/?' 190 var stringPath = '$path/?'
186 - .replaceAllMapped(RegExp(r'(\.)?:(\w+)(\?)?'), _replace) 191 + .replaceAllMapped(RegExp(r'(\.)?:(\w+)(\?)?'), recursiveReplace)
187 .replaceAll('//', '/'); 192 .replaceAll('//', '/');
188 193
189 return PathDecoded(RegExp('^$stringPath\$'), keys); 194 return PathDecoded(RegExp('^$stringPath\$'), keys);
@@ -12,6 +12,27 @@ class GetDelegate extends RouterDelegate<RouteDecoder> @@ -12,6 +12,27 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
12 ChangeNotifier, 12 ChangeNotifier,
13 PopNavigatorRouterDelegateMixin<RouteDecoder>, 13 PopNavigatorRouterDelegateMixin<RouteDecoder>,
14 IGetNavigation { 14 IGetNavigation {
  15 + factory GetDelegate.createDelegate({
  16 + GetPage<dynamic>? notFoundRoute,
  17 + List<GetPage> pages = const [],
  18 + List<NavigatorObserver>? navigatorObservers,
  19 + TransitionDelegate<dynamic>? transitionDelegate,
  20 + PopMode backButtonPopMode = PopMode.history,
  21 + PreventDuplicateHandlingMode preventDuplicateHandlingMode =
  22 + PreventDuplicateHandlingMode.reorderRoutes,
  23 + GlobalKey<NavigatorState>? navigatorKey,
  24 + }) {
  25 + return GetDelegate(
  26 + notFoundRoute: notFoundRoute,
  27 + navigatorObservers: navigatorObservers,
  28 + transitionDelegate: transitionDelegate,
  29 + backButtonPopMode: backButtonPopMode,
  30 + preventDuplicateHandlingMode: preventDuplicateHandlingMode,
  31 + pages: pages,
  32 + navigatorKey: navigatorKey,
  33 + );
  34 + }
  35 +
15 final List<RouteDecoder> _activePages = <RouteDecoder>[]; 36 final List<RouteDecoder> _activePages = <RouteDecoder>[];
16 final PopMode backButtonPopMode; 37 final PopMode backButtonPopMode;
17 final PreventDuplicateHandlingMode preventDuplicateHandlingMode; 38 final PreventDuplicateHandlingMode preventDuplicateHandlingMode;
@@ -72,7 +93,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder> @@ -72,7 +93,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
72 }) : navigatorKey = navigatorKey ?? GlobalKey<NavigatorState>(), 93 }) : navigatorKey = navigatorKey ?? GlobalKey<NavigatorState>(),
73 notFoundRoute = notFoundRoute ??= GetPage( 94 notFoundRoute = notFoundRoute ??= GetPage(
74 name: '/404', 95 name: '/404',
75 - page: () => Scaffold( 96 + page: () => const Scaffold(
76 body: Center(child: Text('Route not found')), 97 body: Center(child: Text('Route not found')),
77 ), 98 ),
78 ) { 99 ) {
@@ -84,7 +105,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder> @@ -84,7 +105,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
84 105
85 Future<RouteDecoder?> runMiddleware(RouteDecoder config) async { 106 Future<RouteDecoder?> runMiddleware(RouteDecoder config) async {
86 final middlewares = config.currentTreeBranch.last.middlewares; 107 final middlewares = config.currentTreeBranch.last.middlewares;
87 - if (middlewares == null) { 108 + if (middlewares.isEmpty) {
88 return config; 109 return config;
89 } 110 }
90 var iterator = config; 111 var iterator = config;
@@ -112,11 +133,11 @@ class GetDelegate extends RouterDelegate<RouteDecoder> @@ -112,11 +133,11 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
112 _activePages.add(res); 133 _activePages.add(res);
113 } 134 }
114 135
115 - Future<T?> _unsafeHistoryRemove<T>(RouteDecoder config, T result) async {  
116 - var index = _activePages.indexOf(config);  
117 - if (index >= 0) return _unsafeHistoryRemoveAt(index, result);  
118 - return null;  
119 - } 136 + // Future<T?> _unsafeHistoryRemove<T>(RouteDecoder config, T result) async {
  137 + // var index = _activePages.indexOf(config);
  138 + // if (index >= 0) return _unsafeHistoryRemoveAt(index, result);
  139 + // return null;
  140 + // }
120 141
121 Future<T?> _unsafeHistoryRemoveAt<T>(int index, T result) async { 142 Future<T?> _unsafeHistoryRemoveAt<T>(int index, T result) async {
122 if (index == _activePages.length - 1 && _activePages.length > 1) { 143 if (index == _activePages.length - 1 && _activePages.length > 1) {
@@ -145,10 +166,6 @@ class GetDelegate extends RouterDelegate<RouteDecoder> @@ -145,10 +166,6 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
145 return currentConfiguration?.pageSettings; 166 return currentConfiguration?.pageSettings;
146 } 167 }
147 168
148 - Future<T?> _removeHistoryEntry<T>(RouteDecoder entry, T result) async {  
149 - return _unsafeHistoryRemove<T>(entry, result);  
150 - }  
151 -  
152 Future<void> _pushHistory(RouteDecoder config) async { 169 Future<void> _pushHistory(RouteDecoder config) async {
153 if (config.route!.preventDuplicates) { 170 if (config.route!.preventDuplicates) {
154 final originalEntryIndex = _activePages.indexWhere( 171 final originalEntryIndex = _activePages.indexWhere(
@@ -560,7 +577,6 @@ class GetDelegate extends RouterDelegate<RouteDecoder> @@ -560,7 +577,6 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
560 _activePages.remove(RouteDecoder.fromRoute(name)); 577 _activePages.remove(RouteDecoder.fromRoute(name));
561 } 578 }
562 579
563 -  
564 bool get canBack { 580 bool get canBack {
565 return _activePages.length > 1; 581 return _activePages.length > 1;
566 } 582 }
@@ -691,7 +707,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder> @@ -691,7 +707,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
691 decoder.parameters.addAll(parameters); 707 decoder.parameters.addAll(parameters);
692 } 708 }
693 709
694 - decoder.route = decoder.route?.copy( 710 + decoder.route = decoder.route?.copyWith(
695 completer: _activePages.isEmpty ? null : Completer(), 711 completer: _activePages.isEmpty ? null : Completer(),
696 arguments: arguments, 712 arguments: arguments,
697 parameters: parameters, 713 parameters: parameters,
@@ -786,7 +802,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder> @@ -786,7 +802,7 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
786 if (wasPopup) return true; 802 if (wasPopup) return true;
787 803
788 if (_canPop(popMode ?? backButtonPopMode)) { 804 if (_canPop(popMode ?? backButtonPopMode)) {
789 - await _pop(popMode ?? backButtonPopMode, result); 805 + await _pop(popMode ?? backButtonPopMode, result);
790 notifyListeners(); 806 notifyListeners();
791 return true; 807 return true;
792 } 808 }
@@ -801,7 +817,6 @@ class GetDelegate extends RouterDelegate<RouteDecoder> @@ -801,7 +817,6 @@ class GetDelegate extends RouterDelegate<RouteDecoder>
801 notifyListeners(); 817 notifyListeners();
802 } 818 }
803 819
804 -  
805 bool _onPopVisualRoute(Route<dynamic> route, dynamic result) { 820 bool _onPopVisualRoute(Route<dynamic> route, dynamic result) {
806 final didPop = route.didPop(result); 821 final didPop = route.didPop(result);
807 if (!didPop) { 822 if (!didPop) {
@@ -7,6 +7,7 @@ import 'package:flutter/gestures.dart'; @@ -7,6 +7,7 @@ import 'package:flutter/gestures.dart';
7 import 'package:flutter/material.dart'; 7 import 'package:flutter/material.dart';
8 8
9 import '../../../get.dart'; 9 import '../../../get.dart';
  10 +import '../root/get_root.dart';
10 11
11 const double _kBackGestureWidth = 20.0; 12 const double _kBackGestureWidth = 20.0;
12 13
@@ -379,8 +380,8 @@ Cannot read the previousTitle for a route that has not yet been installed''', @@ -379,8 +380,8 @@ Cannot read the previousTitle for a route that has not yet been installed''',
379 ? CurvedAnimation(parent: animation, curve: finalCurve) 380 ? CurvedAnimation(parent: animation, curve: finalCurve)
380 : animation, 381 : animation,
381 secondaryRouteAnimation: secondaryAnimation, 382 secondaryRouteAnimation: secondaryAnimation,
382 - child: child,  
383 linearTransition: linearTransition, 383 linearTransition: linearTransition,
  384 + child: child,
384 ); 385 );
385 } else { 386 } else {
386 if (route.customTransition != null) { 387 if (route.customTransition != null) {
@@ -635,7 +636,7 @@ Cannot read the previousTitle for a route that has not yet been installed''', @@ -635,7 +636,7 @@ Cannot read the previousTitle for a route that has not yet been installed''',
635 )); 636 ));
636 637
637 case Transition.fade: 638 case Transition.fade:
638 - return FadeUpwardsPageTransitionsBuilder().buildTransitions( 639 + return const FadeUpwardsPageTransitionsBuilder().buildTransitions(
639 route, 640 route,
640 context, 641 context,
641 animation, 642 animation,
@@ -655,7 +656,7 @@ Cannot read the previousTitle for a route that has not yet been installed''', @@ -655,7 +656,7 @@ Cannot read the previousTitle for a route that has not yet been installed''',
655 )); 656 ));
656 657
657 case Transition.topLevel: 658 case Transition.topLevel:
658 - return ZoomPageTransitionsBuilder().buildTransitions( 659 + return const ZoomPageTransitionsBuilder().buildTransitions(
659 route, 660 route,
660 context, 661 context,
661 animation, 662 animation,
@@ -675,7 +676,7 @@ Cannot read the previousTitle for a route that has not yet been installed''', @@ -675,7 +676,7 @@ Cannot read the previousTitle for a route that has not yet been installed''',
675 )); 676 ));
676 677
677 case Transition.native: 678 case Transition.native:
678 - return PageTransitionsTheme().buildTransitions( 679 + return const PageTransitionsTheme().buildTransitions(
679 route, 680 route,
680 context, 681 context,
681 iosAnimation, 682 iosAnimation,
@@ -716,8 +717,8 @@ Cannot read the previousTitle for a route that has not yet been installed''', @@ -716,8 +717,8 @@ Cannot read the previousTitle for a route that has not yet been installed''',
716 )); 717 ));
717 718
718 default: 719 default:
719 - final customTransition =  
720 - context.get<GetMaterialController>().customTransition; 720 + final customTransition = GetRoot.of(context).config.customTransition;
  721 +
721 if (customTransition != null) { 722 if (customTransition != null) {
722 return customTransition.buildTransition(context, route.curve, 723 return customTransition.buildTransition(context, route.curve,
723 route.alignment, animation, secondaryAnimation, child); 724 route.alignment, animation, secondaryAnimation, child);
@@ -57,17 +57,17 @@ class Dependencies { @@ -57,17 +57,17 @@ class Dependencies {
57 } 57 }
58 58
59 abstract class Module extends StatefulWidget { 59 abstract class Module extends StatefulWidget {
60 - Module({Key? key}) : super(key: key); 60 + const Module({Key? key}) : super(key: key);
61 61
62 Widget view(BuildContext context); 62 Widget view(BuildContext context);
63 63
64 void dependencies(Dependencies i); 64 void dependencies(Dependencies i);
65 65
66 @override 66 @override
67 - _ModuleState createState() => _ModuleState(); 67 + ModuleState createState() => ModuleState();
68 } 68 }
69 69
70 -class _ModuleState extends State<Module> { 70 +class ModuleState extends State<Module> {
71 @override 71 @override
72 void initState() { 72 void initState() {
73 RouterReportManager.instance.reportCurrentRoute(this); 73 RouterReportManager.instance.reportCurrentRoute(this);
  1 +import 'dart:async';
  2 +
  3 +import 'package:flutter/widgets.dart';
  4 +
  5 +import 'get_route.dart';
  6 +
  7 +class RouteMatcher {
  8 + final RouteNode _root = RouteNode('/', '/');
  9 +
  10 + RouteNode addRoute(String path) {
  11 + final segments = _parsePath(path);
  12 + var currentNode = _root;
  13 +
  14 + for (final segment in segments) {
  15 + final existingChild = currentNode.findChild(segment);
  16 + if (existingChild != null) {
  17 + currentNode = existingChild;
  18 + } else {
  19 + final newChild = RouteNode(segment, path);
  20 + currentNode.addChild(newChild);
  21 + currentNode = newChild;
  22 + }
  23 + }
  24 + return currentNode;
  25 + }
  26 +
  27 + void removeRoute(String path) {
  28 + final segments = _parsePath(path);
  29 + var currentNode = _root;
  30 + RouteNode? nodeToDelete;
  31 +
  32 + // Traverse the tree to find the node to delete
  33 + for (final segment in segments) {
  34 + final child = currentNode.findChild(segment);
  35 + if (child == null) {
  36 + return; // Node not found, nothing to delete
  37 + }
  38 + if (child.nodeSegments.length == segments.length) {
  39 + nodeToDelete = child;
  40 + break;
  41 + }
  42 + currentNode = child;
  43 + }
  44 +
  45 + if (nodeToDelete == null) {
  46 + return; // Node not found, nothing to delete
  47 + }
  48 +
  49 + final parent = nodeToDelete.parent!;
  50 + parent.nodeSegments.remove(nodeToDelete);
  51 + }
  52 +
  53 + RouteNode? _findChild(RouteNode currentNode, String segment) {
  54 + return currentNode.nodeSegments
  55 + .firstWhereOrNull((node) => node.matches(segment));
  56 + }
  57 +
  58 + MatchResult? matchRoute(String path) {
  59 + final uri = Uri.parse(path);
  60 + final segments = _parsePath(uri.path);
  61 + var currentNode = _root;
  62 + final parameters = <String, String>{};
  63 + final urlParameters = uri.queryParameters;
  64 +
  65 + for (final segment in segments) {
  66 + if (segment.isEmpty) continue;
  67 + final child = _findChild(currentNode, segment);
  68 + if (child == null) {
  69 + return null;
  70 + } else {
  71 + if (child.path.startsWith(':')) {
  72 + parameters[child.path.substring(1)] = segment;
  73 + }
  74 +
  75 + if (child.nodeSegments.length == segments.length) {
  76 + return null;
  77 + }
  78 +
  79 + currentNode = child;
  80 + }
  81 + }
  82 +
  83 + return MatchResult(
  84 + currentNode,
  85 + parameters,
  86 + path,
  87 + urlParameters: urlParameters,
  88 + );
  89 + }
  90 +
  91 + List<String> _parsePath(String path) {
  92 + return path.split('/').where((segment) => segment.isNotEmpty).toList();
  93 + }
  94 +}
  95 +
  96 +class RouteTreeResult {
  97 + final GetPage? route;
  98 + final MatchResult matchResult;
  99 +
  100 + RouteTreeResult({
  101 + required this.route,
  102 + required this.matchResult,
  103 + });
  104 +
  105 + @override
  106 + String toString() {
  107 + return 'RouteTreeResult(route: $route, matchResult: $matchResult)';
  108 + }
  109 +
  110 + RouteTreeResult configure(String page, Object? arguments) {
  111 + return copyWith(
  112 + route: route?.copyWith(
  113 + key: ValueKey(page),
  114 + settings: RouteSettings(name: page, arguments: arguments),
  115 + completer: Completer(),
  116 + arguments: arguments,
  117 + ));
  118 + }
  119 +
  120 + RouteTreeResult copyWith({
  121 + GetPage? route,
  122 + MatchResult? matchResult,
  123 + }) {
  124 + return RouteTreeResult(
  125 + route: route ?? this.route,
  126 + matchResult: matchResult ?? this.matchResult,
  127 + );
  128 + }
  129 +}
  130 +
  131 +class RouteTree {
  132 + static final instance = RouteTree();
  133 + final Map<String, GetPage> tree = {};
  134 + final RouteMatcher matcher = RouteMatcher();
  135 +
  136 + void addRoute(GetPage route) {
  137 + matcher.addRoute(route.name);
  138 + tree[route.name] = route;
  139 + handleChild(route);
  140 + }
  141 +
  142 + void addRoutes(List<GetPage> routes) {
  143 + for (var route in routes) {
  144 + addRoute(route);
  145 + }
  146 + }
  147 +
  148 + void handleChild(GetPage route) {
  149 + final children = route.children;
  150 + for (var child in children) {
  151 + final middlewares = List.of(route.middlewares);
  152 + final bindings = List.of(route.bindings);
  153 + middlewares.addAll(child.middlewares);
  154 + bindings.addAll(child.bindings);
  155 + child = child.copyWith(middlewares: middlewares, bindings: bindings);
  156 + if (child.inheritParentPath) {
  157 + child = child.copyWith(
  158 + name: ('${route.path}/${child.path}').replaceAll(r'//', '/'));
  159 + }
  160 + addRoute(child);
  161 + }
  162 + }
  163 +
  164 + void removeRoute(GetPage route) {
  165 + matcher.removeRoute(route.name);
  166 + tree.remove(route.path);
  167 + }
  168 +
  169 + void removeRoutes(List<GetPage> routes) {
  170 + for (var route in routes) {
  171 + removeRoute(route);
  172 + }
  173 + }
  174 +
  175 + RouteTreeResult? matchRoute(String path) {
  176 + final matchResult = matcher.matchRoute(path);
  177 + if (matchResult != null) {
  178 + final route = tree[matchResult.node.originalPath];
  179 + return RouteTreeResult(
  180 + route: route,
  181 + matchResult: matchResult,
  182 + );
  183 + }
  184 + return null;
  185 + }
  186 +}
  187 +
  188 +/// A class representing the result of a route matching operation.
  189 +class MatchResult {
  190 + /// The route found that matches the result
  191 + final RouteNode node;
  192 +
  193 + /// The current path of match, eg: adding 'user/:id' the match result for 'user/123' will be: 'user/123'
  194 + final String currentPath;
  195 +
  196 + /// Route parameters eg: adding 'user/:id' the match result for 'user/123' will be: {id: 123}
  197 + final Map<String, String> parameters;
  198 +
  199 + /// Route url parameters eg: adding 'user' the match result for 'user?foo=bar' will be: {foo: bar}
  200 + final Map<String, String> urlParameters;
  201 +
  202 + MatchResult(this.node, this.parameters, this.currentPath,
  203 + {this.urlParameters = const {}});
  204 +
  205 + @override
  206 + String toString() =>
  207 + 'MatchResult(node: $node, currentPath: $currentPath, parameters: $parameters, urlParameters: $urlParameters)';
  208 +}
  209 +
  210 +// A class representing a node in a routing tree.
  211 +class RouteNode {
  212 + String path;
  213 + String originalPath;
  214 + RouteNode? parent;
  215 + List<RouteNode> nodeSegments = [];
  216 +
  217 + RouteNode(this.path, this.originalPath, {this.parent});
  218 +
  219 + bool get isRoot => parent == null;
  220 +
  221 + String get fullPath {
  222 + if (isRoot) {
  223 + return '/';
  224 + } else {
  225 + final parentPath = parent?.fullPath == '/' ? '' : parent?.fullPath;
  226 + return '$parentPath/$path';
  227 + }
  228 + }
  229 +
  230 + bool get hasChildren => nodeSegments.isNotEmpty;
  231 +
  232 + void addChild(RouteNode child) {
  233 + nodeSegments.add(child);
  234 + child.parent = this;
  235 + }
  236 +
  237 + RouteNode? findChild(String name) {
  238 + return nodeSegments.firstWhereOrNull((node) => node.path == name);
  239 + }
  240 +
  241 + bool matches(String name) {
  242 + return name == path || path == '*' || path.startsWith(':');
  243 + }
  244 +
  245 + @override
  246 + String toString() =>
  247 + 'RouteNode(name: $path, nodeSegments: $nodeSegments, fullPath: $fullPath )';
  248 +}
  249 +
  250 +extension Foo<T> on Iterable<T> {
  251 + T? firstWhereOrNull(bool Function(T element) test) {
  252 + for (var element in this) {
  253 + if (test(element)) return element;
  254 + }
  255 + return null;
  256 + }
  257 +}
@@ -185,6 +185,7 @@ class GetObserver extends NavigatorObserver { @@ -185,6 +185,7 @@ class GetObserver extends NavigatorObserver {
185 } 185 }
186 } 186 }
187 187
  188 +//TODO: Use copyWith, and remove mutate variables
188 class Routing { 189 class Routing {
189 String current; 190 String current;
190 String previous; 191 String previous;
1 import 'package:flutter/foundation.dart'; 1 import 'package:flutter/foundation.dart';
2 2
3 -import '../../../route_manager.dart'; 3 +import '../../../get.dart';
4 4
5 @immutable 5 @immutable
6 class RouteDecoder { 6 class RouteDecoder {
@@ -14,9 +14,9 @@ class RouteDecoder { @@ -14,9 +14,9 @@ class RouteDecoder {
14 factory RouteDecoder.fromRoute(String location) { 14 factory RouteDecoder.fromRoute(String location) {
15 var uri = Uri.parse(location); 15 var uri = Uri.parse(location);
16 final args = PageSettings(uri); 16 final args = PageSettings(uri);
17 - final decoder = (Get.rootController.routerDelegate as GetDelegate)  
18 - .matchRoute(location, arguments: args);  
19 - decoder.route = decoder.route?.copy( 17 + final decoder =
  18 + (Get.rootController.rootDelegate).matchRoute(location, arguments: args);
  19 + decoder.route = decoder.route?.copyWith(
20 completer: null, 20 completer: null,
21 arguments: args, 21 arguments: args,
22 parameters: args.params, 22 parameters: args.params,
@@ -57,10 +57,10 @@ class RouteDecoder { @@ -57,10 +57,10 @@ class RouteDecoder {
57 } 57 }
58 58
59 void replaceArguments(Object? arguments) { 59 void replaceArguments(Object? arguments) {
60 - final _route = route;  
61 - if (_route != null) {  
62 - final index = currentTreeBranch.indexOf(_route);  
63 - currentTreeBranch[index] = _route.copy(arguments: arguments); 60 + final newRoute = route;
  61 + if (newRoute != null) {
  62 + final index = currentTreeBranch.indexOf(newRoute);
  63 + currentTreeBranch[index] = newRoute.copyWith(arguments: arguments);
64 } 64 }
65 } 65 }
66 66
@@ -86,7 +86,6 @@ class ParseRouteTree { @@ -86,7 +86,6 @@ class ParseRouteTree {
86 86
87 RouteDecoder matchRoute(String name, {PageSettings? arguments}) { 87 RouteDecoder matchRoute(String name, {PageSettings? arguments}) {
88 final uri = Uri.parse(name); 88 final uri = Uri.parse(name);
89 - // /home/profile/123 => home,profile,123 => /,/home,/home/profile,/home/profile/123  
90 final split = uri.path.split('/').where((element) => element.isNotEmpty); 89 final split = uri.path.split('/').where((element) => element.isNotEmpty);
91 var curPath = '/'; 90 var curPath = '/';
92 final cumulativePaths = <String>[ 91 final cumulativePaths = <String>[
@@ -106,7 +105,7 @@ class ParseRouteTree { @@ -106,7 +105,7 @@ class ParseRouteTree {
106 .where((element) => element.value != null) 105 .where((element) => element.value != null)
107 106
108 ///Prevent page be disposed 107 ///Prevent page be disposed
109 - .map((e) => MapEntry(e.key, e.value!.copy(key: ValueKey(e.key)))) 108 + .map((e) => MapEntry(e.key, e.value!.copyWith(key: ValueKey(e.key))))
110 .toList(); 109 .toList();
111 110
112 final params = Map<String, String>.from(uri.queryParameters); 111 final params = Map<String, String>.from(uri.queryParameters);
@@ -120,7 +119,7 @@ class ParseRouteTree { @@ -120,7 +119,7 @@ class ParseRouteTree {
120 //copy parameters to all pages. 119 //copy parameters to all pages.
121 final mappedTreeBranch = treeBranch 120 final mappedTreeBranch = treeBranch
122 .map( 121 .map(
123 - (e) => e.value.copy( 122 + (e) => e.value.copyWith(
124 parameters: { 123 parameters: {
125 if (e.value.parameters != null) ...e.value.parameters!, 124 if (e.value.parameters != null) ...e.value.parameters!,
126 ...params, 125 ...params,
@@ -185,14 +184,28 @@ class ParseRouteTree { @@ -185,14 +184,28 @@ class ParseRouteTree {
185 for (var page in route.children) { 184 for (var page in route.children) {
186 // Add Parent middlewares to children 185 // Add Parent middlewares to children
187 final parentMiddlewares = [ 186 final parentMiddlewares = [
188 - if (page.middlewares != null) ...page.middlewares!,  
189 - if (route.middlewares != null) ...route.middlewares! 187 + if (page.middlewares.isNotEmpty) ...page.middlewares,
  188 + if (route.middlewares.isNotEmpty) ...route.middlewares
190 ]; 189 ];
  190 +
  191 + final parentBindings = [
  192 + if (page.binding != null) page.binding!,
  193 + if (page.bindings.isNotEmpty) ...page.bindings,
  194 + if (route.bindings.isNotEmpty) ...route.bindings
  195 + ];
  196 +
  197 + final parentBinds = [
  198 + if (page.binds.isNotEmpty) ...page.binds,
  199 + if (route.binds.isNotEmpty) ...route.binds
  200 + ];
  201 +
191 result.add( 202 result.add(
192 _addChild( 203 _addChild(
193 page, 204 page,
194 parentPath, 205 parentPath,
195 parentMiddlewares, 206 parentMiddlewares,
  207 + parentBindings,
  208 + parentBinds,
196 ), 209 ),
197 ); 210 );
198 211
@@ -203,7 +216,16 @@ class ParseRouteTree { @@ -203,7 +216,16 @@ class ParseRouteTree {
203 parentPath, 216 parentPath,
204 [ 217 [
205 ...parentMiddlewares, 218 ...parentMiddlewares,
206 - if (child.middlewares != null) ...child.middlewares!, 219 + if (child.middlewares.isNotEmpty) ...child.middlewares,
  220 + ],
  221 + [
  222 + ...parentBindings,
  223 + if (child.binding != null) child.binding!,
  224 + if (child.bindings.isNotEmpty) ...child.bindings,
  225 + ],
  226 + [
  227 + ...parentBinds,
  228 + if (child.binds.isNotEmpty) ...child.binds,
207 ], 229 ],
208 )); 230 ));
209 } 231 }
@@ -213,10 +235,19 @@ class ParseRouteTree { @@ -213,10 +235,19 @@ class ParseRouteTree {
213 235
214 /// Change the Path for a [GetPage] 236 /// Change the Path for a [GetPage]
215 GetPage _addChild( 237 GetPage _addChild(
216 - GetPage origin, String parentPath, List<GetMiddleware> middlewares) {  
217 - return origin.copy( 238 + GetPage origin,
  239 + String parentPath,
  240 + List<GetMiddleware> middlewares,
  241 + List<BindingsInterface> bindings,
  242 + List<Bind> binds,
  243 + ) {
  244 + return origin.copyWith(
218 middlewares: middlewares, 245 middlewares: middlewares,
219 - name: (parentPath + origin.name).replaceAll(r'//', '/'), 246 + name: origin.inheritParentPath
  247 + ? (parentPath + origin.name).replaceAll(r'//', '/')
  248 + : origin.name,
  249 + bindings: bindings,
  250 + binds: binds,
220 // key: 251 // key:
221 ); 252 );
222 } 253 }
@@ -130,8 +130,8 @@ class MiddlewareRunner { @@ -130,8 +130,8 @@ class MiddlewareRunner {
130 final List<GetMiddleware>? _middlewares; 130 final List<GetMiddleware>? _middlewares;
131 131
132 List<GetMiddleware> _getMiddlewares() { 132 List<GetMiddleware> _getMiddlewares() {
133 - final _m = _middlewares ?? <GetMiddleware>[];  
134 - return _m 133 + final newMiddleware = _middlewares ?? <GetMiddleware>[];
  134 + return List.of(newMiddleware)
135 ..sort( 135 ..sort(
136 (a, b) => (a.priority ?? 0).compareTo(b.priority ?? 0), 136 (a, b) => (a.priority ?? 0).compareTo(b.priority ?? 0),
137 ); 137 );
@@ -198,34 +198,33 @@ class PageRedirect { @@ -198,34 +198,33 @@ class PageRedirect {
198 GetPageRoute<T> getPageToRoute<T>( 198 GetPageRoute<T> getPageToRoute<T>(
199 GetPage rou, GetPage? unk, BuildContext context) { 199 GetPage rou, GetPage? unk, BuildContext context) {
200 while (needRecheck(context)) {} 200 while (needRecheck(context)) {}
201 - final _r = (isUnknown ? unk : rou)!; 201 + final r = (isUnknown ? unk : rou)!;
202 202
203 return GetPageRoute<T>( 203 return GetPageRoute<T>(
204 - page: _r.page,  
205 - parameter: _r.parameters,  
206 - alignment: _r.alignment,  
207 - title: _r.title,  
208 - maintainState: _r.maintainState,  
209 - routeName: _r.name,  
210 - settings: _r,  
211 - curve: _r.curve,  
212 - showCupertinoParallax: _r.showCupertinoParallax,  
213 - gestureWidth: _r.gestureWidth,  
214 - opaque: _r.opaque,  
215 - customTransition: _r.customTransition,  
216 - bindings: _r.bindings,  
217 - binding: _r.binding,  
218 - binds: _r.binds,  
219 - transitionDuration:  
220 - _r.transitionDuration ?? Get.defaultTransitionDuration, 204 + page: r.page,
  205 + parameter: r.parameters,
  206 + alignment: r.alignment,
  207 + title: r.title,
  208 + maintainState: r.maintainState,
  209 + routeName: r.name,
  210 + settings: r,
  211 + curve: r.curve,
  212 + showCupertinoParallax: r.showCupertinoParallax,
  213 + gestureWidth: r.gestureWidth,
  214 + opaque: r.opaque,
  215 + customTransition: r.customTransition,
  216 + bindings: r.bindings,
  217 + binding: r.binding,
  218 + binds: r.binds,
  219 + transitionDuration: r.transitionDuration ?? Get.defaultTransitionDuration,
221 reverseTransitionDuration: 220 reverseTransitionDuration:
222 - _r.reverseTransitionDuration ?? Get.defaultTransitionDuration, 221 + r.reverseTransitionDuration ?? Get.defaultTransitionDuration,
223 // performIncomeAnimation: _r.performIncomeAnimation, 222 // performIncomeAnimation: _r.performIncomeAnimation,
224 // performOutGoingAnimation: _r.performOutGoingAnimation, 223 // performOutGoingAnimation: _r.performOutGoingAnimation,
225 - transition: _r.transition,  
226 - popGesture: _r.popGesture,  
227 - fullscreenDialog: _r.fullscreenDialog,  
228 - middlewares: _r.middlewares, 224 + transition: r.transition,
  225 + popGesture: r.popGesture,
  226 + fullscreenDialog: r.fullscreenDialog,
  227 + middlewares: r.middlewares,
229 ); 228 );
230 } 229 }
231 230
@@ -248,7 +247,7 @@ class PageRedirect { @@ -248,7 +247,7 @@ class PageRedirect {
248 addPageParameter(route!); 247 addPageParameter(route!);
249 248
250 // No middlewares found return match. 249 // No middlewares found return match.
251 - if (match.route!.middlewares == null || match.route!.middlewares!.isEmpty) { 250 + if (match.route!.middlewares.isEmpty) {
252 return false; 251 return false;
253 } 252 }
254 final newSettings = runner.runRedirect(settings!.name); 253 final newSettings = runner.runRedirect(settings!.name);
@@ -4,14 +4,14 @@ import '../router_report.dart'; @@ -4,14 +4,14 @@ import '../router_report.dart';
4 import 'default_route.dart'; 4 import 'default_route.dart';
5 5
6 class RouteReport extends StatefulWidget { 6 class RouteReport extends StatefulWidget {
7 - RouteReport({Key? key, required this.builder}) : super(key: key); 7 + const RouteReport({Key? key, required this.builder}) : super(key: key);
8 final WidgetBuilder builder; 8 final WidgetBuilder builder;
9 9
10 @override 10 @override
11 - _RouteReportState createState() => _RouteReportState(); 11 + RouteReportState createState() => RouteReportState();
12 } 12 }
13 13
14 -class _RouteReportState extends State<RouteReport> with RouteReportMixin { 14 +class RouteReportState extends State<RouteReport> with RouteReportMixin {
15 @override 15 @override
16 void initState() { 16 void initState() {
17 RouterReportManager.instance.reportCurrentRoute(this); 17 RouterReportManager.instance.reportCurrentRoute(this);
@@ -9,12 +9,13 @@ class RouterOutlet<TDelegate extends RouterDelegate<T>, T extends Object> @@ -9,12 +9,13 @@ class RouterOutlet<TDelegate extends RouterDelegate<T>, T extends Object>
9 9
10 //keys 10 //keys
11 RouterOutlet.builder({ 11 RouterOutlet.builder({
  12 + super.key,
12 TDelegate? delegate, 13 TDelegate? delegate,
13 required this.builder, 14 required this.builder,
14 - }) : routerDelegate = delegate ?? Get.delegate<TDelegate, T>()!,  
15 - super(); 15 + }) : routerDelegate = delegate ?? Get.delegate<TDelegate, T>()!;
16 16
17 RouterOutlet({ 17 RouterOutlet({
  18 + Key? key,
18 TDelegate? delegate, 19 TDelegate? delegate,
19 required Iterable<GetPage> Function(T currentNavStack) pickPages, 20 required Iterable<GetPage> Function(T currentNavStack) pickPages,
20 required Widget Function( 21 required Widget Function(
@@ -24,6 +25,7 @@ class RouterOutlet<TDelegate extends RouterDelegate<T>, T extends Object> @@ -24,6 +25,7 @@ class RouterOutlet<TDelegate extends RouterDelegate<T>, T extends Object>
24 ) 25 )
25 pageBuilder, 26 pageBuilder,
26 }) : this.builder( 27 }) : this.builder(
  28 + key: key,
27 builder: (context) { 29 builder: (context) {
28 final currentConfig = context.delegate.currentConfiguration as T?; 30 final currentConfig = context.delegate.currentConfiguration as T?;
29 final rDelegate = context.delegate as TDelegate; 31 final rDelegate = context.delegate as TDelegate;
@@ -37,11 +39,11 @@ class RouterOutlet<TDelegate extends RouterDelegate<T>, T extends Object> @@ -37,11 +39,11 @@ class RouterOutlet<TDelegate extends RouterDelegate<T>, T extends Object>
37 delegate: delegate, 39 delegate: delegate,
38 ); 40 );
39 @override 41 @override
40 - _RouterOutletState<TDelegate, T> createState() =>  
41 - _RouterOutletState<TDelegate, T>(); 42 + RouterOutletState<TDelegate, T> createState() =>
  43 + RouterOutletState<TDelegate, T>();
42 } 44 }
43 45
44 -class _RouterOutletState<TDelegate extends RouterDelegate<T>, T extends Object> 46 +class RouterOutletState<TDelegate extends RouterDelegate<T>, T extends Object>
45 extends State<RouterOutlet<TDelegate, T>> { 47 extends State<RouterOutlet<TDelegate, T>> {
46 RouterDelegate? delegate; 48 RouterDelegate? delegate;
47 late ChildBackButtonDispatcher _backButtonDispatcher; 49 late ChildBackButtonDispatcher _backButtonDispatcher;
@@ -80,7 +82,7 @@ class _RouterOutletState<TDelegate extends RouterDelegate<T>, T extends Object> @@ -80,7 +82,7 @@ class _RouterOutletState<TDelegate extends RouterDelegate<T>, T extends Object>
80 } 82 }
81 } 83 }
82 84
83 -// class _RouterOutletState<TDelegate extends RouterDelegate<T>, 85 +// class RouterOutletState<TDelegate extends RouterDelegate<T>,
84 //T extends Object> 86 //T extends Object>
85 // extends State<RouterOutlet<TDelegate, T>> { 87 // extends State<RouterOutlet<TDelegate, T>> {
86 // TDelegate get delegate => context.delegate as TDelegate; 88 // TDelegate get delegate => context.delegate as TDelegate;
@@ -152,11 +154,11 @@ class GetRouterOutlet extends RouterOutlet<GetDelegate, RouteDecoder> { @@ -152,11 +154,11 @@ class GetRouterOutlet extends RouterOutlet<GetDelegate, RouteDecoder> {
152 delegate: delegate, 154 delegate: delegate,
153 ); 155 );
154 GetRouterOutlet.pickPages({ 156 GetRouterOutlet.pickPages({
  157 + super.key,
155 Widget Function(GetDelegate delegate)? emptyWidget, 158 Widget Function(GetDelegate delegate)? emptyWidget,
156 GetPage Function(GetDelegate delegate)? emptyPage, 159 GetPage Function(GetDelegate delegate)? emptyPage,
157 required Iterable<GetPage> Function(RouteDecoder currentNavStack) pickPages, 160 required Iterable<GetPage> Function(RouteDecoder currentNavStack) pickPages,
158 bool Function(Route<dynamic>, dynamic)? onPopPage, 161 bool Function(Route<dynamic>, dynamic)? onPopPage,
159 - GlobalKey<NavigatorState>? key,  
160 GetDelegate? delegate, 162 GetDelegate? delegate,
161 }) : super( 163 }) : super(
162 pageBuilder: (context, rDelegate, pages) { 164 pageBuilder: (context, rDelegate, pages) {
@@ -179,13 +181,14 @@ class GetRouterOutlet extends RouterOutlet<GetDelegate, RouteDecoder> { @@ -179,13 +181,14 @@ class GetRouterOutlet extends RouterOutlet<GetDelegate, RouteDecoder> {
179 key: key, 181 key: key,
180 ); 182 );
181 } 183 }
182 - return (emptyWidget?.call(rDelegate) ?? SizedBox.shrink()); 184 + return (emptyWidget?.call(rDelegate) ?? const SizedBox.shrink());
183 }, 185 },
184 pickPages: pickPages, 186 pickPages: pickPages,
185 delegate: delegate ?? Get.rootController.rootDelegate, 187 delegate: delegate ?? Get.rootController.rootDelegate,
186 ); 188 );
187 189
188 GetRouterOutlet.builder({ 190 GetRouterOutlet.builder({
  191 + super.key,
189 required Widget Function( 192 required Widget Function(
190 BuildContext context, 193 BuildContext context,
191 ) 194 )
@@ -11,85 +11,6 @@ typedef OnHover = void Function(GetSnackBar snack, SnackHoverState snackHoverSta @@ -11,85 +11,6 @@ typedef OnHover = void Function(GetSnackBar snack, SnackHoverState snackHoverSta
11 11
12 typedef SnackbarStatusCallback = void Function(SnackbarStatus? status); 12 typedef SnackbarStatusCallback = void Function(SnackbarStatus? status);
13 13
14 -@Deprecated('use GetSnackBar')  
15 -class GetBar extends GetSnackBar {  
16 - GetBar({  
17 - Key? key,  
18 - String? title,  
19 - String? message,  
20 - Widget? titleText,  
21 - Widget? messageText,  
22 - Widget? icon,  
23 - bool shouldIconPulse = true,  
24 - double? maxWidth,  
25 - EdgeInsets margin = const EdgeInsets.all(0.0),  
26 - EdgeInsets padding = const EdgeInsets.all(16),  
27 - double borderRadius = 0.0,  
28 - Color? borderColor,  
29 - double borderWidth = 1.0,  
30 - Color backgroundColor = const Color(0xFF303030),  
31 - Color? leftBarIndicatorColor,  
32 - List<BoxShadow>? boxShadows,  
33 - Gradient? backgroundGradient,  
34 - Widget? mainButton,  
35 - OnTap? onTap,  
36 - Duration? duration,  
37 - bool isDismissible = true,  
38 - DismissDirection? dismissDirection,  
39 - bool showProgressIndicator = false,  
40 - AnimationController? progressIndicatorController,  
41 - Color? progressIndicatorBackgroundColor,  
42 - Animation<Color>? progressIndicatorValueColor,  
43 - SnackPosition snackPosition = SnackPosition.bottom,  
44 - SnackStyle snackStyle = SnackStyle.floating,  
45 - Curve forwardAnimationCurve = Curves.easeOutCirc,  
46 - Curve reverseAnimationCurve = Curves.easeOutCirc,  
47 - Duration animationDuration = const Duration(seconds: 1),  
48 - double barBlur = 0.0,  
49 - double overlayBlur = 0.0,  
50 - Color overlayColor = Colors.transparent,  
51 - Form? userInputForm,  
52 - SnackbarStatusCallback? snackbarStatus,  
53 - }) : super(  
54 - key: key,  
55 - title: title,  
56 - message: message,  
57 - titleText: titleText,  
58 - messageText: messageText,  
59 - icon: icon,  
60 - shouldIconPulse: shouldIconPulse,  
61 - maxWidth: maxWidth,  
62 - margin: margin,  
63 - padding: padding,  
64 - borderRadius: borderRadius,  
65 - borderColor: borderColor,  
66 - borderWidth: borderWidth,  
67 - backgroundColor: backgroundColor,  
68 - leftBarIndicatorColor: leftBarIndicatorColor,  
69 - boxShadows: boxShadows,  
70 - backgroundGradient: backgroundGradient,  
71 - mainButton: mainButton,  
72 - onTap: onTap,  
73 - duration: duration,  
74 - isDismissible: isDismissible,  
75 - dismissDirection: dismissDirection,  
76 - showProgressIndicator: showProgressIndicator,  
77 - progressIndicatorController: progressIndicatorController,  
78 - progressIndicatorBackgroundColor: progressIndicatorBackgroundColor,  
79 - progressIndicatorValueColor: progressIndicatorValueColor,  
80 - snackPosition: snackPosition,  
81 - snackStyle: snackStyle,  
82 - forwardAnimationCurve: forwardAnimationCurve,  
83 - reverseAnimationCurve: reverseAnimationCurve,  
84 - animationDuration: animationDuration,  
85 - barBlur: barBlur,  
86 - overlayBlur: overlayBlur,  
87 - overlayColor: overlayColor,  
88 - userInputForm: userInputForm,  
89 - snackbarStatus: snackbarStatus,  
90 - );  
91 -}  
92 -  
93 class GetSnackBar extends StatefulWidget { 14 class GetSnackBar extends StatefulWidget {
94 /// A callback for you to listen to the different Snack status 15 /// A callback for you to listen to the different Snack status
95 final SnackbarStatusCallback? snackbarStatus; 16 final SnackbarStatusCallback? snackbarStatus;
@@ -298,11 +219,11 @@ class GetSnackBarState extends State<GetSnackBar> @@ -298,11 +219,11 @@ class GetSnackBarState extends State<GetSnackBar>
298 AnimationController? _fadeController; 219 AnimationController? _fadeController;
299 late Animation<double> _fadeAnimation; 220 late Animation<double> _fadeAnimation;
300 221
301 - final Widget _emptyWidget = SizedBox(width: 0.0, height: 0.0); 222 + final Widget _emptyWidget = const SizedBox(width: 0.0, height: 0.0);
302 final double _initialOpacity = 1.0; 223 final double _initialOpacity = 1.0;
303 final double _finalOpacity = 0.4; 224 final double _finalOpacity = 0.4;
304 225
305 - final Duration _pulseAnimationDuration = Duration(seconds: 1); 226 + final Duration _pulseAnimationDuration = const Duration(seconds: 1);
306 227
307 late bool _isTitlePresent; 228 late bool _isTitlePresent;
308 late double _messageTopMargin; 229 late double _messageTopMargin;
@@ -518,9 +439,9 @@ You need to either use message[String], or messageText[Widget] or define a userI @@ -518,9 +439,9 @@ You need to either use message[String], or messageText[Widget] or define a userI
518 padding: const EdgeInsets.only( 439 padding: const EdgeInsets.only(
519 left: 8.0, right: 8.0, bottom: 8.0, top: 16.0), 440 left: 8.0, right: 8.0, bottom: 8.0, top: 16.0),
520 child: FocusScope( 441 child: FocusScope(
521 - child: widget.userInputForm!,  
522 node: _focusNode, 442 node: _focusNode,
523 autofocus: true, 443 autofocus: true,
  444 + child: widget.userInputForm!,
524 ), 445 ),
525 ), 446 ),
526 ); 447 );
@@ -586,7 +507,7 @@ You need to either use message[String], or messageText[Widget] or define a userI @@ -586,7 +507,7 @@ You need to either use message[String], or messageText[Widget] or define a userI
586 child: widget.titleText ?? 507 child: widget.titleText ??
587 Text( 508 Text(
588 widget.title ?? "", 509 widget.title ?? "",
589 - style: TextStyle( 510 + style: const TextStyle(
590 fontSize: 16.0, 511 fontSize: 16.0,
591 color: Colors.white, 512 color: Colors.white,
592 fontWeight: FontWeight.bold, 513 fontWeight: FontWeight.bold,
@@ -605,8 +526,8 @@ You need to either use message[String], or messageText[Widget] or define a userI @@ -605,8 +526,8 @@ You need to either use message[String], or messageText[Widget] or define a userI
605 child: widget.messageText ?? 526 child: widget.messageText ??
606 Text( 527 Text(
607 widget.message ?? "", 528 widget.message ?? "",
608 - style:  
609 - TextStyle(fontSize: 14.0, color: Colors.white), 529 + style: const TextStyle(
  530 + fontSize: 14.0, color: Colors.white),
610 ), 531 ),
611 ), 532 ),
612 ], 533 ],
@@ -220,15 +220,15 @@ class SnackbarController { @@ -220,15 +220,15 @@ class SnackbarController {
220 ], 220 ],
221 OverlayEntry( 221 OverlayEntry(
222 builder: (context) => Semantics( 222 builder: (context) => Semantics(
  223 + focused: false,
  224 + container: true,
  225 + explicitChildNodes: true,
223 child: AlignTransition( 226 child: AlignTransition(
224 alignment: _animation, 227 alignment: _animation,
225 child: snackbar.isDismissible 228 child: snackbar.isDismissible
226 ? _getDismissibleSnack(child) 229 ? _getDismissibleSnack(child)
227 : _getSnackbarContainer(child), 230 : _getSnackbarContainer(child),
228 ), 231 ),
229 - focused: false,  
230 - container: true,  
231 - explicitChildNodes: true,  
232 ), 232 ),
233 maintainState: false, 233 maintainState: false,
234 opaque: false, 234 opaque: false,
@@ -226,11 +226,11 @@ Worker debounce<T>( @@ -226,11 +226,11 @@ Worker debounce<T>(
226 void Function()? onDone, 226 void Function()? onDone,
227 bool? cancelOnError, 227 bool? cancelOnError,
228 }) { 228 }) {
229 - final _debouncer = 229 + final newDebouncer =
230 Debouncer(delay: time ?? const Duration(milliseconds: 800)); 230 Debouncer(delay: time ?? const Duration(milliseconds: 800));
231 StreamSubscription sub = listener.listen( 231 StreamSubscription sub = listener.listen(
232 (event) { 232 (event) {
233 - _debouncer(() { 233 + newDebouncer(() {
234 callback(event); 234 callback(event);
235 }); 235 });
236 }, 236 },
@@ -22,6 +22,7 @@ class GetX<T extends GetLifeCycleMixin> extends StatefulWidget { @@ -22,6 +22,7 @@ class GetX<T extends GetLifeCycleMixin> extends StatefulWidget {
22 final String? tag; 22 final String? tag;
23 23
24 const GetX({ 24 const GetX({
  25 + super.key,
25 this.tag, 26 this.tag,
26 required this.builder, 27 required this.builder,
27 this.global = true, 28 this.global = true,
@@ -32,7 +32,7 @@ mixin StateMixin<T> on ListNotifier { @@ -32,7 +32,7 @@ mixin StateMixin<T> on ListNotifier {
32 void _fillInitialStatus() { 32 void _fillInitialStatus() {
33 _status = (_value == null || _value!._isEmpty()) 33 _status = (_value == null || _value!._isEmpty())
34 ? GetStatus<T>.loading() 34 ? GetStatus<T>.loading()
35 - : GetStatus<T>.success(_value!); 35 + : GetStatus<T>.success(_value as T);
36 } 36 }
37 37
38 GetStatus<T> get status { 38 GetStatus<T> get status {
@@ -71,7 +71,7 @@ mixin StateMixin<T> on ListNotifier { @@ -71,7 +71,7 @@ mixin StateMixin<T> on ListNotifier {
71 } 71 }
72 } 72 }
73 73
74 - void futurize(Future<T> Function() body, 74 + void futurize(Future<T> Function() body,
75 {T? initialData, String? errorMessage, bool useEmpty = true}) { 75 {T? initialData, String? errorMessage, bool useEmpty = true}) {
76 final compute = body; 76 final compute = body;
77 _value ??= initialData; 77 _value ??= initialData;
@@ -231,12 +231,12 @@ extension StateExt<T> on StateMixin<T> { @@ -231,12 +231,12 @@ extension StateExt<T> on StateMixin<T> {
231 : Center(child: Text('A error occurred: ${status.errorMessage}')); 231 : Center(child: Text('A error occurred: ${status.errorMessage}'));
232 } else if (status.isEmpty) { 232 } else if (status.isEmpty) {
233 return onEmpty ?? 233 return onEmpty ??
234 - SizedBox.shrink(); // Also can be widget(null); but is risky 234 + const SizedBox.shrink(); // Also can be widget(null); but is risky
235 } else if (status.isSuccess) { 235 } else if (status.isSuccess) {
236 return widget(value); 236 return widget(value);
237 } else if (status.isCustom) { 237 } else if (status.isCustom) {
238 return onCustom?.call(_) ?? 238 return onCustom?.call(_) ??
239 - SizedBox.shrink(); // Also can be widget(null); but is risky 239 + const SizedBox.shrink(); // Also can be widget(null); but is risky
240 } 240 }
241 return widget(value); 241 return widget(value);
242 }); 242 });
@@ -24,7 +24,7 @@ abstract class ObxWidget extends ObxStatelessWidget { @@ -24,7 +24,7 @@ abstract class ObxWidget extends ObxStatelessWidget {
24 class Obx extends ObxWidget { 24 class Obx extends ObxWidget {
25 final WidgetCallback builder; 25 final WidgetCallback builder;
26 26
27 - const Obx(this.builder); 27 + const Obx(this.builder, {super.key});
28 28
29 @override 29 @override
30 Widget build(BuildContext context) { 30 Widget build(BuildContext context) {
@@ -482,7 +482,7 @@ class BindElement<T> extends InheritedElement { @@ -482,7 +482,7 @@ class BindElement<T> extends InheritedElement {
482 /// setState "link" from the Controller. 482 /// setState "link" from the Controller.
483 void _subscribeToController() { 483 void _subscribeToController() {
484 if (widget.filter != null) { 484 if (widget.filter != null) {
485 - _filter = widget.filter!(_controller!); 485 + _filter = widget.filter!(_controller as T);
486 } 486 }
487 final filter = _filter != null ? _filterUpdate : getUpdate; 487 final filter = _filter != null ? _filterUpdate : getUpdate;
488 final localController = _controller; 488 final localController = _controller;
@@ -510,7 +510,7 @@ class BindElement<T> extends InheritedElement { @@ -510,7 +510,7 @@ class BindElement<T> extends InheritedElement {
510 } 510 }
511 511
512 void _filterUpdate() { 512 void _filterUpdate() {
513 - var newFilter = widget.filter!(_controller!); 513 + var newFilter = widget.filter!(_controller as T);
514 if (newFilter != _filter) { 514 if (newFilter != _filter) {
515 _filter = newFilter; 515 _filter = newFilter;
516 getUpdate(); 516 getUpdate();
@@ -176,11 +176,11 @@ class Notifier { @@ -176,11 +176,11 @@ class Notifier {
176 _notifyData?.disposers.add(listener); 176 _notifyData?.disposers.add(listener);
177 } 177 }
178 178
179 - void read(ListNotifierSingleMixin _updaters) { 179 + void read(ListNotifierSingleMixin updaters) {
180 final listener = _notifyData?.updater; 180 final listener = _notifyData?.updater;
181 - if (listener != null && !_updaters.containsListener(listener)) {  
182 - _updaters.addListener(listener);  
183 - add(() => _updaters.removeListener(listener)); 181 + if (listener != null && !updaters.containsListener(listener)) {
  182 + updaters.addListener(listener);
  183 + add(() => updaters.removeListener(listener));
184 } 184 }
185 } 185 }
186 186
@@ -188,7 +188,7 @@ class Notifier { @@ -188,7 +188,7 @@ class Notifier {
188 _notifyData = data; 188 _notifyData = data;
189 final result = builder(); 189 final result = builder();
190 if (data.disposers.isEmpty && data.throwException) { 190 if (data.disposers.isEmpty && data.throwException) {
191 - throw ObxError(); 191 + throw const ObxError();
192 } 192 }
193 _notifyData = null; 193 _notifyData = null;
194 return result; 194 return result;
@@ -38,12 +38,16 @@ class ValueBuilder<T> extends StatefulWidget { @@ -38,12 +38,16 @@ class ValueBuilder<T> extends StatefulWidget {
38 }) : super(key: key); 38 }) : super(key: key);
39 39
40 @override 40 @override
41 - _ValueBuilderState<T> createState() => _ValueBuilderState<T>(initialValue); 41 + ValueBuilderState<T> createState() => ValueBuilderState<T>();
42 } 42 }
43 43
44 -class _ValueBuilderState<T> extends State<ValueBuilder<T>> {  
45 - T value;  
46 - _ValueBuilderState(this.value); 44 +class ValueBuilderState<T> extends State<ValueBuilder<T>> {
  45 + late T value;
  46 + @override
  47 + void initState() {
  48 + value = widget.initialValue;
  49 + super.initState();
  50 + }
47 51
48 @override 52 @override
49 Widget build(BuildContext context) => widget.builder(value, updater); 53 Widget build(BuildContext context) => widget.builder(value, updater);