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 |
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' |
example/analysis_options.yaml
0 → 100644
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'; |
lib/get_animations/animations.dart
0 → 100644
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 | +} |
lib/get_animations/extensions.dart
0 → 100644
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 | +} |
lib/get_animations/get_animated_builder.dart
0 → 100644
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 | +} |
lib/get_animations/index.dart
0 → 100644
@@ -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, |
lib/get_navigation/src/root/get_root.dart
0 → 100644
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 | -} |
@@ -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); |
-
Please register or login to post a comment