Victor Santelé
Committed by GitHub

Merge pull request #1 from jonataslaw/master

update
Showing 58 changed files with 1263 additions and 1101 deletions

Too many changes to show.

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

No preview for this file type
... ... @@ -23,7 +23,7 @@ jobs:
# https://github.com/marketplace/actions/flutter-action
- uses: subosito/flutter-action@v1
with:
flutter-version: "1.22.3"
flutter-version: "2.0.2"
channel: "stable"
- run: flutter pub get
#- run: flutter analyze
... ...
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 60bd88df915880d23877bfc1602e8ddcf4c4dd2a
channel: stable
project_type: app
... ...
## [4.1.2]
- Fix warning ˜can add data to a closed stream˜ when GetBuilder and Obx are nested
- Fix get_connect decoder can not be null (@Goddchen)
- Migrate example code (@3lB4rt0)
- Fix initial value of nullables (@RafaRuiz)
- Improve error message to navigation (@maxzod)
- Fix typo on docs (@Rahulshahare)
- Fixed darktheme being changed only through Get.changeTheme and not through the DarkTheme theme property in MaterialApp (@GoldenSoju)
- Fix controller is removed when navigate to same page (@eduardoflorence)
- Fix missing reload() and reloadAll() to Get extensions (@lkloon123)
## [4.1.1]
- Remove mandatory initialValue to nullables types
## [4.1.0]
- Added Rxn to non nullables reactives types
## [4.0.3]
- Added new linter rules to improve score
## [4.0.2]
- Removed "!" of if else conditions until the null-safety of the dart is consistent for using it.
## [4.0.1]
- Fix changelog
## [4.0.0]
- Added append function to StateMixin. Now is possible track loading, success and error handle of your application with ONE LINE OF CODE. Ex: append(()=> api.getUser);
- Migrate to null-safety
- Added ScrollMixin to controllers
- Added loadingMore status to RxStatus
- Fix content-type qual null (@katekko)
- Made GetInstance non nullable (@eduardoflorence)
- Fix multi-parameters url (@iMrLopez)
- Fix Expected value of SkDeletable error (@obadajasm)
- Added triggers, an Rx method that triggers events, even if they are the same as the previous event (@RafaRuiz)
- Improve docs: (@CNAD666), (@dhhAndroid), (@Jackylee1992),
Switching to null-safety:
You can continue using GetX as normal, with as little breaking changes as possible.
It is still possible to declare the var.obs variable, and this remains the preferred way, forcing null-safety and giving you all the security that sound null-safety delivers to your app. However, if you need to use null, we also provide a solution for you.
Declare the variables with `?` Ex: `final Rx<int?> count = 0.obs`.
You can also use custom Rxn types with null-safety:
`RxInt` == not nullable
`RxnInt` == nullable.
## [3.25.6]
- Added documentation in French (@kamazoun)
- Fix logs messages (@damphat)
... ...
... ... @@ -119,7 +119,7 @@ void main() => runApp(GetMaterialApp(home: Home()));
```
- Note: this does not modify the MaterialApp of the Flutter, GetMaterialApp is not a modified MaterialApp, it is just a pre-configured Widget, which has the default MaterialApp as a child. You can configure this manually, but it is definitely not necessary. GetMaterialApp will create routes, inject them, inject translations, inject everything you need for route navigation. If you use Get only for state management or dependency management, it is not necessary to use GetMaterialApp. GetMaterialApp is necessary for routes, snackbars, internationalization, bottomSheets, dialogs, and high-level apis related to routes and absence of context.
- Note²: This step in only necessary if you gonna use route management (`Get.to()`, `Get.back()` and so on). If you not gonna use it then it is not necessary to do step 1
- Note²: This step is only necessary if you gonna use route management (`Get.to()`, `Get.back()` and so on). If you not gonna use it then it is not necessary to do step 1
- Step 2:
Create your business logic class and place all variables, methods and controllers inside it.
... ...
... ... @@ -214,7 +214,7 @@ Obx(() => Text("${controller.name}"));
### 关于状态管理的更多细节
**关于状态管理更深入的解释请查看[这里](./documentation/zh_CN/state_management.md)。在那里你将看到更多的例子,以及简单的阶段管理器和响应式状态管理器之间的区别**
**关于状态管理更深入的解释请查看[这里](./documentation/zh_CN/state_management.md)。在那里你将看到更多的例子,以及简单的状态管理器和响应式状态管理器之间的区别**
你会对GetX的能力有一个很好的了解。
... ...
... ... @@ -20,6 +20,8 @@ linter:
# INCLUDE_FIX (copy of effective dart 1.2.0)
# STYLE
camel_case_types: true
close_sinks: true
unnecessary_statements: true
camel_case_extensions: true
library_names: true
file_names: true
... ...
... ... @@ -246,6 +246,28 @@ print(Get.parameters['user']);
// out: 34954
```
or send multiple parameters like this
```dart
Get.toNamed("/profile/34954?flag=true&country=italy");
```
or
```dart
var parameters = <String, String>{"flag": "true","country": "italy",};
Get.toNamed("/profile/34954", parameters: parameters);
```
On second screen take the data by parameters as usually
```dart
print(Get.parameters['user']);
print(Get.parameters['flag']);
print(Get.parameters['country']);
// out: 34954 true italy
```
And now, all you need to do is use Get.toNamed() to navigate your named routes, without any context (you can call your routes directly from your BLoC or Controller class), and when your app is compiled to the web, your routes will appear in the url <3
### Middleware
... ...
... ... @@ -242,7 +242,21 @@ Y en la segunda pantalla tome los datos por parámetro
```dart
print(Get.parameters['user']);
// out: 34954
// salida: 34954
```
o envie multiples parametros de la siguiente manera
```dart
Get.toNamed("/profile/34954?flag=true");
```
En la segunda pantalla tome los parametros como lo haria normalmente
```dart
print(Get.parameters['user']);
print(Get.parameters['flag']);
// salida: 34954 true
```
Y ahora, todo lo que necesita hacer es usar Get.toNamed() para navegar por sus rutas nombradas, sin ningún contexto (puede llamar a sus rutas directamente desde su clase BLoC o Controller), y cuando su aplicación se compila para web, sus rutas aparecerán en la url del navegador <3
... ...
... ... @@ -247,6 +247,20 @@ print(Get.parameters['user']);
// donne: 34954
```
ou envoyer plusieurs paramètres comme celui-ci
```dart
Get.toNamed("/profile/34954?flag=true");
```
Sur le deuxième écran, prenez les données par paramètres comme d'habitude
```dart
print(Get.parameters['user']);
print(Get.parameters['flag']);
// donne: 34954 true
```
Et maintenant, tout ce que vous avez à faire est d'utiliser Get.toNamed() pour parcourir vos routes nommées, sans aucun contexte (vous pouvez appeler vos routes directement à partir de votre classe BLoC ou Controller), et lorsque votre application est compilée sur le Web, vos routes apparaîtront dans l'url <3
### Middleware
... ...
... ... @@ -248,6 +248,21 @@ print(Get.parameters['user']);
// keluaran: 34954
```
atau kirim beberapa parameter seperti ini
```dart
Get.toNamed("/profile/34954?flag=true");
```
Pada layar kedua, ambil data berdasarkan parameter seperti biasanya
```dart
print(Get.parameters['user']);
print(Get.parameters['flag']);
// keluaran: 34954 true
```
Dan sekarang, yang anda perlu lakukan adalah menggunakan Get.toNamed() untuk bernavigasi ke named route anda, tanpa konteks (anda bisa memanggil route secara langsung dari kelas BLoC atau Controller), dan ketika aplikasi anda di-compile di web, route anda akan muncul di url <3
### Middleware
... ...
... ... @@ -246,6 +246,23 @@ print(Get.parameters['user']);
// 출력: 34954
```
또는 이와 같은 여러 매개 변수를 보냅니다.
```dart
Get.toNamed("/profile/34954?flag=true");
```
두 번째 화면에서 일반적으로 매개 변수별로 데이터를 가져옵니다.
```dart
print(Get.parameters['user']);
print(Get.parameters['flag']);
// 출력: 34954 true
```
이제 Get.toNamed()를 사용하여 어떤 context도 없이 명명된 라우트를 탐색하고 (BLoC 또는 Controller 클래스로 부터 직접 라우트를 호출할 수 있음) 앱이 웹으로 컴파일되면 경로는 url에 표시됩니다. <3
### 미들웨어
... ...
... ... @@ -322,9 +322,26 @@ Get.toNamed("/segunda/34954");
Na segunda tela receba os dados usando `Get.parameters[]`
```dart
print(Get.parameters['user']); // valor: 34954
print(Get.parameters['user']);
// valor: 34954
```
ou envie vários parâmetros como este
```dart
Get.toNamed("/profile/34954?flag=true");
```
Na segunda tela, pegue os dados por parâmetros normalmente
```dart
print(Get.parameters['user']);
print(Get.parameters['flag']);
// valor: 34954 true
```
E agora, tudo que você precisa fazer é usar `Get.toNamed)` para navegar por suas rotas nomeadas, sem nenhum `context` (você pode chamar suas rotas diretamente do seu BLoc ou do Controller), e quando seu aplicativo é compilado para a web, suas rotas vão aparecer na url ❤
#### Middleware
... ...
... ... @@ -246,6 +246,22 @@ print(Get.parameters['user']);
// out: 34954
```
или отправьте несколько таких параметров
```dart
Get.toNamed("/profile/34954?flag=true");
```
На втором экране взять данные по параметрам как обычно.
```dart
print(Get.parameters['user']);
print(Get.parameters['flag']);
// out: 34954 true
```
И теперь все, что вам нужно сделать, это использовать Get.toNamed() для навигации по именованным маршрутам без какого-либо контекста (вы можете вызывать свои маршруты непосредственно из класса BLoC или контроллера), а когда ваше приложение будет скомпилировано в Интернете, ваше маршруты появятся в url <3
### Middleware
... ...
... ... @@ -243,6 +243,21 @@ print(Get.parameters['user']);
// out: 34954
```
或像这样发送多个参数
```dart
Get.toNamed("/profile/34954?flag=true");
```
在第二个屏幕上,通常按参数获取数据
```dart
print(Get.parameters['user']);
print(Get.parameters['flag']);
// out: 34954 true
```
现在,你需要做的就是使用Get.toNamed()来导航你的别名路由,不需要任何context(你可以直接从你的BLoC或Controller类中调用你的路由),当你的应用程序被编译到web时,你的路由将出现在URL中。
### 中间件
... ...
... ... @@ -343,25 +343,24 @@ ListView.builder (
```dart
// model
// 我们将使整个类成为可观察的,而不是每个属性。
class User() {
User({this.name = '', this.age = 0});
String name;
int age;
class User{
User({this.name = '', this.age = 0});
String name;
int age;
}
// controller
final user = User().obs;
//当你需要更新user变量时。
user.update( (user) { // 这个参数是你要更新的类本身。
user.name = 'Jonny';
user.age = 18;
user.name = 'Jonny';
user.age = 18;
});
// 更新user变量的另一种方式。
user(User(name: 'João', age: 35));
// view
Obx(()=> Text("Name ${user.value.name}: Age: ${user.value.age}"))
Obx(()=> Text("Name ${user.value.name}: Age: ${user.value.age}"));
// 你也可以不使用.value来访问模型值。
user().name; // 注意是user变量,而不是类变量(首字母是小写的)。
```
... ... @@ -410,7 +409,7 @@ interval(count1, (_) => print("interval $_"), time: Duration(seconds: 1));
这个`condition`定义了`callback`函数何时执行。
所有worker都会返回一个`Worker`实例,你可以用它来取消(通过`dispose()`)worker。
- **`ever`**
每当_Rx_变量发出一个新的值时,就会被调用。
... ... @@ -666,7 +665,7 @@ GetBuilder<Controller>(
```dart
GetBuilder<Controller>(
id: 'text' 、、这里
id: 'text', //这里
init: Controller(), // 每个控制器只用一次
builder: (_) => Text(
'${Get.find<Controller>().counter}', //here
... ...
... ... @@ -33,6 +33,7 @@
/ios/
/android/
/web/
/macos/
# Web related
lib/generated_plugin_registrant.dart
... ...
... ... @@ -282,6 +282,7 @@ As the view has only widgets, you can use a view for android, and another for iO
However, some examples like internationalization, Snackbars without context, validators, responsiveness and other Getx resources, were not explored (and it would not even be possible to explore all resources in such a simple example), so below is an example not very complete, but trying demonstrate how to use internationalization, reactive custom classes, reactive lists, snackbars contextless, workers etc.
```dart
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
... ... @@ -397,29 +398,27 @@ class Second extends GetView<ControllerX> {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GetX<ControllerX>(
// Using bindings you don't need of init: method
// Using Getx you can take controller instance of "builder: (_)"
builder: (_) {
Obx(
() {
print("count1 rebuild");
return Text('${_.count1}');
return Text('${controller.count1}');
},
),
GetX<ControllerX>(
builder: (_) {
Obx(
() {
print("count2 rebuild");
return Text('${controller.count2}');
},
),
GetX<ControllerX>(builder: (_) {
Obx(() {
print("sum rebuild");
return Text('${_.sum}');
return Text('${controller.sum}');
}),
GetX<ControllerX>(
builder: (_) => Text('Name: ${controller.user.value.name}'),
Obx(
() => Text('Name: ${controller.user.value?.name}'),
),
GetX<ControllerX>(
builder: (_) => Text('Age: ${_.user.value.age}'),
Obx(
() => Text('Age: ${controller.user.value?.age}'),
),
ElevatedButton(
child: Text("Go to last page"),
... ... @@ -440,25 +439,25 @@ class Second extends GetView<ControllerX> {
ElevatedButton(
child: Text("Increment"),
onPressed: () {
Get.find<ControllerX>().increment();
controller.increment();
},
),
ElevatedButton(
child: Text("Increment"),
onPressed: () {
Get.find<ControllerX>().increment2();
controller.increment2();
},
),
ElevatedButton(
child: Text("Update name"),
onPressed: () {
Get.find<ControllerX>().updateUser();
controller.updateUser();
},
),
ElevatedButton(
child: Text("Dispose worker"),
onPressed: () {
Get.find<ControllerX>().disposeWorker();
controller.disposeWorker();
},
),
],
... ... @@ -509,7 +508,7 @@ class ControllerX extends GetxController {
updateUser() {
user.update((value) {
value.name = 'Jose';
value!.name = 'Jose';
value.age = 30;
});
}
... ... @@ -523,7 +522,7 @@ class ControllerX extends GetxController {
/// Here is an outline of how you can use them:
/// made this if you need cancel you worker
Worker _ever;
late Worker _ever;
@override
onInit() {
... ... @@ -562,8 +561,8 @@ class SizeTransitions extends CustomTransition {
@override
Widget buildTransition(
BuildContext context,
Curve curve,
Alignment alignment,
Curve? curve,
Alignment? alignment,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
... ... @@ -572,7 +571,7 @@ class SizeTransitions extends CustomTransition {
child: SizeTransition(
sizeFactor: CurvedAnimation(
parent: animation,
curve: curve,
curve: curve!,
),
child: child,
),
... ...
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'en_US.dart';
import 'pt_BR.dart';
import 'en_us.dart';
import 'pt_br.dart';
class TranslationService extends Translations {
static final locale = Get.deviceLocale;
static Locale get locale => Get.deviceLocale;
static final fallbackLocale = Locale('en', 'US');
@override
@override
Map<String, Map<String, String>> get keys => {
'en_US': en_US,
'pt_BR': pt_BR,
};
}
\ No newline at end of file
'en_US': en_US,
'pt_BR': pt_BR,
};
}
... ...
... ... @@ -9,7 +9,7 @@ void main() {
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
... ...
... ... @@ -9,7 +9,8 @@ abstract class IHomeProvider {
class HomeProvider extends GetConnect implements IHomeProvider {
@override
void onInit() {
httpClient.defaultDecoder = CasesModel.fromJson;
httpClient.defaultDecoder =
(val) => CasesModel.fromJson(val as Map<String, dynamic>);
httpClient.baseUrl = 'https://api.covid19api.com';
}
... ...
... ... @@ -3,16 +3,16 @@ import '../domain/entity/cases_model.dart';
import 'home_api_provider.dart';
class HomeRepository implements IHomeRepository {
HomeRepository({this.provider});
HomeRepository({required this.provider});
final IHomeProvider provider;
@override
Future<CasesModel> getCases() async {
final cases = await provider.getCases("/summary");
if (cases.status.hasError) {
return Future.error(cases.statusText);
return Future.error(cases.statusText!);
} else {
return cases.body;
return cases.body!;
}
}
}
... ...
// To parse this JSON data, do
//
// final CasesModel = CasesModelFromJson(jsonString);
// final welcome = welcomeFromJson(jsonString);
import 'dart:convert';
class CasesModel {
final Global global;
final List<Country> countries;
final String date;
CasesModel({
this.global,
this.countries,
this.date,
required this.id,
required this.message,
required this.global,
required this.countries,
required this.date,
});
static CasesModel fromRawJson(String str) =>
final String id;
final String message;
final Global global;
final List<Country> countries;
final DateTime date;
factory CasesModel.fromRawJson(String str) =>
CasesModel.fromJson(json.decode(str) as Map<String, dynamic>);
String toRawJson() => json.encode(toJson());
static CasesModel fromJson(dynamic json) => CasesModel(
global: json["Global"] == null
? null
: Global.fromJson(json["Global"] as Map<String, dynamic>),
countries: json["Countries"] == null
? null
: List<Country>.from(
(json["Countries"] as List<dynamic>)
.map((x) => Country.fromJson(x as Map<String, dynamic>)),
),
date: json["Date"] == null ? null : json["Date"] as String,
factory CasesModel.fromJson(Map<String, dynamic> json) => CasesModel(
id: json["ID"] as String,
message: json["Message"] as String,
global: Global.fromJson(json["Global"] as Map<String, dynamic>),
countries: List<Country>.from((json["Countries"] as Iterable).map(
(x) => Country.fromJson(x as Map<String, dynamic>),
)),
date: DateTime.parse(json["Date"] as String),
);
Map<String, dynamic> toJson() => {
"Global": global == null ? null : global.toJson(),
"Countries": countries == null
? null
: List<dynamic>.from(countries.map((x) => x.toJson())),
"Date": date == null ? null : date,
"ID": id,
"Message": message,
"Global": global.toJson(),
"Countries": List<dynamic>.from(countries.map((x) => x.toJson())),
"Date": date.toIso8601String(),
};
}
class Country {
Country({
required this.id,
required this.country,
required this.countryCode,
required this.slug,
required this.newConfirmed,
required this.totalConfirmed,
required this.newDeaths,
required this.totalDeaths,
required this.newRecovered,
required this.totalRecovered,
required this.date,
required this.premium,
});
final String id;
final String country;
final String countryCode;
final String slug;
... ... @@ -52,20 +69,8 @@ class Country {
final int totalDeaths;
final int newRecovered;
final int totalRecovered;
final String date;
Country({
this.country,
this.countryCode,
this.slug,
this.newConfirmed,
this.totalConfirmed,
this.newDeaths,
this.totalDeaths,
this.newRecovered,
this.totalRecovered,
this.date,
});
final DateTime date;
final Premium premium;
factory Country.fromRawJson(String str) =>
Country.fromJson(json.decode(str) as Map<String, dynamic>);
... ... @@ -73,56 +78,67 @@ class Country {
String toRawJson() => json.encode(toJson());
factory Country.fromJson(Map<String, dynamic> json) => Country(
country: json["Country"] == null ? null : json["Country"] as String,
countryCode:
json["CountryCode"] == null ? null : json["CountryCode"] as String,
slug: json["Slug"] == null ? null : json["Slug"] as String,
newConfirmed:
json["NewConfirmed"] == null ? null : json["NewConfirmed"] as int,
totalConfirmed: json["TotalConfirmed"] == null
? null
: json["TotalConfirmed"] as int,
newDeaths: json["NewDeaths"] == null ? null : json["NewDeaths"] as int,
totalDeaths:
json["TotalDeaths"] == null ? null : json["TotalDeaths"] as int,
newRecovered:
json["NewRecovered"] == null ? null : json["NewRecovered"] as int,
totalRecovered: json["TotalRecovered"] == null
? null
: json["TotalRecovered"] as int,
date: json["Date"] == null ? null : json["Date"] as String,
id: json["ID"] as String,
country: json["Country"] as String,
countryCode: json["CountryCode"] as String,
slug: json["Slug"] as String,
newConfirmed: json["NewConfirmed"] as int,
totalConfirmed: json["TotalConfirmed"] as int,
newDeaths: json["NewDeaths"] as int,
totalDeaths: json["TotalDeaths"] as int,
newRecovered: json["NewRecovered"] as int,
totalRecovered: json["TotalRecovered"] as int,
date: DateTime.parse(json["Date"] as String),
premium: Premium.fromJson(json["Premium"] as Map<String, dynamic>),
);
Map<String, dynamic> toJson() => {
"Country": country == null ? null : country,
"CountryCode": countryCode == null ? null : countryCode,
"Slug": slug == null ? null : slug,
"NewConfirmed": newConfirmed == null ? null : newConfirmed,
"TotalConfirmed": totalConfirmed == null ? null : totalConfirmed,
"NewDeaths": newDeaths == null ? null : newDeaths,
"TotalDeaths": totalDeaths == null ? null : totalDeaths,
"NewRecovered": newRecovered == null ? null : newRecovered,
"TotalRecovered": totalRecovered == null ? null : totalRecovered,
"Date": date == null ? null : date,
"ID": id,
"Country": country,
"CountryCode": countryCode,
"Slug": slug,
"NewConfirmed": newConfirmed,
"TotalConfirmed": totalConfirmed,
"NewDeaths": newDeaths,
"TotalDeaths": totalDeaths,
"NewRecovered": newRecovered,
"TotalRecovered": totalRecovered,
"Date": date.toIso8601String(),
"Premium": premium.toJson(),
};
}
class Premium {
Premium();
factory Premium.fromRawJson(String str) =>
Premium.fromJson(json.decode(str) as Map<String, dynamic>);
String toRawJson() => json.encode(toJson());
factory Premium.fromJson(Map<String, dynamic> json) => Premium();
Map<String, dynamic> toJson() => {};
}
class Global {
Global({
required this.newConfirmed,
required this.totalConfirmed,
required this.newDeaths,
required this.totalDeaths,
required this.newRecovered,
required this.totalRecovered,
required this.date,
});
final int newConfirmed;
final int totalConfirmed;
final int newDeaths;
final int totalDeaths;
final int newRecovered;
final int totalRecovered;
Global({
this.newConfirmed,
this.totalConfirmed,
this.newDeaths,
this.totalDeaths,
this.newRecovered,
this.totalRecovered,
});
final DateTime date;
factory Global.fromRawJson(String str) =>
Global.fromJson(json.decode(str) as Map<String, dynamic>);
... ... @@ -130,27 +146,22 @@ class Global {
String toRawJson() => json.encode(toJson());
factory Global.fromJson(Map<String, dynamic> json) => Global(
newConfirmed:
json["NewConfirmed"] == null ? null : json["NewConfirmed"] as int,
totalConfirmed: json["TotalConfirmed"] == null
? null
: json["TotalConfirmed"] as int,
newDeaths: json["NewDeaths"] == null ? null : json["NewDeaths"] as int,
totalDeaths:
json["TotalDeaths"] == null ? null : json["TotalDeaths"] as int,
newRecovered:
json["NewRecovered"] == null ? null : json["NewRecovered"] as int,
totalRecovered: json["TotalRecovered"] == null
? null
: json["TotalRecovered"] as int,
newConfirmed: json["NewConfirmed"] as int,
totalConfirmed: json["TotalConfirmed"] as int,
newDeaths: json["NewDeaths"] as int,
totalDeaths: json["TotalDeaths"] as int,
newRecovered: json["NewRecovered"] as int,
totalRecovered: json["TotalRecovered"] as int,
date: DateTime.parse(json["Date"] as String),
);
Map<String, dynamic> toJson() => {
"NewConfirmed": newConfirmed == null ? null : newConfirmed,
"TotalConfirmed": totalConfirmed == null ? null : totalConfirmed,
"NewDeaths": newDeaths == null ? null : newDeaths,
"TotalDeaths": totalDeaths == null ? null : totalDeaths,
"NewRecovered": newRecovered == null ? null : newRecovered,
"TotalRecovered": totalRecovered == null ? null : totalRecovered,
"NewConfirmed": newConfirmed,
"TotalConfirmed": totalConfirmed,
"NewDeaths": newDeaths,
"TotalDeaths": totalDeaths,
"NewRecovered": newRecovered,
"TotalRecovered": totalRecovered,
"Date": date.toIso8601String(),
};
}
... ...
... ... @@ -4,22 +4,16 @@ import '../../domain/adapters/repository_adapter.dart';
import '../../domain/entity/cases_model.dart';
class HomeController extends SuperController<CasesModel> {
HomeController({this.homeRepository});
HomeController({required this.homeRepository});
/// inject repo abstraction dependency
final IHomeRepository homeRepository;
/// When the controller is initialized, make the http request
@override
void onInit() {
super.onInit();
// show loading on start, data on success
// and error message on error with 0 boilerplate
homeRepository.getCases().then((data) {
change(data, status: RxStatus.success());
}, onError: (err) {
change(null, status: RxStatus.error(err.toString()));
});
//Loading, Success, Error handle with 1 line of code
append(() => homeRepository.getCases);
}
@override
... ...
... ... @@ -18,7 +18,6 @@ class CountryView extends GetView<HomeController> {
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 15.0, sigmaY: 15.0),
child: Container(
decoration: BoxDecoration(color: Colors.white.withOpacity(0.0)),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
... ... @@ -29,9 +28,9 @@ class CountryView extends GetView<HomeController> {
),
body: Center(
child: ListView.builder(
itemCount: controller.state.countries.length,
itemCount: controller.state!.countries.length,
itemBuilder: (context, index) {
final country = controller.state.countries[index];
final country = controller.state!.countries[index];
return ListTile(
onTap: () {
Get.toNamed('/home/country/details',
... ...
... ... @@ -21,7 +21,6 @@ class DetailsView extends StatelessWidget {
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 15.0, sigmaY: 15.0),
child: Container(
decoration: BoxDecoration(color: Colors.white.withOpacity(0.0)),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
... ...
... ... @@ -42,7 +42,7 @@ class HomeView extends GetView<HomeController> {
),
),
Text(
'${state.global.totalConfirmed}',
'${state!.global.totalConfirmed}',
style: TextStyle(fontSize: 45, fontWeight: FontWeight.bold),
),
SizedBox(
... ...
... ... @@ -18,7 +18,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
... ... @@ -28,7 +28,7 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons.
get:
path: ../
get_test: ^3.13.3
#get_test: ^3.13.3
dependency_overrides:
get:
... ...
... ... @@ -6,8 +6,8 @@ import 'package:get/get.dart';
import 'package:get_demo/pages/home/domain/adapters/repository_adapter.dart';
import 'package:get_demo/pages/home/domain/entity/cases_model.dart';
import 'package:get_demo/pages/home/presentation/controllers/home_controller.dart';
import 'package:get_demo/routes/app_pages.dart';
import 'package:get_test/get_test.dart';
// import 'package:get_demo/routes/app_pages.dart';
// import 'package:get_test/get_test.dart';
import 'package:matcher/matcher.dart' as m;
class MockRepository implements IHomeRepository {
... ... @@ -17,7 +17,18 @@ class MockRepository implements IHomeRepository {
if (Random().nextBool()) {
return CasesModel(
global: Global(totalDeaths: 100, totalConfirmed: 200),
global: Global(
totalDeaths: 100,
totalConfirmed: 200,
date: DateTime.now(),
newConfirmed: 0,
newDeaths: 0,
newRecovered: 0,
totalRecovered: 0),
countries: [],
date: DateTime.now(),
id: '',
message: '',
);
}
... ... @@ -26,6 +37,7 @@ class MockRepository implements IHomeRepository {
}
void main() {
WidgetsFlutterBinding.ensureInitialized();
setUpAll(() => HttpOverrides.global = null);
final binding = BindingsBuilder(() {
Get.lazyPut<IHomeRepository>(() => MockRepository());
... ... @@ -69,13 +81,25 @@ void main() {
}
if (controller.status.isSuccess) {
expect(controller.state.global.totalDeaths, 100);
expect(controller.state.global.totalConfirmed, 200);
expect(controller.state!.global.totalDeaths, 100);
expect(controller.state!.global.totalConfirmed, 200);
}
});
test('ever', () async {
final count = ''.obs;
var result = '';
ever<String>(count, (value) {
result = value;
});
count.value = '1';
expect('1', result);
});
/// Tests with GetTests
getTest(
/// TEMPORARILY REMOVED from the null-safetym branch as
/// get_test is not yet null safety.
/* getTest(
"test description",
getPages: AppPages.routes,
initialRoute: AppPages.INITIAL,
... ... @@ -104,33 +128,6 @@ void main() {
),
test: (e) {
expect(find.text("ban:0"), findsOneWidget);
expect(e.count.value, 0);
},
);
testGetBuilder(
'GetBuilder test',
widget: GetBuilder<Controller>(
init: Controller(),
builder: (controller) {
return Text("ban:${controller.count}");
},
),
test: (e) {
expect(find.text("ban:0"), findsOneWidget);
expect(e.count.value, 0);
},
);
testObx(
'Obx test',
widget: (controller) => Obx(
() => Text("ban:${controller.count}"),
),
controller: Controller(),
test: (e) {
expect(find.text("ban:0"), findsOneWidget);
expect(e.count.value, 0);
},
);
... ... @@ -151,7 +148,7 @@ void main() {
onClose: (c) {
print('onClose');
},
);
);*/
}
class Controller extends GetxController {
... ...
... ... @@ -13,74 +13,74 @@ export 'http/src/response/response.dart';
export 'sockets/sockets.dart';
abstract class GetConnectInterface with GetLifeCycleBase {
List<GetSocket> sockets;
List<GetSocket>? sockets;
GetHttpClient get httpClient;
Future<Response<T>> get<T>(
String url, {
Map<String, String> headers,
String contentType,
Map<String, dynamic> query,
Decoder<T> decoder,
Map<String, String>? headers,
String? contentType,
Map<String, dynamic>? query,
Decoder<T>? decoder,
});
Future<Response<T>> request<T>(
String url,
String method, {
dynamic body,
String contentType,
Map<String, String> headers,
Map<String, dynamic> query,
Decoder<T> decoder,
String? contentType,
Map<String, String>? headers,
Map<String, dynamic>? query,
Decoder<T>? decoder,
});
Future<Response<T>> post<T>(
String url,
dynamic body, {
String contentType,
Map<String, String> headers,
Map<String, dynamic> query,
Decoder<T> decoder,
String? contentType,
Map<String, String>? headers,
Map<String, dynamic>? query,
Decoder<T>? decoder,
});
Future<Response<T>> put<T>(
String url,
dynamic body, {
String contentType,
Map<String, String> headers,
Map<String, dynamic> query,
Decoder<T> decoder,
String? contentType,
Map<String, String>? headers,
Map<String, dynamic>? query,
Decoder<T>? decoder,
});
Future<Response<T>> delete<T>(
String url, {
Map<String, String> headers,
String contentType,
Map<String, dynamic> query,
Decoder<T> decoder,
Map<String, String>? headers,
String? contentType,
Map<String, dynamic>? query,
Decoder<T>? decoder,
});
Future<Response<T>> patch<T>(
String url,
dynamic body, {
String contentType,
Map<String, String> headers,
Map<String, dynamic> query,
Decoder<T> decoder,
Progress uploadProgress,
String? contentType,
Map<String, String>? headers,
Map<String, dynamic>? query,
Decoder<T>? decoder,
Progress? uploadProgress,
});
Future<GraphQLResponse<T>> query<T>(
String query, {
String url,
Map<String, dynamic> variables,
Map<String, String> headers,
String? url,
Map<String, dynamic>? variables,
Map<String, String>? headers,
});
Future<GraphQLResponse<T>> mutation<T>(
String mutation, {
String url,
Map<String, dynamic> variables,
Map<String, String> headers,
String? url,
Map<String, dynamic>? variables,
Map<String, String>? headers,
});
GetSocket socket(
... ... @@ -103,16 +103,16 @@ class GetConnect extends GetConnectInterface {
bool allowAutoSignedCert;
String userAgent;
String baseUrl;
String? baseUrl;
String defaultContentType = 'application/json; charset=utf-8';
bool followRedirects;
int maxRedirects;
int maxAuthRetries;
Decoder defaultDecoder;
Decoder? defaultDecoder;
Duration timeout;
List<TrustedCertificate> trustedCertificates;
GetHttpClient _httpClient;
List<GetSocket> _sockets;
List<TrustedCertificate>? trustedCertificates;
GetHttpClient? _httpClient;
List<GetSocket>? _sockets;
@override
List<GetSocket> get sockets => _sockets ??= <GetSocket>[];
... ... @@ -132,10 +132,10 @@ class GetConnect extends GetConnectInterface {
@override
Future<Response<T>> get<T>(
String url, {
Map<String, String> headers,
String contentType,
Map<String, dynamic> query,
Decoder<T> decoder,
Map<String, String>? headers,
String? contentType,
Map<String, dynamic>? query,
Decoder<T>? decoder,
}) {
_checkIfDisposed();
return httpClient.get<T>(
... ... @@ -149,13 +149,13 @@ class GetConnect extends GetConnectInterface {
@override
Future<Response<T>> post<T>(
String url,
String? url,
dynamic body, {
String contentType,
Map<String, String> headers,
Map<String, dynamic> query,
Decoder<T> decoder,
Progress uploadProgress,
String? contentType,
Map<String, String>? headers,
Map<String, dynamic>? query,
Decoder<T>? decoder,
Progress? uploadProgress,
}) {
_checkIfDisposed();
return httpClient.post<T>(
... ... @@ -173,11 +173,11 @@ class GetConnect extends GetConnectInterface {
Future<Response<T>> put<T>(
String url,
dynamic body, {
String contentType,
Map<String, String> headers,
Map<String, dynamic> query,
Decoder<T> decoder,
Progress uploadProgress,
String? contentType,
Map<String, String>? headers,
Map<String, dynamic>? query,
Decoder<T>? decoder,
Progress? uploadProgress,
}) {
_checkIfDisposed();
return httpClient.put<T>(
... ... @@ -195,11 +195,11 @@ class GetConnect extends GetConnectInterface {
Future<Response<T>> patch<T>(
String url,
dynamic body, {
String contentType,
Map<String, String> headers,
Map<String, dynamic> query,
Decoder<T> decoder,
Progress uploadProgress,
String? contentType,
Map<String, String>? headers,
Map<String, dynamic>? query,
Decoder<T>? decoder,
Progress? uploadProgress,
}) {
_checkIfDisposed();
return httpClient.patch<T>(
... ... @@ -218,11 +218,11 @@ class GetConnect extends GetConnectInterface {
String url,
String method, {
dynamic body,
String contentType,
Map<String, String> headers,
Map<String, dynamic> query,
Decoder<T> decoder,
Progress uploadProgress,
String? contentType,
Map<String, String>? headers,
Map<String, dynamic>? query,
Decoder<T>? decoder,
Progress? uploadProgress,
}) {
_checkIfDisposed();
return httpClient.request<T>(
... ... @@ -240,10 +240,10 @@ class GetConnect extends GetConnectInterface {
@override
Future<Response<T>> delete<T>(
String url, {
Map<String, String> headers,
String contentType,
Map<String, dynamic> query,
Decoder<T> decoder,
Map<String, String>? headers,
String? contentType,
Map<String, dynamic>? query,
Decoder<T>? decoder,
}) {
_checkIfDisposed();
return httpClient.delete(
... ... @@ -262,14 +262,14 @@ class GetConnect extends GetConnectInterface {
}) {
_checkIfDisposed(isHttp: false);
final _socket = GetSocket(_concatUrl(url), ping: ping);
final _socket = GetSocket(_concatUrl(url)!, ping: ping);
sockets.add(_socket);
return _socket;
}
String _concatUrl(String url) {
String? _concatUrl(String? url) {
if (url == null) return baseUrl;
return baseUrl == null ? url : baseUrl + url;
return baseUrl == null ? url : baseUrl! + url;
}
/// query allow made GraphQL raw querys
... ... @@ -294,9 +294,9 @@ class GetConnect extends GetConnectInterface {
@override
Future<GraphQLResponse<T>> query<T>(
String query, {
String url,
Map<String, dynamic> variables,
Map<String, String> headers,
String? url,
Map<String, dynamic>? variables,
Map<String, String>? headers,
}) async {
try {
final res = await post(
... ... @@ -316,7 +316,7 @@ class GetConnect extends GetConnectInterface {
))
.toList());
}
return GraphQLResponse<T>(body: res.body['data'] as T);
return GraphQLResponse<T>(body: res.body['data'] as T?);
} on Exception catch (_) {
return GraphQLResponse<T>(graphQLErrors: [
GraphQLError(
... ... @@ -330,9 +330,9 @@ class GetConnect extends GetConnectInterface {
@override
Future<GraphQLResponse<T>> mutation<T>(
String mutation, {
String url,
Map<String, dynamic> variables,
Map<String, String> headers,
String? url,
Map<String, dynamic>? variables,
Map<String, String>? headers,
}) async {
try {
final res = await post(
... ... @@ -352,7 +352,7 @@ class GetConnect extends GetConnectInterface {
))
.toList());
}
return GraphQLResponse<T>(body: res.body['data'] as T);
return GraphQLResponse<T>(body: res.body['data'] as T?);
} on Exception catch (_) {
return GraphQLResponse<T>(graphQLErrors: [
GraphQLError(
... ...
class GetHttpException implements Exception {
final String message;
final Uri uri;
final Uri? uri;
GetHttpException(this.message, [this.uri]);
... ... @@ -11,8 +11,8 @@ class GetHttpException implements Exception {
class GraphQLError {
GraphQLError({this.code, this.message});
final String message;
final String code;
final String? message;
final String? code;
@override
String toString() => 'GETCONNECT ERROR:\n\tcode:$code\n\tmessage:$message';
... ...
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import '../src/certificates/certificates.dart';
import '../src/exceptions/exceptions.dart';
... ... @@ -20,7 +19,7 @@ typedef Progress = Function(double percent);
class GetHttpClient {
String userAgent;
String baseUrl;
String? baseUrl;
String defaultContentType = 'application/json; charset=utf-8';
... ... @@ -28,7 +27,7 @@ class GetHttpClient {
int maxRedirects;
int maxAuthRetries;
Decoder defaultDecoder;
Decoder? defaultDecoder;
Duration timeout;
... ... @@ -46,7 +45,7 @@ class GetHttpClient {
this.maxAuthRetries = 1,
bool allowAutoSignedCert = false,
this.baseUrl,
List<TrustedCertificate> trustedCertificates,
List<TrustedCertificate>? trustedCertificates,
}) : _httpClient = HttpRequestImpl(
allowAutoSignedCert: allowAutoSignedCert,
trustedCertificates: trustedCertificates,
... ... @@ -73,11 +72,11 @@ class GetHttpClient {
_modifier.removeResponseModifier<T>(interceptor);
}
Uri _createUri(String url, Map<String, dynamic> query) {
Uri _createUri(String? url, Map<String, dynamic>? query) {
if (baseUrl != null) {
url = baseUrl + url;
url = baseUrl! + url!;
}
final uri = Uri.parse(url);
final uri = Uri.parse(url!);
if (query != null) {
return uri.replace(queryParameters: query);
}
... ... @@ -85,16 +84,16 @@ class GetHttpClient {
}
Future<Request<T>> _requestWithBody<T>(
String url,
String contentType,
String? url,
String? contentType,
dynamic body,
String method,
Map<String, dynamic> query,
Decoder<T> decoder,
Progress uploadProgress,
Map<String, dynamic>? query,
Decoder<T>? decoder,
Progress? uploadProgress,
) async {
List<int> bodyBytes;
BodyBytesStream bodyStream;
List<int>? bodyBytes;
Stream<List<int>>? bodyStream;
final headers = <String, String>{};
headers['user-agent'] = userAgent;
... ... @@ -146,9 +145,9 @@ class GetHttpClient {
);
}
BodyBytesStream _trackProgress(
Stream<List<int>> _trackProgress(
List<int> bodyBytes,
Progress uploadProgress,
Progress? uploadProgress,
) {
var total = 0;
var length = bodyBytes.length;
... ... @@ -164,12 +163,12 @@ class GetHttpClient {
sink.add(data);
}),
);
return BodyBytesStream(byteStream);
return byteStream;
}
void _setSimpleHeaders(
Map<String, String> headers,
String contentType,
String? contentType,
) {
headers['content-type'] = contentType ?? defaultContentType;
headers['user-agent'] = userAgent;
... ... @@ -179,7 +178,7 @@ class GetHttpClient {
HandlerExecute<T> handler, {
bool authenticate = false,
int requestNumber = 1,
Map<String, String> headers,
Map<String, String>? headers,
}) async {
try {
var request = await handler();
... ... @@ -188,7 +187,7 @@ class GetHttpClient {
request.headers[key] = value;
});
if (authenticate) await _modifier.authenticator(request);
if (authenticate) await _modifier.authenticator!(request);
await _modifier.modifyRequest(request);
var response = await _httpClient.send<T>(request);
... ... @@ -238,9 +237,9 @@ class GetHttpClient {
Future<Request<T>> _get<T>(
String url,
String contentType,
Map<String, dynamic> query,
Decoder<T> decoder,
String? contentType,
Map<String, dynamic>? query,
Decoder<T>? decoder,
) {
final headers = <String, String>{};
_setSimpleHeaders(headers, contentType);
... ... @@ -250,19 +249,19 @@ class GetHttpClient {
method: 'get',
url: uri,
headers: headers,
decoder: decoder ?? (defaultDecoder as Decoder<T>),
decoder: decoder ?? (defaultDecoder as Decoder<T>?),
contentLength: 0,
));
}
Future<Request<T>> _request<T>(
String url,
String? url,
String method, {
String contentType,
@required dynamic body,
@required Map<String, dynamic> query,
Decoder<T> decoder,
@required Progress uploadProgress,
String? contentType,
required dynamic body,
required Map<String, dynamic>? query,
Decoder<T>? decoder,
required Progress? uploadProgress,
}) {
return _requestWithBody<T>(
url,
... ... @@ -270,16 +269,16 @@ class GetHttpClient {
body,
method,
query,
decoder ?? (defaultDecoder as Decoder<T>),
decoder ?? (defaultDecoder as Decoder<T>?),
uploadProgress,
);
}
Request<T> _delete<T>(
String url,
String contentType,
Map<String, dynamic> query,
Decoder<T> decoder,
String? contentType,
Map<String, dynamic>? query,
Decoder<T>? decoder,
) {
final headers = <String, String>{};
_setSimpleHeaders(headers, contentType);
... ... @@ -289,18 +288,18 @@ class GetHttpClient {
method: 'delete',
url: uri,
headers: headers,
decoder: decoder ?? (defaultDecoder as Decoder<T>),
decoder: decoder ?? (defaultDecoder as Decoder<T>?),
);
}
Future<Response<T>> patch<T>(
String url, {
dynamic body,
String contentType,
Map<String, String> headers,
Map<String, dynamic> query,
Decoder<T> decoder,
Progress uploadProgress,
String? contentType,
Map<String, String>? headers,
Map<String, dynamic>? query,
Decoder<T>? decoder,
Progress? uploadProgress,
// List<MultipartFile> files,
}) async {
try {
... ... @@ -328,13 +327,13 @@ class GetHttpClient {
}
Future<Response<T>> post<T>(
String url, {
String? url, {
dynamic body,
String contentType,
Map<String, String> headers,
Map<String, dynamic> query,
Decoder<T> decoder,
Progress uploadProgress,
String? contentType,
Map<String, String>? headers,
Map<String, dynamic>? query,
Decoder<T>? decoder,
Progress? uploadProgress,
// List<MultipartFile> files,
}) async {
try {
... ... @@ -365,11 +364,11 @@ class GetHttpClient {
String url,
String method, {
dynamic body,
String contentType,
Map<String, String> headers,
Map<String, dynamic> query,
Decoder<T> decoder,
Progress uploadProgress,
String? contentType,
Map<String, String>? headers,
Map<String, dynamic>? query,
Decoder<T>? decoder,
Progress? uploadProgress,
}) async {
try {
var response = await _performRequest<T>(
... ... @@ -398,11 +397,11 @@ class GetHttpClient {
Future<Response<T>> put<T>(
String url, {
dynamic body,
String contentType,
Map<String, String> headers,
Map<String, dynamic> query,
Decoder<T> decoder,
Progress uploadProgress,
String? contentType,
Map<String, String>? headers,
Map<String, dynamic>? query,
Decoder<T>? decoder,
Progress? uploadProgress,
}) async {
try {
var response = await _performRequest<T>(
... ... @@ -430,10 +429,10 @@ class GetHttpClient {
Future<Response<T>> get<T>(
String url, {
Map<String, String> headers,
String contentType,
Map<String, dynamic> query,
Decoder<T> decoder,
Map<String, String>? headers,
String? contentType,
Map<String, dynamic>? query,
Decoder<T>? decoder,
}) async {
try {
var response = await _performRequest<T>(
... ... @@ -514,10 +513,10 @@ class GetHttpClient {
Future<Response<T>> delete<T>(
String url, {
Map<String, String> headers,
String contentType,
Map<String, dynamic> query,
Decoder<T> decoder,
Map<String, String>? headers,
String? contentType,
Map<String, dynamic>? query,
Decoder<T>? decoder,
}) async {
try {
var response = await _performRequest<T>(
... ...
import 'dart:async';
import 'dart:html' as html;
import 'dart:typed_data';
import '../../certificates/certificates.dart';
import '../../exceptions/exceptions.dart';
... ... @@ -13,7 +12,7 @@ import '../utils/body_decoder.dart';
class HttpRequestImpl implements HttpRequestBase {
HttpRequestImpl({
bool allowAutoSignedCert = true,
List<TrustedCertificate> trustedCertificates,
List<TrustedCertificate>? trustedCertificates,
});
/// The currently active XHRs.
... ... @@ -41,16 +40,16 @@ class HttpRequestImpl implements HttpRequestBase {
var completer = Completer<Response<T>>();
xhr.onLoad.first.then((_) {
var blob = xhr.response as html.Blob ?? html.Blob([]);
var blob = xhr.response as html.Blob? ?? html.Blob([]);
var reader = html.FileReader();
reader.onLoad.first.then((_) async {
var bodyBytes = BodyBytesStream.fromBytes(reader.result as Uint8List);
var bodyBytes = BodyBytesStream.fromBytes(reader.result as List<int>);
final stringBody =
await bodyBytesToString(bodyBytes, xhr.responseHeaders);
String contentType;
String? contentType;
if (xhr.responseHeaders.containsKey('content-type')) {
contentType = xhr.responseHeaders['content-type'];
... ...
... ... @@ -10,24 +10,24 @@ import '../utils/body_decoder.dart';
/// A `dart:io` implementation of `HttpRequestBase`.
class HttpRequestImpl extends HttpRequestBase {
io.HttpClient _httpClient;
io.SecurityContext _securityContext;
io.HttpClient? _httpClient;
io.SecurityContext? _securityContext;
HttpRequestImpl({
bool allowAutoSignedCert = true,
List<TrustedCertificate> trustedCertificates,
List<TrustedCertificate>? trustedCertificates,
}) {
_httpClient = io.HttpClient();
if (trustedCertificates != null) {
_securityContext = io.SecurityContext();
for (final trustedCertificate in trustedCertificates) {
_securityContext
_securityContext!
.setTrustedCertificatesBytes(List.from(trustedCertificate.bytes));
}
}
_httpClient = io.HttpClient(context: _securityContext);
_httpClient.badCertificateCallback = (_, __, ___) => allowAutoSignedCert;
_httpClient!.badCertificateCallback = (_, __, ___) => allowAutoSignedCert;
}
@override
... ... @@ -36,7 +36,7 @@ class HttpRequestImpl extends HttpRequestBase {
//var stream = BodyBytesStream.fromBytes(requestBody ?? const []);
try {
var ioRequest = (await _httpClient.openUrl(request.method, request.url))
var ioRequest = (await _httpClient!.openUrl(request.method, request.url))
..followRedirects = request.followRedirects
..persistentConnection = request.persistentConnection
..maxRedirects = request.maxRedirects
... ... @@ -50,7 +50,7 @@ class HttpRequestImpl extends HttpRequestBase {
headers[key] = values.join(',');
});
final bodyBytes = BodyBytesStream(response);
final bodyBytes = (response);
final stringBody = await bodyBytesToString(bodyBytes, headers);
final body = bodyDecoded<T>(
... ... @@ -77,7 +77,7 @@ class HttpRequestImpl extends HttpRequestBase {
@override
void close() {
if (_httpClient != null) {
_httpClient.close(force: true);
_httpClient!.close(force: true);
_httpClient = null;
}
}
... ...
... ... @@ -16,14 +16,14 @@ class MockClient extends HttpRequestBase {
@override
Future<Response<T>> send<T>(Request<T> request) async {
var requestBody = await request.bodyBytes.toBytes();
var bodyBytes = BodyBytesStream.fromBytes(requestBody ?? const []);
var bodyBytes = BodyBytesStream.fromBytes(requestBody);
var response = await _handler(request);
final stringBody = await bodyBytesToString(bodyBytes, response.headers);
final stringBody = await bodyBytesToString(bodyBytes, response.headers!);
var mimeType = response.headers.containsKey('content-type')
? response.headers['content-type']
var mimeType = response.headers!.containsKey('content-type')
? response.headers!['content-type']
: '';
final body = bodyDecoded<T>(
... ...
... ... @@ -6,7 +6,7 @@ import '../interface/request_base.dart';
class HttpRequestImpl extends HttpRequestBase {
HttpRequestImpl({
bool allowAutoSignedCert = true,
List<TrustedCertificate> trustedCertificates,
List<TrustedCertificate>? trustedCertificates,
});
@override
void close() {}
... ...
... ... @@ -4,8 +4,8 @@ import '../../../../../get_core/get_core.dart';
import '../../request/request.dart';
T bodyDecoded<T>(Request<T> request, String stringBody, String mimeType) {
T body;
T? bodyDecoded<T>(Request<T> request, String stringBody, String? mimeType) {
T? body;
var bodyToDecode;
if (mimeType != null && mimeType.contains('application/json')) {
... ... @@ -23,9 +23,9 @@ T bodyDecoded<T>(Request<T> request, String stringBody, String mimeType) {
if (stringBody == '') {
body = null;
} else if (request.decoder == null) {
body = bodyToDecode as T;
body = bodyToDecode as T?;
} else {
body = request.decoder(bodyToDecode);
body = request.decoder!(bodyToDecode);
}
} on Exception catch (_) {
body = stringBody as T;
... ...
... ... @@ -3,17 +3,17 @@ import 'dart:async';
import '../request/request.dart';
import '../response/response.dart';
typedef RequestModifier<T> = FutureOr<Request<T>> Function(Request<T> request);
typedef RequestModifier<T> = FutureOr<Request<T>> Function(Request<T?> request);
typedef ResponseModifier<T> = FutureOr Function(
Request<T> request, Response<T> response);
Request<T?> request, Response<T?> response);
typedef HandlerExecute<T> = Future<Request<T>> Function();
class GetModifier<T> {
final _requestModifiers = <RequestModifier>[];
final _responseModifiers = <ResponseModifier>[];
RequestModifier authenticator;
RequestModifier? authenticator;
void addRequestModifier<T>(RequestModifier<T> interceptor) {
_requestModifiers.add(interceptor as RequestModifier);
... ...
... ... @@ -57,9 +57,7 @@ class FormData {
String _fileHeader(MapEntry<String, MultipartFile> file) {
var header =
'content-disposition: form-data; name="${browserEncode(file.key)}"';
if (file.value.filename != null) {
header = '$header; filename="${browserEncode(file.value.filename)}"';
}
header = '$header; filename="${browserEncode(file.value.filename)}"';
header = '$header\r\n'
'content-type: ${file.value.contentType}';
return '$header\r\n\r\n';
... ... @@ -83,7 +81,7 @@ class FormData {
_maxBoundaryLength +
'\r\n'.length +
utf8.encode(_fileHeader(file)).length +
file.value.length +
file.value.length! +
'\r\n'.length;
}
... ... @@ -109,7 +107,7 @@ class FormData {
for (final file in files) {
yield separator;
yield utf8.encode(_fileHeader(file));
yield* file.value.stream;
yield* file.value.stream!;
yield line;
}
yield close;
... ...
import 'package:flutter/foundation.dart';
import '../http/stub/file_decoder_stub.dart'
if (dart.library.html) '../http/html/file_decoder_html.dart'
if (dart.library.io) '../http/io/file_decoder_io.dart';
... ... @@ -9,7 +7,7 @@ import '../request/request.dart';
class MultipartFile {
MultipartFile(
dynamic data, {
@required this.filename,
required this.filename,
this.contentType = 'application/octet-stream',
}) : _bytes = fileToBytes(data) {
_length = _bytes.length;
... ... @@ -21,13 +19,13 @@ class MultipartFile {
final String contentType;
/// This stream will emit the file content of File.
BodyBytesStream _stream;
Stream<List<int>>? _stream;
int _length;
int? _length;
BodyBytesStream get stream => _stream;
Stream<List<int>>? get stream => _stream;
int get length => _length;
int? get length => _length;
final String filename;
}
... ...
... ... @@ -2,8 +2,6 @@ import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import '../http.dart';
import '../multipart/form_data.dart';
... ... @@ -14,16 +12,16 @@ class Request<T> {
/// The [Uri] from request
final Uri url;
final Decoder<T> decoder;
final Decoder<T>? decoder;
/// The Http Method from this [Request]
/// ex: `GET`,`POST`,`PUT`,`DELETE`
final String method;
final int contentLength;
final int? contentLength;
/// The BodyBytesStream of body from this [Request]
final BodyBytesStream bodyBytes;
final Stream<List<int>> bodyBytes;
/// When true, the client will follow redirects to resolves this [Request]
final bool followRedirects;
... ... @@ -33,45 +31,41 @@ class Request<T> {
final bool persistentConnection;
final FormData files;
final FormData? files;
const Request._({
@required this.method,
@required this.bodyBytes,
@required this.url,
@required this.headers,
@required this.contentLength,
@required this.followRedirects,
@required this.maxRedirects,
@required this.files,
@required this.persistentConnection,
@required this.decoder,
required this.method,
required this.bodyBytes,
required this.url,
required this.headers,
required this.contentLength,
required this.followRedirects,
required this.maxRedirects,
required this.files,
required this.persistentConnection,
required this.decoder,
});
factory Request({
@required Uri url,
@required String method,
@required Map<String, String> headers,
BodyBytesStream bodyBytes,
required Uri url,
required String method,
required Map<String, String> headers,
Stream<List<int>>? bodyBytes,
bool followRedirects = true,
int maxRedirects = 4,
int contentLength,
FormData files,
int? contentLength,
FormData? files,
bool persistentConnection = true,
Decoder<T> decoder,
Decoder<T>? decoder,
}) {
assert(url != null);
assert(method != null);
assert(followRedirects != null);
if (followRedirects) {
assert(maxRedirects != null);
assert(maxRedirects > 0);
}
return Request._(
url: url,
method: method,
bodyBytes: bodyBytes ??= BodyBytesStream.fromBytes(const []),
headers: Map.from(headers ??= <String, String>{}),
headers: Map.from(headers),
followRedirects: followRedirects,
maxRedirects: maxRedirects,
contentLength: contentLength,
... ... @@ -82,11 +76,9 @@ class Request<T> {
}
}
class BodyBytesStream extends StreamView<List<int>> {
BodyBytesStream(Stream<List<int>> stream) : super(stream);
factory BodyBytesStream.fromBytes(List<int> bytes) =>
BodyBytesStream(Stream.fromIterable([bytes]));
extension BodyBytesStream on Stream<List<int>> {
static Stream<List<int>> fromBytes(List<int> bytes) =>
Stream.fromIterable([bytes]);
Future<Uint8List> toBytes() {
var completer = Completer<Uint8List>();
... ... @@ -95,7 +87,7 @@ class BodyBytesStream extends StreamView<List<int>> {
Uint8List.fromList(bytes),
),
);
listen(sink.add,
listen((val) => sink.add(val),
onError: completer.completeError,
onDone: sink.close,
cancelOnError: true);
... ...
... ... @@ -5,8 +5,8 @@ import '../request/request.dart';
import '../status/http_status.dart';
class GraphQLResponse<T> extends Response<T> {
final List<GraphQLError> graphQLErrors;
GraphQLResponse({T body, this.graphQLErrors}) : super(body: body);
final List<GraphQLError>? graphQLErrors;
GraphQLResponse({T? body, this.graphQLErrors}) : super(body: body);
}
class Response<T> {
... ... @@ -21,16 +21,16 @@ class Response<T> {
});
/// The Http [Request] linked with this [Response].
final Request request;
final Request? request;
/// The response headers.
final Map<String, String> headers;
final Map<String, String>? headers;
/// The status code returned by the server.
final int statusCode;
final int? statusCode;
/// Human-readable context for [statusCode].
final String statusText;
final String? statusText;
/// [HttpStatus] from [Response]. `status.connectionError` is true
/// when statusCode is null. `status.isUnauthorized` is true when
... ... @@ -49,19 +49,19 @@ class Response<T> {
bool get unauthorized => status.isUnauthorized;
/// The response body as a Stream of Bytes.
final BodyBytesStream bodyBytes;
final Stream<List<int>>? bodyBytes;
/// The response body as a Stream of Bytes.
final String bodyString;
final String? bodyString;
/// The decoded body of this [Response]. You can access the
/// body parameters as Map
/// Ex: body['title'];
final T body;
final T? body;
}
Future<String> bodyBytesToString(
BodyBytesStream bodyBytes, Map<String, String> headers) {
Stream<List<int>> bodyBytes, Map<String, String> headers) {
return bodyBytes.bytesToString(_encodingForHeaders(headers));
}
... ... @@ -70,13 +70,13 @@ Future<String> bodyBytesToString(
/// Defaults to [latin1] if the headers don't specify a charset or if that
/// charset is unknown.
Encoding _encodingForHeaders(Map<String, String> headers) =>
_encodingForCharset(_contentTypeForHeaders(headers).parameters['charset']);
_encodingForCharset(_contentTypeForHeaders(headers).parameters!['charset']);
/// Returns the [Encoding] that corresponds to [charset].
///
/// Returns [fallback] if [charset] is null or if no [Encoding] was found that
/// corresponds to [charset].
Encoding _encodingForCharset(String charset, [Encoding fallback = latin1]) {
Encoding _encodingForCharset(String? charset, [Encoding fallback = latin1]) {
if (charset == null) return fallback;
return Encoding.getByName(charset) ?? fallback;
}
... ... @@ -92,10 +92,10 @@ HeaderValue _contentTypeForHeaders(Map<String, String> headers) {
class HeaderValue {
String _value;
Map<String, String> _parameters;
Map<String, String> _unmodifiableParameters;
Map<String, String?>? _parameters;
Map<String, String?>? _unmodifiableParameters;
HeaderValue([this._value = '', Map<String, String> parameters]) {
HeaderValue([this._value = '', Map<String, String>? parameters]) {
if (parameters != null) {
_parameters = HashMap<String, String>.from(parameters);
}
... ... @@ -103,7 +103,7 @@ class HeaderValue {
static HeaderValue parse(String value,
{String parameterSeparator = ';',
String valueSeparator,
String? valueSeparator,
bool preserveBackslash = false}) {
var result = HeaderValue();
result._parse(value, parameterSeparator, valueSeparator, preserveBackslash);
... ... @@ -116,9 +116,9 @@ class HeaderValue {
_parameters ??= HashMap<String, String>();
}
Map<String, String> get parameters {
Map<String, String?>? get parameters {
_ensureParameters();
_unmodifiableParameters ??= UnmodifiableMapView(_parameters);
_unmodifiableParameters ??= UnmodifiableMapView(_parameters!);
return _unmodifiableParameters;
}
... ... @@ -126,15 +126,15 @@ class HeaderValue {
String toString() {
var stringBuffer = StringBuffer();
stringBuffer.write(_value);
if (parameters != null && parameters.isNotEmpty) {
_parameters.forEach((name, value) {
if (parameters != null && parameters!.isNotEmpty) {
_parameters!.forEach((name, value) {
stringBuffer..write('; ')..write(name)..write('=')..write(value);
});
}
return stringBuffer.toString();
}
void _parse(String value, String parameterSeparator, String valueSeparator,
void _parse(String value, String parameterSeparator, String? valueSeparator,
bool preserveBackslash) {
var index = 0;
... ... @@ -173,7 +173,7 @@ class HeaderValue {
}
void parseParameters() {
var parameters = HashMap<String, String>();
var parameters = HashMap<String, String?>();
_parameters = UnmodifiableMapView(parameters);
String parseParameterName() {
... ... @@ -191,7 +191,7 @@ class HeaderValue {
return value.substring(start, index).toLowerCase();
}
String parseParameterValue() {
String? parseParameterValue() {
if (!done() && value[index] == '\"') {
var stringBuffer = StringBuffer();
index++;
... ...
class HttpStatus {
HttpStatus(this.code);
final int code;
final int? code;
static const int continue_ = 100;
static const int switchingProtocols = 101;
... ... @@ -83,7 +83,7 @@ class HttpStatus {
between(internalServerError, networkConnectTimeoutError);
bool between(int begin, int end) {
return !connectionError && code >= begin && code <= end;
return !connectionError && code! >= begin && code! <= end;
}
bool get isOk => between(200, 299);
... ...
import 'dart:async';
import 'dart:convert';
import '../request/request.dart';
bool isTokenChar(int byte) {
return byte > 31 && byte < 128 && !SEPARATOR_MAP[byte];
... ... @@ -52,10 +50,9 @@ String validateField(String field) {
return field.toLowerCase();
}
BodyBytesStream toBodyBytesStream(Stream<List<int>> stream) {
if (stream is BodyBytesStream) return stream;
return BodyBytesStream(stream);
}
// Stream<List<int>> toBodyBytesStream(Stream<List<int>> stream) {
// return (stream);
// }
final _asciiOnly = RegExp(r'^[\x00-\x7F]+$');
... ...
import 'dart:convert';
class Close {
final String message;
final int reason;
final String? message;
final int? reason;
Close(this.message, this.reason);
... ... @@ -19,31 +19,31 @@ typedef CloseSocket = void Function(Close);
typedef MessageSocket = void Function(dynamic val);
class SocketNotifier {
var _onMessages = <MessageSocket>[];
var _onEvents = <String, MessageSocket>{};
var _onCloses = <CloseSocket>[];
var _onErrors = <CloseSocket>[];
List<void Function(dynamic)>? _onMessages = <MessageSocket>[];
Map<String, void Function(dynamic)>? _onEvents = <String, MessageSocket>{};
List<void Function(Close)>? _onCloses = <CloseSocket>[];
List<void Function(Close)>? _onErrors = <CloseSocket>[];
OpenSocket open;
late OpenSocket open;
void addMessages(MessageSocket socket) {
_onMessages.add((socket));
_onMessages!.add((socket));
}
void addEvents(String event, MessageSocket socket) {
_onEvents[event] = socket;
_onEvents![event] = socket;
}
void addCloses(CloseSocket socket) {
_onCloses.add(socket);
_onCloses!.add(socket);
}
void addErrors(CloseSocket socket) {
_onErrors.add((socket));
_onErrors!.add((socket));
}
void notifyData(dynamic data) {
for (var item in _onMessages) {
for (var item in _onMessages!) {
item(data);
}
if (data is String) {
... ... @@ -52,14 +52,14 @@ class SocketNotifier {
}
void notifyClose(Close err) {
for (var item in _onCloses) {
for (var item in _onCloses!) {
item(err);
}
}
void notifyError(Close err) {
// rooms.removeWhere((key, value) => value.contains(_ws));
for (var item in _onErrors) {
for (var item in _onErrors!) {
item(err);
}
}
... ... @@ -69,8 +69,8 @@ class SocketNotifier {
var msg = jsonDecode(message);
final event = msg['type'];
final data = msg['data'];
if (_onEvents.containsKey(event)) {
_onEvents[event](data);
if (_onEvents!.containsKey(event)) {
_onEvents![event]!(data);
}
} on Exception catch (_) {
return;
... ...
... ... @@ -15,8 +15,8 @@ enum ConnectionStatus {
class BaseWebSocket {
String url;
WebSocket socket;
SocketNotifier socketNotifier = SocketNotifier();
WebSocket? socket;
SocketNotifier? socketNotifier = SocketNotifier();
Duration ping;
bool isDisposed = false;
bool allowSelfSigned;
... ... @@ -30,39 +30,39 @@ class BaseWebSocket {
? url.replaceAll('https:', 'wss:')
: url.replaceAll('http:', 'ws:');
}
ConnectionStatus connectionStatus;
Timer _t;
ConnectionStatus? connectionStatus;
Timer? _t;
void connect() {
try {
connectionStatus = ConnectionStatus.connecting;
socket = WebSocket(url);
socket.onOpen.listen((e) {
socket!.onOpen.listen((e) {
socketNotifier?.open();
_t = Timer?.periodic(ping, (t) {
socket.send('');
socket!.send('');
});
connectionStatus = ConnectionStatus.connected;
});
socket.onMessage.listen((event) {
socketNotifier.notifyData(event.data);
socket!.onMessage.listen((event) {
socketNotifier!.notifyData(event.data);
});
socket.onClose.listen((e) {
socket!.onClose.listen((e) {
_t?.cancel();
connectionStatus = ConnectionStatus.closed;
socketNotifier.notifyClose(Close(e.reason, e.code));
socketNotifier!.notifyClose(Close(e.reason, e.code));
});
socket.onError.listen((event) {
socket!.onError.listen((event) {
_t?.cancel();
socketNotifier.notifyError(Close(event.toString(), 0));
socketNotifier!.notifyError(Close(event.toString(), 0));
connectionStatus = ConnectionStatus.closed;
});
} on Exception catch (e) {
_t?.cancel();
socketNotifier.notifyError(Close(e.toString(), 500));
socketNotifier!.notifyError(Close(e.toString(), 500));
connectionStatus = ConnectionStatus.closed;
// close(500, e.toString());
}
... ... @@ -70,35 +70,35 @@ class BaseWebSocket {
// ignore: use_setters_to_change_properties
void onOpen(OpenSocket fn) {
socketNotifier.open = fn;
socketNotifier!.open = fn;
}
void onClose(CloseSocket fn) {
socketNotifier.addCloses(fn);
socketNotifier!.addCloses(fn);
}
void onError(CloseSocket fn) {
socketNotifier.addErrors(fn);
socketNotifier!.addErrors(fn);
}
void onMessage(MessageSocket fn) {
socketNotifier.addMessages(fn);
socketNotifier!.addMessages(fn);
}
void on(String event, MessageSocket message) {
socketNotifier.addEvents(event, message);
socketNotifier!.addEvents(event, message);
}
void close([int status, String reason]) {
if (socket != null) socket.close(status, reason);
void close([int? status, String? reason]) {
socket?.close(status, reason);
}
void send(dynamic data) {
if (connectionStatus == ConnectionStatus.closed) {
connect();
}
if (socket != null && socket.readyState == WebSocket.OPEN) {
socket.send(data);
if (socket != null && socket!.readyState == WebSocket.OPEN) {
socket!.send(data);
} else {
Get.log('WebSocket not connected, message $data not sent');
}
... ... @@ -109,7 +109,7 @@ class BaseWebSocket {
}
void dispose() {
socketNotifier.dispose();
socketNotifier!.dispose();
socketNotifier = null;
isDisposed = true;
}
... ...
... ... @@ -15,8 +15,8 @@ enum ConnectionStatus {
class BaseWebSocket {
String url;
WebSocket socket;
SocketNotifier socketNotifier = SocketNotifier();
WebSocket? socket;
SocketNotifier? socketNotifier = SocketNotifier();
bool isDisposed = false;
BaseWebSocket(
this.url, {
... ... @@ -26,7 +26,7 @@ class BaseWebSocket {
Duration ping;
bool allowSelfSigned;
ConnectionStatus connectionStatus;
ConnectionStatus? connectionStatus;
Future connect() async {
if (isDisposed) {
... ... @@ -38,52 +38,51 @@ class BaseWebSocket {
? await _connectForSelfSignedCert(url)
: await WebSocket.connect(url);
socket.pingInterval = ping;
socket!.pingInterval = ping;
socketNotifier?.open();
connectionStatus = ConnectionStatus.connected;
socket.listen((data) {
socketNotifier.notifyData(data);
socket!.listen((data) {
socketNotifier!.notifyData(data);
}, onError: (err) {
socketNotifier.notifyError(Close(err.toString(), 1005));
socketNotifier!.notifyError(Close(err.toString(), 1005));
}, onDone: () {
connectionStatus = ConnectionStatus.closed;
socketNotifier
.notifyClose(Close('Connection Closed', socket.closeCode));
socketNotifier!
.notifyClose(Close('Connection Closed', socket!.closeCode));
}, cancelOnError: true);
return;
} on SocketException catch (e) {
connectionStatus = ConnectionStatus.closed;
socketNotifier.notifyError(Close(e.osError.message, e.osError.errorCode));
socketNotifier!
.notifyError(Close(e.osError!.message, e.osError!.errorCode));
return;
}
}
// ignore: use_setters_to_change_properties
void onOpen(OpenSocket fn) {
socketNotifier.open = fn;
socketNotifier!.open = fn;
}
void onClose(CloseSocket fn) {
socketNotifier.addCloses(fn);
socketNotifier!.addCloses(fn);
}
void onError(CloseSocket fn) {
socketNotifier.addErrors(fn);
socketNotifier!.addErrors(fn);
}
void onMessage(MessageSocket fn) {
socketNotifier.addMessages(fn);
socketNotifier!.addMessages(fn);
}
void on(String event, MessageSocket message) {
socketNotifier.addEvents(event, message);
socketNotifier!.addEvents(event, message);
}
void close([int status, String reason]) {
if (socket != null) {
socket.close(status, reason);
}
void close([int? status, String? reason]) {
socket?.close(status, reason);
}
void send(dynamic data) async {
... ... @@ -92,12 +91,12 @@ class BaseWebSocket {
}
if (socket != null) {
socket.add(data);
socket!.add(data);
}
}
void dispose() {
socketNotifier.dispose();
socketNotifier!.dispose();
socketNotifier = null;
isDisposed = true;
}
... ...
... ... @@ -36,7 +36,7 @@ class BaseWebSocket {
throw 'To use sockets you need dart:io or dart:html';
}
void close([int status, String reason]) {
void close([int? status, String? reason]) {
throw 'To use sockets you need dart:io or dart:html';
}
... ...
... ... @@ -5,7 +5,7 @@ import 'smart_management.dart';
/// class through extensions
abstract class GetInterface {
SmartManagement smartManagement = SmartManagement.full;
String reference;
String? reference;
bool isLogEnable = true;
LogWriterCallback log = defaultLogWriterCallback;
}
... ...
... ... @@ -42,7 +42,7 @@ class BindingsBuilder<T> extends Bindings {
/// ),
/// ```
factory BindingsBuilder.put(InstanceBuilderCallback<T> builder,
{String tag, bool permanent = false}) {
{String? tag, bool permanent = false}) {
return BindingsBuilder(
() => GetInstance().put<T>(builder(), tag: tag, permanent: permanent));
}
... ...
... ... @@ -28,7 +28,7 @@ extension Inst on GetInterface {
/// Subsequent calls to [Get.lazyPut()] with the same parameters
/// (<[S]> and optionally [tag] will **not** override the original).
void lazyPut<S>(InstanceBuilderCallback<S> builder,
{String tag, bool fenix = false}) {
{String? tag, bool fenix = false}) {
GetInstance().lazyPut<S>(builder, tag: tag, fenix: fenix);
}
... ... @@ -40,7 +40,7 @@ extension Inst on GetInterface {
/// Awaits for the resolution of the Future from [builder()] parameter and
/// stores the Instance returned.
Future<S> putAsync<S>(AsyncInstanceBuilderCallback<S> builder,
{String tag, bool permanent = false}) async =>
{String? tag, bool permanent = false}) async =>
GetInstance().putAsync<S>(builder, tag: tag, permanent: permanent);
/// Creates a new Class Instance [S] from the builder callback[S].
... ... @@ -61,13 +61,13 @@ extension Inst on GetInterface {
/// Repl b = find();
/// print(a==b); (false)```
void create<S>(InstanceBuilderCallback<S> builder,
{String tag, bool permanent = true}) =>
{String? tag, bool permanent = true}) =>
GetInstance().create<S>(builder, tag: tag, permanent: permanent);
/// Finds a Instance of the required Class <[S]>(or [tag])
/// In the case of using [Get.create()], it will generate an Instance
/// each time you call [Get.find()].
S find<S>({String tag}) => GetInstance().find<S>(tag: tag);
S find<S>({String? tag}) => GetInstance().find<S>(tag: tag);
/// Injects an [Instance<S>] in memory.
///
... ... @@ -84,9 +84,9 @@ extension Inst on GetInterface {
/// and [Get.delete()]
/// - [builder] If defined, the [dependency] must be returned from here
S put<S>(S dependency,
{String tag,
{String? tag,
bool permanent = false,
InstanceBuilderCallback<S> builder}) =>
InstanceBuilderCallback<S>? builder}) =>
GetInstance().put<S>(dependency, tag: tag, permanent: permanent);
/// Clears all registered instances (and/or tags).
... ... @@ -104,15 +104,21 @@ extension Inst on GetInterface {
///
/// - [tag] Optional "tag" used to register the Instance
/// - [force] Will delete an Instance even if marked as [permanent].
Future<bool> delete<S>({String tag, bool force = false}) async =>
Future<bool> delete<S>({String? tag, bool force = false}) async =>
GetInstance().delete<S>(tag: tag, force: force);
void reloadAll({bool force = false}) => GetInstance().reloadAll(force: force);
void reload<S>({String? tag, String? key, bool force = false}) =>
GetInstance().reload<S>(tag: tag, key: key, force: force);
/// Checks if a Class Instance<[S]> (or [tag]) is registered in memory.
/// - [tag] optional, if you use a [tag] to register the Instance.
bool isRegistered<S>({String tag}) => GetInstance().isRegistered<S>(tag: tag);
bool isRegistered<S>({String? tag}) =>
GetInstance().isRegistered<S>(tag: tag);
/// Checks if an Instance<[S]> (or [tag]) returned from a factory builder
/// [Get.lazyPut()], is registered in memory.
/// - [tag] optional, if you use a [tag] to register the Instance.
bool isPrepared<S>({String tag}) => GetInstance().isPrepared<S>(tag: tag);
bool isPrepared<S>({String? tag}) => GetInstance().isPrepared<S>(tag: tag);
}
... ...
import 'dart:async';
import 'dart:collection';
import 'package:flutter/foundation.dart';
import '../../get_core/get_core.dart';
import 'lifecycle.dart';
class InstanceInfo {
final bool isPermanent;
final bool isSingleton;
bool get isCreate => !isSingleton;
final bool? isPermanent;
final bool? isSingleton;
bool get isCreate => !isSingleton!;
final bool isRegistered;
final bool isPrepared;
final bool isInit;
final bool? isInit;
const InstanceInfo({
@required this.isPermanent,
@required this.isSingleton,
@required this.isRegistered,
@required this.isPrepared,
@required this.isInit,
required this.isPermanent,
required this.isSingleton,
required this.isRegistered,
required this.isPrepared,
required this.isInit,
});
}
... ... @@ -28,7 +26,7 @@ class GetInstance {
const GetInstance._();
static GetInstance _getInstance;
static GetInstance? _getInstance;
T call<T>() => find<T>();
... ... @@ -42,13 +40,13 @@ class GetInstance {
/// Holds a reference to [Get.reference] when the Instance was
/// created to manage the memory.
static final Map<String, String> _routesKey = {};
static final Map<String, String?> _routesKey = {};
/// Stores the onClose() references of instances created with [Get.create()]
/// using the [Get.reference].
/// Experimental feature to keep the lifecycle and memory management with
/// non-singleton instances.
static final Map<String, HashSet<Function>> _routesByCreate = {};
static final Map<String?, HashSet<Function>> _routesByCreate = {};
void printInstanceStack() {
Get.log(_routesKey.toString());
... ... @@ -56,7 +54,7 @@ class GetInstance {
void injector<S>(
InjectorBuilderCallback<S> fn, {
String tag,
String? tag,
bool fenix = false,
// bool permanent = false,
}) {
... ... @@ -73,7 +71,7 @@ class GetInstance {
/// stores the Instance returned.
Future<S> putAsync<S>(
AsyncInstanceBuilderCallback<S> builder, {
String tag,
String? tag,
bool permanent = false,
}) async {
return put<S>(await builder(), tag: tag, permanent: permanent);
... ... @@ -91,9 +89,9 @@ class GetInstance {
/// [Get.smartManagement] rules.
S put<S>(
S dependency, {
String tag,
String? tag,
bool permanent = false,
@deprecated InstanceBuilderCallback<S> builder,
@deprecated InstanceBuilderCallback<S>? builder,
}) {
_insert(
isSingleton: true,
... ... @@ -127,8 +125,8 @@ class GetInstance {
/// (<[S]> and optionally [tag] will **not** override the original).
void lazyPut<S>(
InstanceBuilderCallback<S> builder, {
String tag,
bool fenix,
String? tag,
bool? fenix,
bool permanent = false,
}) {
_insert(
... ... @@ -158,7 +156,7 @@ class GetInstance {
/// print(a==b); (false)```
void create<S>(
InstanceBuilderCallback<S> builder, {
String tag,
String? tag,
bool permanent = true,
}) {
_insert(
... ... @@ -171,13 +169,12 @@ class GetInstance {
/// Injects the Instance [S] builder into the [_singleton] HashMap.
void _insert<S>({
bool isSingleton,
String name,
bool? isSingleton,
String? name,
bool permanent = false,
InstanceBuilderCallback<S> builder,
required InstanceBuilderCallback<S> builder,
bool fenix = false,
}) {
assert(builder != null);
final key = _getKey(S, name);
_singl.putIfAbsent(
key,
... ... @@ -206,14 +203,12 @@ class GetInstance {
/// Removes [Get.create()] instances registered in [routeName].
if (_routesByCreate.containsKey(routeName)) {
for (final onClose in _routesByCreate[routeName]) {
for (final onClose in _routesByCreate[routeName]!) {
// assure the [DisposableInterface] instance holding a reference
// to [onClose()] wasn't disposed.
if (onClose != null) {
onClose();
}
onClose();
}
_routesByCreate[routeName].clear();
_routesByCreate[routeName]!.clear();
_routesByCreate.remove(routeName);
}
... ... @@ -222,7 +217,7 @@ class GetInstance {
}
for (final element in keysToRemove) {
_routesKey?.remove(element);
_routesKey.remove(element);
}
keysToRemove.clear();
}
... ... @@ -236,14 +231,14 @@ class GetInstance {
/// (not for Singletons access).
/// Returns the instance if not initialized, required for Get.create() to
/// work properly.
S _initDependencies<S>({String name}) {
S? _initDependencies<S>({String? name}) {
final key = _getKey(S, name);
final isInit = _singl[key].isInit;
S i;
final isInit = _singl[key]!.isInit;
S? i;
if (!isInit) {
i = _startController<S>(tag: name);
if (_singl[key].isSingleton) {
_singl[key].isInit = true;
if (_singl[key]!.isSingleton!) {
_singl[key]!.isInit = true;
if (Get.smartManagement != SmartManagement.onlyBuilder) {
_registerRouteInstance<S>(tag: name);
}
... ... @@ -254,11 +249,11 @@ class GetInstance {
/// Links a Class instance [S] (or [tag]) to the current route.
/// Requires usage of [GetMaterialApp].
void _registerRouteInstance<S>({String tag}) {
void _registerRouteInstance<S>({String? tag}) {
_routesKey.putIfAbsent(_getKey(S, tag), () => Get.reference);
}
InstanceInfo getInstanceInfo<S>({String tag}) {
InstanceInfo getInstanceInfo<S>({String? tag}) {
final build = _getDependency<S>(tag: tag);
return InstanceInfo(
... ... @@ -270,7 +265,7 @@ class GetInstance {
);
}
_InstanceBuilderFactory _getDependency<S>({String tag, String key}) {
_InstanceBuilderFactory? _getDependency<S>({String? tag, String? key}) {
final newKey = key ?? _getKey(S, tag);
if (!_singl.containsKey(newKey)) {
... ... @@ -282,31 +277,30 @@ class GetInstance {
}
/// Initializes the controller
S _startController<S>({String tag}) {
S _startController<S>({String? tag}) {
final key = _getKey(S, tag);
final i = _singl[key].getDependency() as S;
final i = _singl[key]!.getDependency() as S;
if (i is GetLifeCycleBase) {
if (i.onStart != null) {
i.onStart();
if (tag == null) {
Get.log('Instance "$S" has been initialized');
} else {
Get.log('Instance "$S" with tag "$tag" has been initialized');
}
i.onStart();
if (tag == null) {
Get.log('Instance "$S" has been initialized');
} else {
Get.log('Instance "$S" with tag "$tag" has been initialized');
}
if (!_singl[key].isSingleton && i.onDelete != null) {
if (!_singl[key]!.isSingleton!) {
_routesByCreate[Get.reference] ??= HashSet<Function>();
_routesByCreate[Get.reference].add(i.onDelete);
// _routesByCreate[Get.reference]!.add(i.onDelete as Function);
_routesByCreate[Get.reference]!.add(i.onDelete);
}
}
return i;
}
S putOrFind<S>(InstanceBuilderCallback<S> dep, {String tag}) {
S putOrFind<S>(InstanceBuilderCallback<S> dep, {String? tag}) {
final key = _getKey(S, tag);
if (_singl.containsKey(key)) {
return _singl[key].getDependency() as S;
return _singl[key]!.getDependency() as S;
} else {
return GetInstance().put(dep(), tag: tag);
}
... ... @@ -317,7 +311,7 @@ class GetInstance {
/// it will create an instance each time you call [find].
/// If the registered type <[S]> (or [tag]) is a Controller,
/// it will initialize it's lifecycle.
S find<S>({String tag}) {
S find<S>({String? tag}) {
final key = _getKey(S, tag);
if (isRegistered<S>(tag: tag)) {
if (_singl[key] == null) {
... ... @@ -332,7 +326,7 @@ class GetInstance {
/// `initDependencies`, so we have to return the instance from there
/// to make it compatible with `Get.create()`.
final i = _initDependencies<S>(name: tag);
return i ?? _singl[key].getDependency() as S;
return i ?? _singl[key]!.getDependency() as S;
} else {
// ignore: lines_longer_than_80_chars
throw '"$S" not found. You need to call "Get.put($S())" or "Get.lazyPut(()=>$S())"';
... ... @@ -341,7 +335,7 @@ class GetInstance {
/// Generates the key based on [type] (and optionally a [name])
/// to register an Instance Builder in the hashmap.
String _getKey(Type type, String name) {
String _getKey(Type type, String? name) {
return name == null ? type.toString() : type.toString() + name;
}
... ... @@ -374,7 +368,7 @@ class GetInstance {
/// - [key] For internal usage, is the processed key used to register
/// the Instance. **don't use** it unless you know what you are doing.
/// - [force] Will delete an Instance even if marked as [permanent].
bool delete<S>({String tag, String key, bool force = false}) {
bool delete<S>({String? tag, String? key, bool force = false}) {
final newKey = key ?? _getKey(S, tag);
if (!_singl.containsKey(newKey)) {
... ... @@ -382,7 +376,7 @@ class GetInstance {
return false;
}
final builder = _singl[newKey];
final builder = _singl[newKey]!;
if (builder.permanent && !force) {
Get.log(
... ... @@ -398,7 +392,7 @@ class GetInstance {
return false;
}
if (i is GetLifeCycleBase && i.onDelete != null) {
if (i is GetLifeCycleBase) {
i.onDelete();
Get.log('"$newKey" onDelete() called');
}
... ... @@ -430,7 +424,7 @@ class GetInstance {
});
}
void reload<S>({String tag, String key, bool force = false}) {
void reload<S>({String? tag, String? key, bool force = false}) {
final newKey = key ?? _getKey(S, tag);
final builder = _getDependency<S>(tag: tag, key: newKey);
... ... @@ -451,12 +445,12 @@ class GetInstance {
/// Check if a Class Instance<[S]> (or [tag]) is registered in memory.
/// - [tag] is optional, if you used a [tag] to register the Instance.
bool isRegistered<S>({String tag}) => _singl.containsKey(_getKey(S, tag));
bool isRegistered<S>({String? tag}) => _singl.containsKey(_getKey(S, tag));
/// Checks if a lazy factory callback ([Get.lazyPut()] that returns an
/// Instance<[S]> is registered in memory.
/// - [tag] is optional, if you used a [tag] to register the lazy Instance.
bool isPrepared<S>({String tag}) {
bool isPrepared<S>({String? tag}) {
final newKey = _getKey(S, tag);
final builder = _getDependency<S>(tag: tag, key: newKey);
... ... @@ -481,14 +475,14 @@ typedef AsyncInstanceBuilderCallback<S> = Future<S> Function();
class _InstanceBuilderFactory<S> {
/// Marks the Builder as a single instance.
/// For reusing [dependency] instead of [builderFunc]
bool isSingleton;
bool? isSingleton;
/// When fenix mode is avaliable, when a new instance is need
/// Instance manager will recreate a new instance of S
bool fenix;
/// Stores the actual object instance when [isSingleton]=true.
S dependency;
S? dependency;
/// Generates (and regenerates) the instance when [isSingleton]=false.
/// Usually used by factory methods
... ... @@ -500,7 +494,7 @@ class _InstanceBuilderFactory<S> {
bool isInit = false;
String tag;
String? tag;
_InstanceBuilderFactory(
this.isSingleton,
... ... @@ -521,12 +515,12 @@ class _InstanceBuilderFactory<S> {
/// Gets the actual instance by it's [builderFunc] or the persisted instance.
S getDependency() {
if (isSingleton) {
if (isSingleton!) {
if (dependency == null) {
_showInitLog();
dependency = builderFunc();
}
return dependency;
return dependency!;
} else {
return builderFunc();
}
... ...
... ... @@ -5,11 +5,11 @@ import '../../get_core/get_core.dart';
/// methods.
/// Used in [DisposableInterface] to avoid the danger of overriding onStart.
class _InternalFinalCallback<T> {
ValueUpdater<T> _callback;
ValueUpdater<T>? _callback;
_InternalFinalCallback({ValueUpdater<T> callback}) : _callback = callback;
_InternalFinalCallback({ValueUpdater<T>? callback}) : _callback = callback;
T call() => _callback.call();
T call() => _callback!.call();
}
/// The [GetLifeCycle]
... ...
... ... @@ -14,24 +14,21 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> {
this.modalBarrierColor,
this.isDismissible = true,
this.enableDrag = true,
@required this.isScrollControlled,
RouteSettings settings,
required this.isScrollControlled,
RouteSettings? settings,
this.enterBottomSheetDuration = const Duration(milliseconds: 250),
this.exitBottomSheetDuration = const Duration(milliseconds: 200),
}) : assert(isScrollControlled != null),
name = "BOTTOMSHEET: ${builder.hashCode}",
assert(isDismissible != null),
assert(enableDrag != null),
}) : name = "BOTTOMSHEET: ${builder.hashCode}",
super(settings: settings);
final bool isPersistent;
final WidgetBuilder builder;
final ThemeData theme;
final bool? isPersistent;
final WidgetBuilder? builder;
final ThemeData? theme;
final bool isScrollControlled;
final Color backgroundColor;
final double elevation;
final ShapeBorder shape;
final Clip clipBehavior;
final Color modalBarrierColor;
final Color? backgroundColor;
final double? elevation;
final ShapeBorder? shape;
final Clip? clipBehavior;
final Color? modalBarrierColor;
final bool isDismissible;
final bool enableDrag;
final String name;
... ... @@ -47,21 +44,21 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> {
bool get barrierDismissible => isDismissible;
@override
final String barrierLabel;
final String? barrierLabel;
@override
Color get barrierColor => modalBarrierColor ?? Colors.black54;
AnimationController _animationController;
AnimationController? _animationController;
@override
AnimationController createAnimationController() {
assert(_animationController == null);
_animationController =
BottomSheet.createAnimationController(navigator.overlay);
_animationController.duration = enterBottomSheetDuration;
_animationController.reverseDuration = exitBottomSheetDuration;
return _animationController;
BottomSheet.createAnimationController(navigator!.overlay!);
_animationController!.duration = enterBottomSheetDuration;
_animationController!.reverseDuration = exitBottomSheetDuration;
return _animationController!;
}
@override
... ... @@ -80,10 +77,10 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> {
child: _GetModalBottomSheet<T>(
route: this,
backgroundColor: backgroundColor ??
sheetTheme?.modalBackgroundColor ??
sheetTheme?.backgroundColor,
sheetTheme.modalBackgroundColor ??
sheetTheme.backgroundColor,
elevation:
elevation ?? sheetTheme?.modalElevation ?? sheetTheme?.elevation,
elevation ?? sheetTheme.modalElevation ?? sheetTheme.elevation,
shape: shape,
clipBehavior: clipBehavior,
isScrollControlled: isScrollControlled,
... ... @@ -91,14 +88,14 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> {
),
),
);
if (theme != null) bottomSheet = Theme(data: theme, child: bottomSheet);
if (theme != null) bottomSheet = Theme(data: theme!, child: bottomSheet);
return bottomSheet;
}
}
class _GetModalBottomSheet<T> extends StatefulWidget {
const _GetModalBottomSheet({
Key key,
Key? key,
this.route,
this.backgroundColor,
this.elevation,
... ... @@ -107,16 +104,14 @@ class _GetModalBottomSheet<T> extends StatefulWidget {
this.isScrollControlled = false,
this.enableDrag = true,
this.isPersistent = false,
}) : assert(isScrollControlled != null),
assert(enableDrag != null),
super(key: key);
}) : super(key: key);
final bool isPersistent;
final GetModalBottomSheetRoute<T> route;
final GetModalBottomSheetRoute<T>? route;
final bool isScrollControlled;
final Color backgroundColor;
final double elevation;
final ShapeBorder shape;
final Clip clipBehavior;
final Color? backgroundColor;
final double? elevation;
final ShapeBorder? shape;
final Clip? clipBehavior;
final bool enableDrag;
@override
... ... @@ -142,13 +137,13 @@ class _GetModalBottomSheetState<T> extends State<_GetModalBottomSheet<T>> {
final routeLabel = _getRouteLabel(localizations);
return AnimatedBuilder(
animation: widget.route.animation,
animation: widget.route!.animation!,
builder: (context, child) {
// Disable the initial animation when accessible navigation is on so
// that the semantics are added to the tree at the correct time.
final animationValue = mediaQuery.accessibleNavigation
? 1.0
: widget.route.animation.value;
: widget.route!.animation!.value;
return Semantics(
scopesRoute: true,
namesRoute: true,
... ... @@ -160,13 +155,13 @@ class _GetModalBottomSheetState<T> extends State<_GetModalBottomSheet<T>> {
animationValue, widget.isScrollControlled),
child: widget.isPersistent == false
? BottomSheet(
animationController: widget.route._animationController,
animationController: widget.route!._animationController,
onClosing: () {
if (widget.route.isCurrent) {
if (widget.route!.isCurrent) {
Navigator.pop(context);
}
},
builder: widget.route.builder,
builder: widget.route!.builder!,
backgroundColor: widget.backgroundColor,
elevation: widget.elevation,
shape: widget.shape,
... ... @@ -176,13 +171,13 @@ class _GetModalBottomSheetState<T> extends State<_GetModalBottomSheet<T>> {
: Scaffold(
bottomSheet: BottomSheet(
animationController:
widget.route._animationController,
widget.route!._animationController,
onClosing: () {
// if (widget.route.isCurrent) {
// Navigator.pop(context);
// }
},
builder: widget.route.builder,
builder: widget.route!.builder!,
backgroundColor: widget.backgroundColor,
elevation: widget.elevation,
shape: widget.shape,
... ... @@ -199,7 +194,7 @@ class _GetModalBottomSheetState<T> extends State<_GetModalBottomSheet<T>> {
class _GetPerModalBottomSheet<T> extends StatefulWidget {
const _GetPerModalBottomSheet({
Key key,
Key? key,
this.route,
this.isPersistent,
this.backgroundColor,
... ... @@ -208,16 +203,14 @@ class _GetPerModalBottomSheet<T> extends StatefulWidget {
this.clipBehavior,
this.isScrollControlled = false,
this.enableDrag = true,
}) : assert(isScrollControlled != null),
assert(enableDrag != null),
super(key: key);
final bool isPersistent;
final GetModalBottomSheetRoute<T> route;
}) : super(key: key);
final bool? isPersistent;
final GetModalBottomSheetRoute<T>? route;
final bool isScrollControlled;
final Color backgroundColor;
final double elevation;
final ShapeBorder shape;
final Clip clipBehavior;
final Color? backgroundColor;
final double? elevation;
final ShapeBorder? shape;
final Clip? clipBehavior;
final bool enableDrag;
@override
... ... @@ -247,13 +240,13 @@ class _GetPerModalBottomSheetState<T>
final routeLabel = _getRouteLabel(localizations);
return AnimatedBuilder(
animation: widget.route.animation,
animation: widget.route!.animation!,
builder: (context, child) {
// Disable the initial animation when accessible navigation is on so
// that the semantics are added to the tree at the correct time.
final animationValue = mediaQuery.accessibleNavigation
? 1.0
: widget.route.animation.value;
: widget.route!.animation!.value;
return Semantics(
scopesRoute: true,
namesRoute: true,
... ... @@ -265,13 +258,13 @@ class _GetPerModalBottomSheetState<T>
animationValue, widget.isScrollControlled),
child: widget.isPersistent == false
? BottomSheet(
animationController: widget.route._animationController,
animationController: widget.route!._animationController,
onClosing: () {
if (widget.route.isCurrent) {
if (widget.route!.isCurrent) {
Navigator.pop(context);
}
},
builder: widget.route.builder,
builder: widget.route!.builder!,
backgroundColor: widget.backgroundColor,
elevation: widget.elevation,
shape: widget.shape,
... ... @@ -281,13 +274,13 @@ class _GetPerModalBottomSheetState<T>
: Scaffold(
bottomSheet: BottomSheet(
animationController:
widget.route._animationController,
widget.route!._animationController,
onClosing: () {
// if (widget.route.isCurrent) {
// Navigator.pop(context);
// }
},
builder: widget.route.builder,
builder: widget.route!.builder!,
backgroundColor: widget.backgroundColor,
elevation: widget.elevation,
shape: widget.shape,
... ...
... ... @@ -4,15 +4,14 @@ import '../../../get_instance/src/get_instance.dart';
class GetDialogRoute<T> extends PopupRoute<T> {
GetDialogRoute({
@required RoutePageBuilder pageBuilder,
required RoutePageBuilder pageBuilder,
bool barrierDismissible = true,
String barrierLabel,
String? barrierLabel,
Color barrierColor = const Color(0x80000000),
Duration transitionDuration = const Duration(milliseconds: 200),
RouteTransitionsBuilder transitionBuilder,
RouteSettings settings,
}) : assert(barrierDismissible != null),
widget = pageBuilder,
RouteTransitionsBuilder? transitionBuilder,
RouteSettings? settings,
}) : widget = pageBuilder,
name = "DIALOG: ${pageBuilder.hashCode}",
_barrierDismissible = barrierDismissible,
_barrierLabel = barrierLabel,
... ... @@ -32,15 +31,15 @@ class GetDialogRoute<T> extends PopupRoute<T> {
@override
void dispose() {
if (Get.smartManagement != SmartManagement.onlyBuilder) {
WidgetsBinding.instance.addPostFrameCallback(
WidgetsBinding.instance!.addPostFrameCallback(
(_) => GetInstance().removeDependencyByRoute(name));
}
super.dispose();
}
@override
String get barrierLabel => _barrierLabel;
final String _barrierLabel;
String? get barrierLabel => _barrierLabel;
final String? _barrierLabel;
@override
Color get barrierColor => _barrierColor;
... ... @@ -50,7 +49,7 @@ class GetDialogRoute<T> extends PopupRoute<T> {
Duration get transitionDuration => _transitionDuration;
final Duration _transitionDuration;
final RouteTransitionsBuilder _transitionBuilder;
final RouteTransitionsBuilder? _transitionBuilder;
@override
Widget buildPage(BuildContext context, Animation<double> animation,
... ... @@ -73,6 +72,6 @@ class GetDialogRoute<T> extends PopupRoute<T> {
),
child: child);
} // Some default transition
return _transitionBuilder(context, animation, secondaryAnimation, child);
return _transitionBuilder!(context, animation, secondaryAnimation, child);
}
}
... ...
... ... @@ -14,42 +14,42 @@ import 'routes/transitions_type.dart';
extension ExtensionSnackbar on GetInterface {
void rawSnackbar({
String title,
String message,
Widget titleText,
Widget messageText,
Widget icon,
String? title,
String? message,
Widget? titleText,
Widget? messageText,
Widget? icon,
bool instantInit = true,
bool shouldIconPulse = true,
double maxWidth,
double? maxWidth,
EdgeInsets margin = const EdgeInsets.all(0.0),
EdgeInsets padding = const EdgeInsets.all(16),
double borderRadius = 0.0,
Color borderColor,
Color? borderColor,
double borderWidth = 1.0,
Color backgroundColor = const Color(0xFF303030),
Color leftBarIndicatorColor,
List<BoxShadow> boxShadows,
Gradient backgroundGradient,
Widget mainButton,
OnTap onTap,
Color? leftBarIndicatorColor,
List<BoxShadow>? boxShadows,
Gradient? backgroundGradient,
Widget? mainButton,
OnTap? onTap,
Duration duration = const Duration(seconds: 3),
bool isDismissible = true,
SnackDismissDirection dismissDirection = SnackDismissDirection.VERTICAL,
bool showProgressIndicator = false,
AnimationController progressIndicatorController,
Color progressIndicatorBackgroundColor,
Animation<Color> progressIndicatorValueColor,
AnimationController? progressIndicatorController,
Color? progressIndicatorBackgroundColor,
Animation<Color>? progressIndicatorValueColor,
SnackPosition snackPosition = SnackPosition.BOTTOM,
SnackStyle snackStyle = SnackStyle.FLOATING,
Curve forwardAnimationCurve = Curves.easeOutCirc,
Curve reverseAnimationCurve = Curves.easeOutCirc,
Duration animationDuration = const Duration(seconds: 1),
SnackbarStatusCallback snackbarStatus,
double barBlur = 0.0,
SnackbarStatusCallback? snackbarStatus,
double? barBlur = 0.0,
double overlayBlur = 0.0,
Color overlayColor,
Form userInputForm,
Color? overlayColor,
Form? userInputForm,
}) async {
final getBar = GetBar(
snackbarStatus: snackbarStatus,
... ... @@ -76,7 +76,7 @@ extension ExtensionSnackbar on GetInterface {
onTap: onTap,
isDismissible: isDismissible,
dismissDirection: dismissDirection,
showProgressIndicator: showProgressIndicator ?? false,
showProgressIndicator: showProgressIndicator,
progressIndicatorController: progressIndicatorController,
progressIndicatorBackgroundColor: progressIndicatorBackgroundColor,
progressIndicatorValueColor: progressIndicatorValueColor,
... ... @@ -92,70 +92,68 @@ extension ExtensionSnackbar on GetInterface {
if (instantInit) {
getBar.show();
} else {
SchedulerBinding.instance.addPostFrameCallback((_) {
SchedulerBinding.instance!.addPostFrameCallback((_) {
getBar.show();
});
}
}
Future<T> showSnackbar<T>(GetBar snackbar) {
return key?.currentState?.push(SnackRoute<T>(snack: snackbar));
Future<T?>? showSnackbar<T>(GetBar snackbar) {
return key.currentState?.push(SnackRoute<T>(snack: snackbar));
}
void snackbar<T>(
String title,
String message, {
Color colorText,
Duration duration,
Color? colorText,
Duration? duration,
/// with instantInit = false you can put snackbar on initState
bool instantInit = true,
SnackPosition snackPosition,
Widget titleText,
Widget messageText,
Widget icon,
bool shouldIconPulse,
double maxWidth,
EdgeInsets margin,
EdgeInsets padding,
double borderRadius,
Color borderColor,
double borderWidth,
Color backgroundColor,
Color leftBarIndicatorColor,
List<BoxShadow> boxShadows,
Gradient backgroundGradient,
TextButton mainButton,
OnTap onTap,
bool isDismissible,
bool showProgressIndicator,
SnackDismissDirection dismissDirection,
AnimationController progressIndicatorController,
Color progressIndicatorBackgroundColor,
Animation<Color> progressIndicatorValueColor,
SnackStyle snackStyle,
Curve forwardAnimationCurve,
Curve reverseAnimationCurve,
Duration animationDuration,
double barBlur,
double overlayBlur,
SnackbarStatusCallback snackbarStatus,
Color overlayColor,
Form userInputForm,
SnackPosition? snackPosition,
Widget? titleText,
Widget? messageText,
Widget? icon,
bool? shouldIconPulse,
double? maxWidth,
EdgeInsets? margin,
EdgeInsets? padding,
double? borderRadius,
Color? borderColor,
double? borderWidth,
Color? backgroundColor,
Color? leftBarIndicatorColor,
List<BoxShadow>? boxShadows,
Gradient? backgroundGradient,
TextButton? mainButton,
OnTap? onTap,
bool? isDismissible,
bool? showProgressIndicator,
SnackDismissDirection? dismissDirection,
AnimationController? progressIndicatorController,
Color? progressIndicatorBackgroundColor,
Animation<Color>? progressIndicatorValueColor,
SnackStyle? snackStyle,
Curve? forwardAnimationCurve,
Curve? reverseAnimationCurve,
Duration? animationDuration,
double? barBlur,
double? overlayBlur,
SnackbarStatusCallback? snackbarStatus,
Color? overlayColor,
Form? userInputForm,
}) async {
final getBar = GetBar(
snackbarStatus: snackbarStatus,
titleText: (title == null)
? null
: titleText ??
Text(
title,
style: TextStyle(
color: colorText ?? iconColor ?? Colors.black,
fontWeight: FontWeight.w800,
fontSize: 16,
),
),
titleText: titleText ??
Text(
title,
style: TextStyle(
color: colorText ?? iconColor ?? Colors.black,
fontWeight: FontWeight.w800,
fontSize: 16,
),
),
messageText: messageText ??
Text(
message,
... ... @@ -200,7 +198,7 @@ extension ExtensionSnackbar on GetInterface {
showSnackbar<T>(getBar);
} else {
routing.isSnackbar = true;
SchedulerBinding.instance.addPostFrameCallback((_) {
SchedulerBinding.instance!.addPostFrameCallback((_) {
showSnackbar<T>(getBar);
});
}
... ... @@ -212,33 +210,27 @@ extension ExtensionDialog on GetInterface {
/// You can pass a [transitionDuration] and/or [transitionCurve],
/// overriding the defaults when the dialog shows up and closes.
/// When the dialog closes, uses those animations in reverse.
Future<T> dialog<T>(
Future<T?> dialog<T>(
Widget widget, {
bool barrierDismissible = true,
Color barrierColor,
Color? barrierColor,
bool useSafeArea = true,
bool useRootNavigator = true,
Object arguments,
Duration transitionDuration,
Curve transitionCurve,
String name,
RouteSettings routeSettings,
Object? arguments,
Duration? transitionDuration,
Curve? transitionCurve,
String? name,
RouteSettings? routeSettings,
}) {
assert(widget != null);
assert(barrierDismissible != null);
assert(useSafeArea != null);
assert(useRootNavigator != null);
assert(debugCheckHasMaterialLocalizations(context));
assert(debugCheckHasMaterialLocalizations(context!));
// final theme = Theme.of(context, shadowThemeOnly: true);
final theme = Theme.of(context);
final theme = Theme.of(context!);
return generalDialog<T>(
pageBuilder: (buildContext, animation, secondaryAnimation) {
final pageChild = widget;
Widget dialog = Builder(builder: (context) {
return theme != null
? Theme(data: theme, child: pageChild)
: pageChild;
return Theme(data: theme, child: pageChild);
});
if (useSafeArea) {
dialog = SafeArea(child: dialog);
... ... @@ -246,7 +238,7 @@ extension ExtensionDialog on GetInterface {
return dialog;
},
barrierDismissible: barrierDismissible,
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
barrierLabel: MaterialLocalizations.of(context!).modalBarrierDismissLabel,
barrierColor: barrierColor ?? Colors.black54,
transitionDuration: transitionDuration ?? defaultDialogTransitionDuration,
transitionBuilder: (context, animation, secondaryAnimation, child) {
... ... @@ -265,20 +257,18 @@ extension ExtensionDialog on GetInterface {
}
/// Api from showGeneralDialog with no context
Future<T> generalDialog<T>({
@required RoutePageBuilder pageBuilder,
Future<T?> generalDialog<T>({
required RoutePageBuilder pageBuilder,
bool barrierDismissible = false,
String barrierLabel,
String? barrierLabel,
Color barrierColor = const Color(0x80000000),
Duration transitionDuration = const Duration(milliseconds: 200),
RouteTransitionsBuilder transitionBuilder,
RouteTransitionsBuilder? transitionBuilder,
bool useRootNavigator = true,
RouteSettings routeSettings,
RouteSettings? routeSettings,
}) {
assert(pageBuilder != null);
assert(useRootNavigator != null);
assert(!barrierDismissible || barrierLabel != null);
return Navigator.of(overlayContext, rootNavigator: useRootNavigator)
return Navigator.of(overlayContext!, rootNavigator: useRootNavigator)
.push<T>(GetDialogRoute<T>(
pageBuilder: pageBuilder,
barrierDismissible: barrierDismissible,
... ... @@ -291,32 +281,32 @@ extension ExtensionDialog on GetInterface {
}
/// Custom UI Dialog.
Future<T> defaultDialog<T>({
Future<T?> defaultDialog<T>({
String title = "Alert",
TextStyle titleStyle,
Widget content,
VoidCallback onConfirm,
VoidCallback onCancel,
VoidCallback onCustom,
Color cancelTextColor,
Color confirmTextColor,
String textConfirm,
String textCancel,
String textCustom,
Widget confirm,
Widget cancel,
Widget custom,
Color backgroundColor,
TextStyle? titleStyle,
Widget? content,
VoidCallback? onConfirm,
VoidCallback? onCancel,
VoidCallback? onCustom,
Color? cancelTextColor,
Color? confirmTextColor,
String? textConfirm,
String? textCancel,
String? textCustom,
Widget? confirm,
Widget? cancel,
Widget? custom,
Color? backgroundColor,
bool barrierDismissible = true,
Color buttonColor,
Color? buttonColor,
String middleText = "Dialog made in 3 lines of code",
TextStyle middleTextStyle,
TextStyle? middleTextStyle,
double radius = 20.0,
// ThemeData themeData,
List<Widget> actions,
List<Widget>? actions,
// onWillPop Scope
WillPopCallback onWillPop,
WillPopCallback? onWillPop,
}) {
var leanCancel = onCancel != null || textCancel != null;
var leanConfirm = onConfirm != null || textConfirm != null;
... ... @@ -355,7 +345,6 @@ extension ExtensionDialog on GetInterface {
actions.add(TextButton(
style: TextButton.styleFrom(
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
//color: buttonColor ?? theme.accentColor,
backgroundColor: buttonColor ?? theme.accentColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(100)),
... ... @@ -374,6 +363,7 @@ extension ExtensionDialog on GetInterface {
Widget baseAlertDialog = AlertDialog(
titlePadding: EdgeInsets.all(8),
contentPadding: EdgeInsets.all(8),
backgroundColor: backgroundColor ?? theme.dialogBackgroundColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(radius))),
... ... @@ -383,7 +373,7 @@ extension ExtensionDialog on GetInterface {
mainAxisSize: MainAxisSize.min,
children: [
content ??
Text(middleText ?? "",
Text(middleText,
textAlign: TextAlign.center, style: middleTextStyle),
SizedBox(height: 16),
ButtonTheme(
... ... @@ -420,39 +410,34 @@ extension ExtensionDialog on GetInterface {
}
extension ExtensionBottomSheet on GetInterface {
Future<T> bottomSheet<T>(
Future<T?> bottomSheet<T>(
Widget bottomsheet, {
Color backgroundColor,
double elevation,
Color? backgroundColor,
double? elevation,
bool persistent = true,
ShapeBorder shape,
Clip clipBehavior,
Color barrierColor,
bool ignoreSafeArea,
ShapeBorder? shape,
Clip? clipBehavior,
Color? barrierColor,
bool? ignoreSafeArea,
bool isScrollControlled = false,
bool useRootNavigator = false,
bool isDismissible = true,
bool enableDrag = true,
RouteSettings settings,
Duration enterBottomSheetDuration,
Duration exitBottomSheetDuration,
RouteSettings? settings,
Duration? enterBottomSheetDuration,
Duration? exitBottomSheetDuration,
}) {
assert(bottomsheet != null);
assert(persistent != null);
assert(isScrollControlled != null);
assert(useRootNavigator != null);
assert(isDismissible != null);
assert(enableDrag != null);
return Navigator.of(overlayContext, rootNavigator: useRootNavigator)
return Navigator.of(overlayContext!, rootNavigator: useRootNavigator)
.push(GetModalBottomSheetRoute<T>(
builder: (_) => bottomsheet,
isPersistent: persistent,
// theme: Theme.of(key.currentContext, shadowThemeOnly: true),
theme: Theme.of(key.currentContext),
theme: Theme.of(key.currentContext!),
isScrollControlled: isScrollControlled,
barrierLabel:
MaterialLocalizations.of(key.currentContext).modalBarrierDismissLabel,
barrierLabel: MaterialLocalizations.of(key.currentContext!)
.modalBarrierDismissLabel,
backgroundColor: backgroundColor ?? Colors.transparent,
elevation: elevation,
shape: shape,
... ... @@ -491,24 +476,24 @@ extension GetNavigation on GetInterface {
///
/// By default, GetX will prevent you from push a route that you already in,
/// if you want to push anyway, set [preventDuplicates] to false
Future<T> to<T>(
Future<T?>? to<T>(
dynamic page, {
bool opaque,
Transition transition,
Curve curve,
Duration duration,
int id,
bool? opaque,
Transition? transition,
Curve? curve,
Duration? duration,
int? id,
bool fullscreenDialog = false,
dynamic arguments,
Bindings binding,
Bindings? binding,
bool preventDuplicates = true,
bool popGesture,
bool? popGesture,
}) {
var routeName = "/${page.runtimeType.toString()}";
if (preventDuplicates && routeName == currentRoute) {
return null;
}
return global(id)?.currentState?.push<T>(
return global(id).currentState?.push<T>(
GetPageRoute<T>(
opaque: opaque ?? true,
page: _resolve(page, 'to'),
... ... @@ -536,6 +521,9 @@ extension GetNavigation on GetInterface {
Using a widget function instead of a widget fully guarantees that the widget and its controllers will be removed from memory when they are no longer used.
''');
return () => page;
} else if (page is String) {
throw '''Unexpected String,
use toNamed() instead''';
} else {
throw '''Unexpected format,
you can only use widgets and widget functions here''';
... ... @@ -558,12 +546,12 @@ you can only use widgets and widget functions here''';
/// if you want to push anyway, set [preventDuplicates] to false
///
/// Note: Always put a slash on the route ('/page1'), to avoid unnexpected errors
Future<T> toNamed<T>(
Future<T?>? toNamed<T>(
String page, {
dynamic arguments,
int id,
int? id,
bool preventDuplicates = true,
Map<String, String> parameters,
Map<String, String>? parameters,
}) {
if (preventDuplicates && page == currentRoute) {
return null;
... ... @@ -574,7 +562,7 @@ you can only use widgets and widget functions here''';
page = uri.toString();
}
return global(id)?.currentState?.pushNamed<T>(
return global(id).currentState?.pushNamed<T>(
page,
arguments: arguments,
);
... ... @@ -596,12 +584,12 @@ you can only use widgets and widget functions here''';
/// if you want to push anyway, set [preventDuplicates] to false
///
/// Note: Always put a slash on the route ('/page1'), to avoid unnexpected errors
Future<T> offNamed<T>(
Future<T?>? offNamed<T>(
String page, {
dynamic arguments,
int id,
int? id,
bool preventDuplicates = true,
Map<String, String> parameters,
Map<String, String>? parameters,
}) {
if (preventDuplicates && page == currentRoute) {
return null;
... ... @@ -611,7 +599,7 @@ you can only use widgets and widget functions here''';
final uri = Uri(path: page, queryParameters: parameters);
page = uri.toString();
}
return global(id)?.currentState?.pushReplacementNamed(
return global(id).currentState?.pushReplacementNamed(
page,
arguments: arguments,
);
... ... @@ -630,10 +618,10 @@ you can only use widgets and widget functions here''';
/// or also like this:
/// `Get.until((route) => !Get.isDialogOpen())`, to make sure the
/// dialog is closed
void until(RoutePredicate predicate, {int id}) {
void until(RoutePredicate predicate, {int? id}) {
// if (key.currentState.mounted) // add this if appear problems on future with route navigate
// when widget don't mounted
return global(id)?.currentState?.popUntil(predicate);
return global(id).currentState?.popUntil(predicate);
}
/// **Navigation.pushAndRemoveUntil()** shortcut.<br><br>
... ... @@ -654,10 +642,10 @@ you can only use widgets and widget functions here''';
/// or also like this:
/// `Get.until((route) => !Get.isDialogOpen())`, to make sure the dialog
/// is closed
Future<T> offUntil<T>(Route<T> page, RoutePredicate predicate, {int id}) {
Future<T?>? offUntil<T>(Route<T> page, RoutePredicate predicate, {int? id}) {
// if (key.currentState.mounted) // add this if appear problems on future with route navigate
// when widget don't mounted
return global(id)?.currentState?.pushAndRemoveUntil<T>(page, predicate);
return global(id).currentState?.pushAndRemoveUntil<T>(page, predicate);
}
/// **Navigation.pushNamedAndRemoveUntil()** shortcut.<br><br>
... ... @@ -678,19 +666,19 @@ you can only use widgets and widget functions here''';
/// to make sure the dialog is closed
///
/// Note: Always put a slash on the route name ('/page1'), to avoid unexpected errors
Future<T> offNamedUntil<T>(
Future<T?>? offNamedUntil<T>(
String page,
RoutePredicate predicate, {
int id,
int? id,
dynamic arguments,
Map<String, String> parameters,
Map<String, String>? parameters,
}) {
if (parameters != null) {
final uri = Uri(path: page, queryParameters: parameters);
page = uri.toString();
}
return global(id)?.currentState?.pushNamedAndRemoveUntil<T>(
return global(id).currentState?.pushNamedAndRemoveUntil<T>(
page,
predicate,
arguments: arguments,
... ... @@ -708,18 +696,18 @@ you can only use widgets and widget functions here''';
/// The `offNamed()` pop a page, and goes to the next. The
/// `offAndToNamed()` goes to the next page, and removes the previous one.
/// The route transition animation is different.
Future<T> offAndToNamed<T>(
Future<T?>? offAndToNamed<T>(
String page, {
dynamic arguments,
int id,
int? id,
dynamic result,
Map<String, String> parameters,
Map<String, String>? parameters,
}) {
if (parameters != null) {
final uri = Uri(path: page, queryParameters: parameters);
page = uri.toString();
}
return global(id)?.currentState?.popAndPushNamed(
return global(id).currentState?.popAndPushNamed(
page,
arguments: arguments,
result: result,
... ... @@ -732,8 +720,8 @@ you can only use widgets and widget functions here''';
///
/// [id] is for when you are using nested navigation,
/// as explained in documentation
void removeRoute(Route<dynamic> route, {int id}) {
return global(id)?.currentState?.removeRoute(route);
void removeRoute(Route<dynamic> route, {int? id}) {
return global(id).currentState?.removeRoute(route);
}
/// **Navigation.pushNamedAndRemoveUntil()** shortcut.<br><br>
... ... @@ -756,19 +744,19 @@ you can only use widgets and widget functions here''';
/// as explained in documentation
///
/// Note: Always put a slash on the route ('/page1'), to avoid unexpected errors
Future<T> offAllNamed<T>(
Future<T?>? offAllNamed<T>(
String newRouteName, {
RoutePredicate predicate,
RoutePredicate? predicate,
dynamic arguments,
int id,
Map<String, String> parameters,
int? id,
Map<String, String>? parameters,
}) {
if (parameters != null) {
final uri = Uri(path: newRouteName, queryParameters: parameters);
newRouteName = uri.toString();
}
return global(id)?.currentState?.pushNamedAndRemoveUntil<T>(
return global(id).currentState?.pushNamedAndRemoveUntil<T>(
newRouteName,
predicate ?? (_) => false,
arguments: arguments,
... ... @@ -777,11 +765,11 @@ you can only use widgets and widget functions here''';
/// Returns true if a Snackbar, Dialog or BottomSheet is currently OPEN
bool get isOverlaysOpen =>
(isSnackbarOpen || isDialogOpen || isBottomSheetOpen);
(isSnackbarOpen! || isDialogOpen! || isBottomSheetOpen!);
/// Returns true if there is no Snackbar, Dialog or BottomSheet open
bool get isOverlaysClosed =>
(!isSnackbarOpen && !isDialogOpen && !isBottomSheetOpen);
(!isSnackbarOpen! && !isDialogOpen! && !isBottomSheetOpen!);
/// **Navigation.popUntil()** shortcut.<br><br>
///
... ... @@ -796,10 +784,10 @@ you can only use widgets and widget functions here''';
/// It has the advantage of not needing context, so you can call
/// from your business logic.
void back<T>({
T result,
T? result,
bool closeOverlays = false,
bool canPop = true,
int id,
int? id,
}) {
if (closeOverlays && isOverlaysOpen) {
navigator?.popUntil((route) {
... ... @@ -807,11 +795,11 @@ you can only use widgets and widget functions here''';
});
}
if (canPop) {
if (global(id)?.currentState?.canPop() == true) {
global(id)?.currentState?.pop<T>(result);
if (global(id).currentState?.canPop() == true) {
global(id).currentState?.pop<T>(result);
}
} else {
global(id)?.currentState?.pop<T>(result);
global(id).currentState?.pop<T>(result);
}
}
... ... @@ -821,12 +809,12 @@ you can only use widgets and widget functions here''';
///
/// [id] is for when you are using nested navigation,
/// as explained in documentation
void close(int times, [int id]) {
if ((times == null) || (times < 1)) {
void close(int times, [int? id]) {
if (times < 1) {
times = 1;
}
var count = 0;
var back = global(id)?.currentState?.popUntil((route) => count++ == times);
var back = global(id).currentState?.popUntil((route) => count++ == times);
return back;
}
... ... @@ -856,25 +844,25 @@ you can only use widgets and widget functions here''';
///
/// By default, GetX will prevent you from push a route that you already in,
/// if you want to push anyway, set [preventDuplicates] to false
Future<T> off<T>(
Future<T?>? off<T>(
dynamic page, {
bool opaque = false,
Transition transition,
Curve curve,
bool popGesture,
int id,
Transition? transition,
Curve? curve,
bool? popGesture,
int? id,
dynamic arguments,
Bindings binding,
Bindings? binding,
bool fullscreenDialog = false,
bool preventDuplicates = true,
Duration duration,
Duration? duration,
}) {
var routeName = "/${page.runtimeType.toString()}";
if (preventDuplicates && routeName == currentRoute) {
return null;
}
return global(id)?.currentState?.pushReplacement(GetPageRoute(
opaque: opaque ?? true,
return global(id).currentState?.pushReplacement(GetPageRoute(
opaque: opaque,
page: _resolve(page, 'off'),
binding: binding,
settings: RouteSettings(arguments: arguments),
... ... @@ -917,24 +905,24 @@ you can only use widgets and widget functions here''';
///
/// By default, GetX will prevent you from push a route that you already in,
/// if you want to push anyway, set [preventDuplicates] to false
Future<T> offAll<T>(
Future<T?>? offAll<T>(
dynamic page, {
RoutePredicate predicate,
RoutePredicate? predicate,
bool opaque = false,
bool popGesture,
int id,
bool? popGesture,
int? id,
dynamic arguments,
Bindings binding,
Bindings? binding,
bool fullscreenDialog = false,
Transition transition,
Curve curve,
Duration duration,
Transition? transition,
Curve? curve,
Duration? duration,
}) {
var routeName = "/${page.runtimeType.toString()}";
return global(id)?.currentState?.pushAndRemoveUntil<T>(
return global(id).currentState?.pushAndRemoveUntil<T>(
GetPageRoute<T>(
opaque: opaque ?? true,
opaque: opaque,
popGesture: popGesture ?? defaultPopGesture,
page: _resolve(page, 'offAll'),
binding: binding,
... ... @@ -948,32 +936,28 @@ you can only use widgets and widget functions here''';
predicate ?? (route) => false);
}
void addPages(List<GetPage> getPages) {
void addPages(List<GetPage>? getPages) {
if (getPages != null) {
if (routeTree == null) {
routeTree = ParseRouteTree();
}
routeTree = ParseRouteTree();
routeTree.addRoutes(getPages);
}
}
void addPage(GetPage getPage) {
if (getPage != null) {
if (routeTree == null) routeTree = ParseRouteTree();
routeTree.addRoute(getPage);
}
routeTree = ParseRouteTree();
routeTree.addRoute(getPage);
}
/// change default config of Get
void config(
{bool enableLog,
LogWriterCallback logWriterCallback,
bool defaultPopGesture,
bool defaultOpaqueRoute,
Duration defaultDurationTransition,
bool defaultGlobalState,
Transition defaultTransition}) {
{bool? enableLog,
LogWriterCallback? logWriterCallback,
bool? defaultPopGesture,
bool? defaultOpaqueRoute,
Duration? defaultDurationTransition,
bool? defaultGlobalState,
Transition? defaultTransition}) {
if (enableLog != null) {
Get.isLogEnable = enableLog;
}
... ... @@ -1014,7 +998,7 @@ you can only use widgets and widget functions here''';
/// Your entire application will be rebuilt, and touch events will not
/// work until the end of rendering.
void forceAppUpdate() {
engine.performReassemble();
engine!.performReassemble();
}
void appUpdate() => getxController.update();
... ... @@ -1027,17 +1011,17 @@ you can only use widgets and widget functions here''';
getxController.setThemeMode(themeMode);
}
GlobalKey<NavigatorState> addKey(GlobalKey<NavigatorState> newKey) {
GlobalKey<NavigatorState>? addKey(GlobalKey<NavigatorState> newKey) {
getxController.key = newKey;
return key;
}
GlobalKey<NavigatorState> nestedKey(int key) {
GlobalKey<NavigatorState>? nestedKey(dynamic key) {
keys.putIfAbsent(key, () => GlobalKey<NavigatorState>());
return keys[key];
}
GlobalKey<NavigatorState> global(int k) {
GlobalKey<NavigatorState> global(int? k) {
GlobalKey<NavigatorState> _key;
if (k == null) {
_key = key;
... ... @@ -1045,7 +1029,7 @@ you can only use widgets and widget functions here''';
if (!keys.containsKey(k)) {
throw 'Route id ($k) not found';
}
_key = keys[k];
_key = keys[k]!;
}
if (_key.currentContext == null && !testMode) {
... ... @@ -1061,12 +1045,6 @@ you can only use widgets and widget functions here''';
return _key;
}
@Deprecated('''
Since version 2.8 it is possible to access the properties
[Get.arguments] and [Get.currentRoute] directly.
[routeSettings] is useless and should not be used.''')
RouteSettings get routeSettings => null;
/// give current arguments
dynamic get arguments => routing.args;
... ... @@ -1077,16 +1055,16 @@ Since version 2.8 it is possible to access the properties
String get previousRoute => routing.previous;
/// check if snackbar is open
bool get isSnackbarOpen => routing.isSnackbar;
bool? get isSnackbarOpen => routing.isSnackbar;
/// check if dialog is open
bool get isDialogOpen => routing.isDialog;
bool? get isDialogOpen => routing.isDialog;
/// check if bottomsheet is open
bool get isBottomSheetOpen => routing.isBottomSheet;
bool? get isBottomSheetOpen => routing.isBottomSheet;
/// check a raw current route
Route<dynamic> get rawRoute => routing.route;
Route<dynamic>? get rawRoute => routing.route;
/// check if popGesture is enable
bool get isPopGestureEnable => defaultPopGesture;
... ... @@ -1095,12 +1073,12 @@ Since version 2.8 it is possible to access the properties
bool get isOpaqueRouteDefault => defaultOpaqueRoute;
/// give access to currentContext
BuildContext get context => key?.currentContext;
BuildContext? get context => key.currentContext;
/// give access to current Overlay Context
BuildContext get overlayContext {
BuildContext overlay;
key?.currentState?.overlay?.context?.visitChildElements((element) {
BuildContext? get overlayContext {
BuildContext? overlay;
key.currentState?.overlay?.context.visitChildElements((element) {
overlay = element;
});
return overlay;
... ... @@ -1108,25 +1086,23 @@ Since version 2.8 it is possible to access the properties
/// give access to Theme.of(context)
ThemeData get theme {
ThemeData _theme;
var _theme = ThemeData.fallback();
if (context != null) {
_theme = Theme.of(context);
_theme = Theme.of(context!);
}
return _theme;
}
///The current [WidgetsBinding]
WidgetsBinding get engine {
WidgetsBinding? get engine {
if (WidgetsBinding.instance == null) {
WidgetsFlutterBinding();
}
return WidgetsBinding.instance;
}
//TODO: Change to ui.SingletonFlutterWindow rather dynamic
//when Flutter update stable. dynamic is used to avoid Breaking Changes
/// The window to which this binding is bound.
dynamic get window => ui.window;
ui.SingletonFlutterWindow get window => ui.window;
Locale get deviceLocale => ui.window.locale;
... ... @@ -1153,10 +1129,10 @@ Since version 2.8 it is possible to access the properties
double get textScaleFactor => ui.window.textScaleFactor;
/// give access to TextTheme.of(context)
TextTheme get textTheme => theme?.textTheme;
TextTheme get textTheme => theme.textTheme;
/// give access to Mediaquery.of(context)
MediaQueryData get mediaQuery => MediaQuery.of(context);
MediaQueryData get mediaQuery => MediaQuery.of(context!);
/// Check if dark mode theme is enable
bool get isDarkMode => (theme.brightness == Brightness.dark);
... ... @@ -1166,10 +1142,10 @@ Since version 2.8 it is possible to access the properties
(ui.window.platformBrightness == Brightness.dark);
/// give access to Theme.of(context).iconTheme.color
Color get iconColor => theme?.iconTheme?.color;
Color? get iconColor => theme.iconTheme.color;
/// give access to FocusScope.of(context)
FocusNode get focusScope => FocusManager.instance.primaryFocus;
FocusNode? get focusScope => FocusManager.instance.primaryFocus;
// /// give access to Immutable MediaQuery.of(context).size.height
// double get height => MediaQuery.of(context).size.height;
... ... @@ -1177,16 +1153,16 @@ Since version 2.8 it is possible to access the properties
// /// give access to Immutable MediaQuery.of(context).size.width
// double get width => MediaQuery.of(context).size.width;
GlobalKey<NavigatorState> get key => getxController?.key;
GlobalKey<NavigatorState> get key => getxController.key;
Map<int, GlobalKey<NavigatorState>> get keys => getxController?.keys;
Map<dynamic, GlobalKey<NavigatorState>> get keys => getxController.keys;
GetMaterialController get rootController => getxController;
bool get defaultPopGesture => getxController.defaultPopGesture;
bool get defaultOpaqueRoute => getxController.defaultOpaqueRoute;
Transition get defaultTransition => getxController.defaultTransition;
Transition? get defaultTransition => getxController.defaultTransition;
Duration get defaultTransitionDuration {
return getxController.defaultTransitionDuration;
... ... @@ -1204,15 +1180,15 @@ Since version 2.8 it is possible to access the properties
Routing get routing => getxController.routing;
Map<String, String> get parameters => getxController.parameters;
set parameters(Map<String, String> newParameters) =>
Map<String, String?> get parameters => getxController.parameters;
set parameters(Map<String, String?> newParameters) =>
getxController.parameters = newParameters;
ParseRouteTree get routeTree => getxController.routeTree;
set routeTree(ParseRouteTree tree) => getxController.routeTree = tree;
CustomTransition get customTransition => getxController.customTransition;
set customTransition(CustomTransition newTransition) =>
CustomTransition? get customTransition => getxController.customTransition;
set customTransition(CustomTransition? newTransition) =>
getxController.customTransition = newTransition;
bool get testMode => getxController.testMode;
... ... @@ -1224,4 +1200,4 @@ Since version 2.8 it is possible to access the properties
/// It replaces the Flutter Navigator, but needs no context.
/// You can to use navigator.push(YourRoute()) rather
/// Navigator.push(context, YourRoute());
NavigatorState get navigator => GetNavigation(Get).key.currentState;
NavigatorState? get navigator => GetNavigation(Get).key.currentState;
... ...
... ... @@ -10,16 +10,18 @@ import 'root_controller.dart';
class GetCupertinoApp extends StatelessWidget {
const GetCupertinoApp({
Key key,
Key? key,
this.theme,
this.navigatorKey,
this.home,
this.routes = const <String, WidgetBuilder>{},
Map<String, Widget Function(BuildContext)> this.routes =
const <String, WidgetBuilder>{},
this.initialRoute,
this.onGenerateRoute,
this.onGenerateInitialRoutes,
this.onUnknownRoute,
this.navigatorObservers = const <NavigatorObserver>[],
List<NavigatorObserver> this.navigatorObservers =
const <NavigatorObserver>[],
this.builder,
this.translationsKeys,
this.translations,
... ... @@ -58,78 +60,70 @@ class GetCupertinoApp extends StatelessWidget {
this.highContrastTheme,
this.highContrastDarkTheme,
this.actions,
}) : assert(routes != null),
assert(navigatorObservers != null),
assert(title != null),
assert(showPerformanceOverlay != null),
assert(checkerboardRasterCacheImages != null),
assert(checkerboardOffscreenLayers != null),
assert(showSemanticsDebugger != null),
assert(debugShowCheckedModeBanner != null),
routeInformationProvider = null,
}) : routeInformationProvider = null,
routeInformationParser = null,
routerDelegate = null,
backButtonDispatcher = null,
super(key: key);
final GlobalKey<NavigatorState> navigatorKey;
final Widget home;
final Map<String, WidgetBuilder> routes;
final String initialRoute;
final RouteFactory onGenerateRoute;
final InitialRouteListFactory onGenerateInitialRoutes;
final RouteFactory onUnknownRoute;
final List<NavigatorObserver> navigatorObservers;
final TransitionBuilder builder;
final GlobalKey<NavigatorState>? navigatorKey;
final Widget? home;
final Map<String, WidgetBuilder>? routes;
final String? initialRoute;
final RouteFactory? onGenerateRoute;
final InitialRouteListFactory? onGenerateInitialRoutes;
final RouteFactory? onUnknownRoute;
final List<NavigatorObserver>? navigatorObservers;
final TransitionBuilder? builder;
final String title;
final GenerateAppTitle onGenerateTitle;
final CustomTransition customTransition;
final Color color;
final Map<String, Map<String, String>> translationsKeys;
final Translations translations;
final TextDirection textDirection;
final Locale locale;
final Locale fallbackLocale;
final Iterable<LocalizationsDelegate<dynamic>> localizationsDelegates;
final LocaleListResolutionCallback localeListResolutionCallback;
final LocaleResolutionCallback localeResolutionCallback;
final GenerateAppTitle? onGenerateTitle;
final CustomTransition? customTransition;
final Color? color;
final Map<String, Map<String, String>>? translationsKeys;
final Translations? translations;
final TextDirection? textDirection;
final Locale? locale;
final Locale? fallbackLocale;
final Iterable<LocalizationsDelegate<dynamic>>? localizationsDelegates;
final LocaleListResolutionCallback? localeListResolutionCallback;
final LocaleResolutionCallback? localeResolutionCallback;
final Iterable<Locale> supportedLocales;
final bool showPerformanceOverlay;
final bool checkerboardRasterCacheImages;
final bool checkerboardOffscreenLayers;
final bool showSemanticsDebugger;
final bool debugShowCheckedModeBanner;
final Map<LogicalKeySet, Intent> shortcuts;
final ThemeData highContrastTheme;
final ThemeData highContrastDarkTheme;
final Map<Type, Action<Intent>> actions;
final Function(Routing) routingCallback;
final Transition defaultTransition;
final bool opaqueRoute;
final VoidCallback onInit;
final VoidCallback onReady;
final VoidCallback onDispose;
final bool enableLog;
final LogWriterCallback logWriterCallback;
final bool popGesture;
final Map<LogicalKeySet, Intent>? shortcuts;
final ThemeData? highContrastTheme;
final ThemeData? highContrastDarkTheme;
final Map<Type, Action<Intent>>? actions;
final Function(Routing?)? routingCallback;
final Transition? defaultTransition;
final bool? opaqueRoute;
final VoidCallback? onInit;
final VoidCallback? onReady;
final VoidCallback? onDispose;
final bool? enableLog;
final LogWriterCallback? logWriterCallback;
final bool? popGesture;
final SmartManagement smartManagement;
final Bindings initialBinding;
final Duration transitionDuration;
final bool defaultGlobalState;
final List<GetPage> getPages;
final GetPage unknownRoute;
final RouteInformationProvider routeInformationProvider;
final RouteInformationParser<Object> routeInformationParser;
final RouterDelegate<Object> routerDelegate;
final BackButtonDispatcher backButtonDispatcher;
final CupertinoThemeData theme;
final Bindings? initialBinding;
final Duration? transitionDuration;
final bool? defaultGlobalState;
final List<GetPage>? getPages;
final GetPage? unknownRoute;
final RouteInformationProvider? routeInformationProvider;
final RouteInformationParser<Object>? routeInformationParser;
final RouterDelegate<Object>? routerDelegate;
final BackButtonDispatcher? backButtonDispatcher;
final CupertinoThemeData? theme;
const GetCupertinoApp.router({
Key key,
Key? key,
this.theme,
this.routeInformationProvider,
@required this.routeInformationParser,
@required this.routerDelegate,
required RouteInformationParser<Object> this.routeInformationParser,
required RouterDelegate<Object> this.routerDelegate,
this.backButtonDispatcher,
this.builder,
this.title = '',
... ... @@ -169,15 +163,7 @@ class GetCupertinoApp extends StatelessWidget {
this.defaultGlobalState,
this.getPages,
this.unknownRoute,
}) : assert(routeInformationParser != null),
assert(routerDelegate != null),
assert(title != null),
assert(showPerformanceOverlay != null),
assert(checkerboardRasterCacheImages != null),
assert(checkerboardOffscreenLayers != null),
assert(showSemanticsDebugger != null),
assert(debugShowCheckedModeBanner != null),
navigatorObservers = null,
}) : navigatorObservers = null,
navigatorKey = null,
onGenerateRoute = null,
home = null,
... ... @@ -201,7 +187,7 @@ class GetCupertinoApp extends StatelessWidget {
onDispose?.call();
},
initState: (i) {
Get.engine.addPostFrameCallback((timeStamp) {
Get.engine!.addPostFrameCallback((timeStamp) {
onReady?.call();
});
if (locale != null) Get.locale = locale;
... ... @@ -209,9 +195,9 @@ class GetCupertinoApp extends StatelessWidget {
if (fallbackLocale != null) Get.fallbackLocale = fallbackLocale;
if (translations != null) {
Get.addTranslations(translations.keys);
Get.addTranslations(translations!.keys);
} else if (translationsKeys != null) {
Get.addTranslations(translationsKeys);
Get.addTranslations(translationsKeys!);
}
Get.customTransition = customTransition;
... ... @@ -233,8 +219,8 @@ class GetCupertinoApp extends StatelessWidget {
},
builder: (_) => routerDelegate != null
? CupertinoApp.router(
routerDelegate: routerDelegate,
routeInformationParser: routeInformationParser,
routerDelegate: routerDelegate!,
routeInformationParser: routeInformationParser!,
backButtonDispatcher: backButtonDispatcher,
routeInformationProvider: routeInformationProvider,
key: _.unikey,
... ... @@ -245,31 +231,29 @@ class GetCupertinoApp extends StatelessWidget {
(rtlLanguages.contains(Get.locale?.languageCode)
? TextDirection.rtl
: TextDirection.ltr),
child: builder == null ? child : builder(context, child),
child: builder == null ? child! : builder!(context, child),
);
},
title: title ?? '',
title: title,
onGenerateTitle: onGenerateTitle,
color: color,
locale: Get.locale ?? locale,
localizationsDelegates: localizationsDelegates,
localeListResolutionCallback: localeListResolutionCallback,
localeResolutionCallback: localeResolutionCallback,
supportedLocales:
supportedLocales ?? const <Locale>[Locale('en', 'US')],
showPerformanceOverlay: showPerformanceOverlay ?? false,
checkerboardRasterCacheImages:
checkerboardRasterCacheImages ?? false,
checkerboardOffscreenLayers: checkerboardOffscreenLayers ?? false,
showSemanticsDebugger: showSemanticsDebugger ?? false,
debugShowCheckedModeBanner: debugShowCheckedModeBanner ?? true,
supportedLocales: supportedLocales,
showPerformanceOverlay: showPerformanceOverlay,
checkerboardRasterCacheImages: checkerboardRasterCacheImages,
checkerboardOffscreenLayers: checkerboardOffscreenLayers,
showSemanticsDebugger: showSemanticsDebugger,
debugShowCheckedModeBanner: debugShowCheckedModeBanner,
shortcuts: shortcuts,
)
: CupertinoApp(
key: _.unikey,
theme: theme,
navigatorKey:
(navigatorKey == null ? Get.key : Get.addKey(navigatorKey)),
(navigatorKey == null ? Get.key : Get.addKey(navigatorKey!)),
home: home,
routes: routes ?? const <String, WidgetBuilder>{},
initialRoute: initialRoute,
... ... @@ -285,31 +269,29 @@ class GetCupertinoApp extends StatelessWidget {
: <NavigatorObserver>[
GetObserver(routingCallback, Get.routing)
]
..addAll(navigatorObservers)),
..addAll(navigatorObservers!)),
builder: (context, child) {
return Directionality(
textDirection: textDirection ??
(rtlLanguages.contains(Get.locale?.languageCode)
? TextDirection.rtl
: TextDirection.ltr),
child: builder == null ? child : builder(context, child),
child: builder == null ? child! : builder!(context, child),
);
},
title: title ?? '',
title: title,
onGenerateTitle: onGenerateTitle,
color: color,
locale: Get.locale ?? locale,
localizationsDelegates: localizationsDelegates,
localeListResolutionCallback: localeListResolutionCallback,
localeResolutionCallback: localeResolutionCallback,
supportedLocales:
supportedLocales ?? const <Locale>[Locale('en', 'US')],
showPerformanceOverlay: showPerformanceOverlay ?? false,
checkerboardRasterCacheImages:
checkerboardRasterCacheImages ?? false,
checkerboardOffscreenLayers: checkerboardOffscreenLayers ?? false,
showSemanticsDebugger: showSemanticsDebugger ?? false,
debugShowCheckedModeBanner: debugShowCheckedModeBanner ?? true,
supportedLocales: supportedLocales,
showPerformanceOverlay: showPerformanceOverlay,
checkerboardRasterCacheImages: checkerboardRasterCacheImages,
checkerboardOffscreenLayers: checkerboardOffscreenLayers,
showSemanticsDebugger: showSemanticsDebugger,
debugShowCheckedModeBanner: debugShowCheckedModeBanner,
shortcuts: shortcuts,
// actions: actions,
));
... ...
... ... @@ -10,15 +10,17 @@ import 'root_controller.dart';
class GetMaterialApp extends StatelessWidget {
const GetMaterialApp({
Key key,
Key? key,
this.navigatorKey,
this.home,
this.routes = const <String, WidgetBuilder>{},
Map<String, Widget Function(BuildContext)> this.routes =
const <String, WidgetBuilder>{},
this.initialRoute,
this.onGenerateRoute,
this.onGenerateInitialRoutes,
this.onUnknownRoute,
this.navigatorObservers = const <NavigatorObserver>[],
List<NavigatorObserver> this.navigatorObservers =
const <NavigatorObserver>[],
this.builder,
this.textDirection,
this.title = '',
... ... @@ -61,81 +63,72 @@ class GetMaterialApp extends StatelessWidget {
this.highContrastTheme,
this.highContrastDarkTheme,
this.actions,
}) : assert(routes != null),
assert(navigatorObservers != null),
assert(title != null),
assert(debugShowMaterialGrid != null),
assert(showPerformanceOverlay != null),
assert(checkerboardRasterCacheImages != null),
assert(checkerboardOffscreenLayers != null),
assert(showSemanticsDebugger != null),
assert(debugShowCheckedModeBanner != null),
routeInformationProvider = null,
}) : routeInformationProvider = null,
routeInformationParser = null,
routerDelegate = null,
backButtonDispatcher = null,
super(key: key);
final GlobalKey<NavigatorState> navigatorKey;
final Widget home;
final Map<String, WidgetBuilder> routes;
final String initialRoute;
final RouteFactory onGenerateRoute;
final InitialRouteListFactory onGenerateInitialRoutes;
final RouteFactory onUnknownRoute;
final List<NavigatorObserver> navigatorObservers;
final TransitionBuilder builder;
final GlobalKey<NavigatorState>? navigatorKey;
final Widget? home;
final Map<String, WidgetBuilder>? routes;
final String? initialRoute;
final RouteFactory? onGenerateRoute;
final InitialRouteListFactory? onGenerateInitialRoutes;
final RouteFactory? onUnknownRoute;
final List<NavigatorObserver>? navigatorObservers;
final TransitionBuilder? builder;
final String title;
final GenerateAppTitle onGenerateTitle;
final ThemeData theme;
final ThemeData darkTheme;
final GenerateAppTitle? onGenerateTitle;
final ThemeData? theme;
final ThemeData? darkTheme;
final ThemeMode themeMode;
final CustomTransition customTransition;
final Color color;
final Map<String, Map<String, String>> translationsKeys;
final Translations translations;
final TextDirection textDirection;
final Locale locale;
final Locale fallbackLocale;
final Iterable<LocalizationsDelegate<dynamic>> localizationsDelegates;
final LocaleListResolutionCallback localeListResolutionCallback;
final LocaleResolutionCallback localeResolutionCallback;
final CustomTransition? customTransition;
final Color? color;
final Map<String, Map<String, String>>? translationsKeys;
final Translations? translations;
final TextDirection? textDirection;
final Locale? locale;
final Locale? fallbackLocale;
final Iterable<LocalizationsDelegate<dynamic>>? localizationsDelegates;
final LocaleListResolutionCallback? localeListResolutionCallback;
final LocaleResolutionCallback? localeResolutionCallback;
final Iterable<Locale> supportedLocales;
final bool showPerformanceOverlay;
final bool checkerboardRasterCacheImages;
final bool checkerboardOffscreenLayers;
final bool showSemanticsDebugger;
final bool debugShowCheckedModeBanner;
final Map<LogicalKeySet, Intent> shortcuts;
final ThemeData highContrastTheme;
final ThemeData highContrastDarkTheme;
final Map<Type, Action<Intent>> actions;
final Map<LogicalKeySet, Intent>? shortcuts;
final ThemeData? highContrastTheme;
final ThemeData? highContrastDarkTheme;
final Map<Type, Action<Intent>>? actions;
final bool debugShowMaterialGrid;
final ValueChanged<Routing> routingCallback;
final Transition defaultTransition;
final bool opaqueRoute;
final VoidCallback onInit;
final VoidCallback onReady;
final VoidCallback onDispose;
final bool enableLog;
final LogWriterCallback logWriterCallback;
final bool popGesture;
final ValueChanged<Routing?>? routingCallback;
final Transition? defaultTransition;
final bool? opaqueRoute;
final VoidCallback? onInit;
final VoidCallback? onReady;
final VoidCallback? onDispose;
final bool? enableLog;
final LogWriterCallback? logWriterCallback;
final bool? popGesture;
final SmartManagement smartManagement;
final Bindings initialBinding;
final Duration transitionDuration;
final bool defaultGlobalState;
final List<GetPage> getPages;
final GetPage unknownRoute;
final RouteInformationProvider routeInformationProvider;
final RouteInformationParser<Object> routeInformationParser;
final RouterDelegate<Object> routerDelegate;
final BackButtonDispatcher backButtonDispatcher;
final Bindings? initialBinding;
final Duration? transitionDuration;
final bool? defaultGlobalState;
final List<GetPage>? getPages;
final GetPage? unknownRoute;
final RouteInformationProvider? routeInformationProvider;
final RouteInformationParser<Object>? routeInformationParser;
final RouterDelegate<Object>? routerDelegate;
final BackButtonDispatcher? backButtonDispatcher;
const GetMaterialApp.router({
Key key,
Key? key,
this.routeInformationProvider,
@required this.routeInformationParser,
@required this.routerDelegate,
required RouteInformationParser<Object> this.routeInformationParser,
required RouterDelegate<Object> this.routerDelegate,
this.backButtonDispatcher,
this.builder,
this.title = '',
... ... @@ -179,16 +172,7 @@ class GetMaterialApp extends StatelessWidget {
this.defaultGlobalState,
this.getPages,
this.unknownRoute,
}) : assert(routeInformationParser != null),
assert(routerDelegate != null),
assert(title != null),
assert(debugShowMaterialGrid != null),
assert(showPerformanceOverlay != null),
assert(checkerboardRasterCacheImages != null),
assert(checkerboardOffscreenLayers != null),
assert(showSemanticsDebugger != null),
assert(debugShowCheckedModeBanner != null),
navigatorObservers = null,
}) : navigatorObservers = null,
navigatorKey = null,
onGenerateRoute = null,
home = null,
... ... @@ -211,7 +195,7 @@ class GetMaterialApp extends StatelessWidget {
onDispose?.call();
},
initState: (i) {
Get.engine.addPostFrameCallback((timeStamp) {
Get.engine!.addPostFrameCallback((timeStamp) {
onReady?.call();
});
if (locale != null) Get.locale = locale;
... ... @@ -219,9 +203,9 @@ class GetMaterialApp extends StatelessWidget {
if (fallbackLocale != null) Get.fallbackLocale = fallbackLocale;
if (translations != null) {
Get.addTranslations(translations.keys);
Get.addTranslations(translations!.keys);
} else if (translationsKeys != null) {
Get.addTranslations(translationsKeys);
Get.addTranslations(translationsKeys!);
}
Get.customTransition = customTransition;
... ... @@ -243,8 +227,8 @@ class GetMaterialApp extends StatelessWidget {
},
builder: (_) => routerDelegate != null
? MaterialApp.router(
routerDelegate: routerDelegate,
routeInformationParser: routeInformationParser,
routerDelegate: routerDelegate!,
routeInformationParser: routeInformationParser!,
backButtonDispatcher: backButtonDispatcher,
routeInformationProvider: routeInformationProvider,
key: _.unikey,
... ... @@ -254,34 +238,32 @@ class GetMaterialApp extends StatelessWidget {
(rtlLanguages.contains(Get.locale?.languageCode)
? TextDirection.rtl
: TextDirection.ltr),
child: builder == null ? child : builder(context, child),
child: builder == null ? child! : builder!(context, child),
);
},
title: title ?? '',
title: title,
onGenerateTitle: onGenerateTitle,
color: color,
theme: _.theme ?? theme ?? ThemeData.fallback(),
darkTheme: darkTheme,
themeMode: _.themeMode ?? themeMode ?? ThemeMode.system,
darkTheme: _.darkTheme ?? darkTheme ?? ThemeData.fallback(),
themeMode: _.themeMode ?? themeMode,
locale: Get.locale ?? locale,
localizationsDelegates: localizationsDelegates,
localeListResolutionCallback: localeListResolutionCallback,
localeResolutionCallback: localeResolutionCallback,
supportedLocales:
supportedLocales ?? const <Locale>[Locale('en', 'US')],
debugShowMaterialGrid: debugShowMaterialGrid ?? false,
showPerformanceOverlay: showPerformanceOverlay ?? false,
checkerboardRasterCacheImages:
checkerboardRasterCacheImages ?? false,
checkerboardOffscreenLayers: checkerboardOffscreenLayers ?? false,
showSemanticsDebugger: showSemanticsDebugger ?? false,
debugShowCheckedModeBanner: debugShowCheckedModeBanner ?? true,
supportedLocales: supportedLocales,
debugShowMaterialGrid: debugShowMaterialGrid,
showPerformanceOverlay: showPerformanceOverlay,
checkerboardRasterCacheImages: checkerboardRasterCacheImages,
checkerboardOffscreenLayers: checkerboardOffscreenLayers,
showSemanticsDebugger: showSemanticsDebugger,
debugShowCheckedModeBanner: debugShowCheckedModeBanner,
shortcuts: shortcuts,
)
: MaterialApp(
key: _.unikey,
navigatorKey:
(navigatorKey == null ? Get.key : Get.addKey(navigatorKey)),
(navigatorKey == null ? Get.key : Get.addKey(navigatorKey!)),
home: home,
routes: routes ?? const <String, WidgetBuilder>{},
initialRoute: initialRoute,
... ... @@ -297,36 +279,95 @@ class GetMaterialApp extends StatelessWidget {
: <NavigatorObserver>[
GetObserver(routingCallback, Get.routing)
]
..addAll(navigatorObservers)),
..addAll(navigatorObservers!)),
builder: (context, child) {
return Directionality(
textDirection: textDirection ??
(rtlLanguages.contains(Get.locale?.languageCode)
? TextDirection.rtl
: TextDirection.ltr),
child: builder == null ? child : builder(context, child),
child: builder == null ? child! : builder!(context, child),
);
},
title: title ?? '',
title: title,
onGenerateTitle: onGenerateTitle,
color: color,
theme: _.theme ?? theme ?? ThemeData.fallback(),
darkTheme: darkTheme,
themeMode: _.themeMode ?? themeMode ?? ThemeMode.system,
darkTheme: _.darkTheme ?? darkTheme ?? ThemeData.fallback(),
themeMode: _.themeMode ?? themeMode,
locale: Get.locale ?? locale,
localizationsDelegates: localizationsDelegates,
localeListResolutionCallback: localeListResolutionCallback,
localeResolutionCallback: localeResolutionCallback,
supportedLocales:
supportedLocales ?? const <Locale>[Locale('en', 'US')],
debugShowMaterialGrid: debugShowMaterialGrid ?? false,
showPerformanceOverlay: showPerformanceOverlay ?? false,
checkerboardRasterCacheImages:
checkerboardRasterCacheImages ?? false,
checkerboardOffscreenLayers: checkerboardOffscreenLayers ?? false,
showSemanticsDebugger: showSemanticsDebugger ?? false,
debugShowCheckedModeBanner: debugShowCheckedModeBanner ?? true,
supportedLocales: supportedLocales,
debugShowMaterialGrid: debugShowMaterialGrid,
showPerformanceOverlay: showPerformanceOverlay,
checkerboardRasterCacheImages: checkerboardRasterCacheImages,
checkerboardOffscreenLayers: checkerboardOffscreenLayers,
showSemanticsDebugger: showSemanticsDebugger,
debugShowCheckedModeBanner: debugShowCheckedModeBanner,
shortcuts: shortcuts,
// actions: actions,
));
}
class GetNavigator extends StatelessWidget {
final List<GetPage> getPages;
const GetNavigator(
{Key? key,
required this.getPages,
this.pages = const <Page<dynamic>>[],
this.onPopPage,
this.initialRoute,
this.onGenerateInitialRoutes = Navigator.defaultGenerateInitialRoutes,
this.onGenerateRoute,
this.onUnknownRoute,
this.transitionDelegate = const DefaultTransitionDelegate<dynamic>(),
this.reportsRouteUpdateToEngine = false,
this.observers = const <NavigatorObserver>[],
this.restorationScopeId,
this.unKnownRoute})
: super(key: key);
final List<Page<dynamic>> pages;
final GetPage? unKnownRoute;
final PopPageCallback? onPopPage;
final TransitionDelegate<dynamic> transitionDelegate;
final String? initialRoute;
final RouteFactory? onGenerateRoute;
final RouteFactory? onUnknownRoute;
final List<NavigatorObserver> observers;
final String? restorationScopeId;
static const String defaultRouteName = '/';
final RouteListFactory onGenerateInitialRoutes;
final bool reportsRouteUpdateToEngine;
@override
Widget build(Object context) {
return Navigator(
pages: getPages,
onPopPage: onPopPage,
initialRoute: initialRoute,
onGenerateInitialRoutes: onGenerateInitialRoutes,
onGenerateRoute: onGenerateRoute,
onUnknownRoute: onUnknownRoute,
transitionDelegate: transitionDelegate,
reportsRouteUpdateToEngine: reportsRouteUpdateToEngine,
observers: observers,
restorationScopeId: restorationScopeId,
key: Get.nestedKey(key),
);
}
}
... ...