Jonny Borges

improve api

... ... @@ -3,7 +3,7 @@ import 'package:get/get.dart';
import '../../domain/adapters/repository_adapter.dart';
import '../../domain/entity/cases_model.dart';
class HomeController extends SuperController<CasesModel> {
class HomeController extends StateController<CasesModel> {
HomeController({required this.homeRepository});
final IHomeRepository homeRepository;
... ... @@ -13,7 +13,7 @@ class HomeController extends SuperController<CasesModel> {
super.onInit();
//Loading, Success, Error handle with 1 line of code
append(() => homeRepository.getCases);
listenFuture(() => homeRepository.getCases);
}
Country getCountryById(String id) {
... ... @@ -24,61 +24,4 @@ class HomeController extends SuperController<CasesModel> {
return state.countries.first;
}
@override
void onReady() {
print('The build method is done. '
'Your controller is ready to call dialogs and snackbars');
super.onReady();
}
@override
void onClose() {
print('onClose called');
super.onClose();
}
@override
void didChangeMetrics() {
print('the window size did change');
super.didChangeMetrics();
}
@override
void didChangePlatformBrightness() {
print('platform change ThemeMode');
super.didChangePlatformBrightness();
}
@override
Future<bool> didPushRoute(String route) {
print('the route $route will be open');
return super.didPushRoute(route);
}
@override
Future<bool> didPopRoute() {
print('the current route will be closed');
return super.didPopRoute();
}
@override
void onDetached() {
print('onDetached called');
}
@override
void onInactive() {
print('onInative called');
}
@override
void onPaused() {
print('onPaused called');
}
@override
void onResumed() {
print('onResumed called');
}
}
... ...
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'app/routes/app_pages.dart';
import 'services/auth_service.dart';
void main() {
runApp(
GetMaterialApp(
home: Home(),
GetMaterialApp.router(
title: "Application",
initialBinding: BindingsBuilder(
() {
Get.put(AuthService());
},
),
getPages: AppPages.routes,
// routeInformationParser: GetInformationParser(
// // initialRoute: Routes.HOME,
// ),
// routerDelegate: GetDelegate(
// backButtonPopMode: PopMode.History,
// preventDuplicateHandlingMode:
// PreventDuplicateHandlingMode.ReorderRoutes,
// ),
),
);
}
class Controller extends GetxController {
final count = 0.reactive;
void increment() {
count.value++;
update();
}
}
class Home extends ObxStatelessWidget {
const Home({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final controller = Get.put(Controller());
return Scaffold(
appBar: AppBar(title: Text("counter")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Observer(builder: (context) {
print('builder');
return Text(
'${controller.count.value}',
style: TextStyle(fontSize: 30),
);
}),
// ElevatedButton(
// child: Text('Next Route'),
// onPressed: () {
// Get.to(() => Second());
// },
// ),
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: controller.increment,
),
);
}
}
... ...
... ... @@ -96,6 +96,7 @@ extension MapExtension<K, V> on Map<K, V> {
final map = (this as RxMap);
if (map.value == val) return;
map.value = val;
// ignore: invalid_use_of_protected_member
map.refresh();
} else {
if (this == val) return;
... ...
... ... @@ -4,10 +4,8 @@ import 'dart:async';
import 'dart:collection';
import 'package:flutter/foundation.dart';
import 'package:get/get_state_manager/src/rx_flutter/rx_notifier.dart';
import 'package:get/get_state_manager/src/simple/list_notifier.dart';
import '../rx_stream/rx_stream.dart';
import '../../../get_state_manager/src/rx_flutter/rx_notifier.dart';
import '../rx_typedefs/rx_typedefs.dart';
part 'rx_core/rx_impl.dart';
... ...
... ... @@ -8,13 +8,14 @@ import '../../get_state_manager.dart';
import '../simple/list_notifier.dart';
extension _NullOrEmpty on Object {
bool _isNullOrEmpty(dynamic val) {
if (val == null) return true;
bool _isEmpty() {
final val = this;
// if (val == null) return true;
var result = false;
if (val is Iterable) {
result = val.isEmpty;
} else if (val is String) {
result = val.isEmpty;
result = val.trim().isEmpty;
} else if (val is Map) {
result = val.isEmpty;
}
... ... @@ -24,15 +25,17 @@ extension _NullOrEmpty on Object {
mixin StateMixin<T> on ListNotifier {
late T _value;
RxStatus? _status;
GetState? _status;
void _fillEmptyStatus() {
_status = _isNullOrEmpty(_value) ? RxStatus.loading() : RxStatus.success();
_status = (value == null || value!._isEmpty())
? GetState.loading()
: GetState.success(_status);
}
RxStatus get status {
GetState get status {
reportRead();
return _status ??= _status = RxStatus.loading();
return _status ??= _status = GetState.loading();
}
T get state => value;
... ... @@ -51,7 +54,7 @@ mixin StateMixin<T> on ListNotifier {
}
@protected
void change(T newState, {RxStatus? status}) {
void change(T newState, {GetState? status}) {
var _canUpdate = false;
if (status != null) {
_status = status;
... ... @@ -66,12 +69,17 @@ mixin StateMixin<T> on ListNotifier {
}
}
void append(Future<T> Function() body(), {String? errorMessage}) {
void listenFuture(Future<T> Function() body(),
{String? errorMessage, bool useEmpty = true}) {
final compute = body();
compute().then((newValue) {
change(newValue, status: RxStatus.success());
if ((newValue == null || newValue._isEmpty()) && useEmpty) {
change(newValue, status: GetState.loading());
} else {
change(newValue, status: GetState.success(newValue));
}
}, onError: (err) {
change(state, status: RxStatus.error(errorMessage ?? err.toString()));
change(state, status: GetState.error(errorMessage ?? err.toString()));
});
}
}
... ... @@ -186,10 +194,6 @@ class Value<T> extends ListNotifier
dynamic toJson() => (value as dynamic)?.toJson();
}
extension ReactiveT<T> on T {
Value<T> get reactive => Value<T>(this);
}
abstract class GetNotifier<T> extends Value<T> with GetLifeCycleMixin {
GetNotifier(T initial) : super(initial);
}
... ... @@ -218,70 +222,32 @@ extension StateExt<T> on StateMixin<T> {
}
}
class RxStatus {
final bool isLoading;
final bool isError;
final bool isSuccess;
final bool isEmpty;
final bool isLoadingMore;
final String? errorMessage;
RxStatus._({
this.isEmpty = false,
this.isLoading = false,
this.isError = false,
this.isSuccess = false,
this.errorMessage,
this.isLoadingMore = false,
});
factory RxStatus.loading() {
return RxStatus._(isLoading: true);
}
factory RxStatus.loadingMore() {
return RxStatus._(isSuccess: true, isLoadingMore: true);
}
factory RxStatus.success() {
return RxStatus._(isSuccess: true);
}
factory RxStatus.error([String? message]) {
return RxStatus._(isError: true, errorMessage: message);
}
factory RxStatus.empty() {
return RxStatus._(isEmpty: true);
}
}
typedef NotifierBuilder<T> = Widget Function(T state);
abstract class GState<T> {
const GState();
factory GState.loading() => GLoading();
factory GState.error(String message) => GError(message);
factory GState.empty() => GEmpty();
factory GState.success(T data) => GSuccess(data);
abstract class GetState<T> {
const GetState();
factory GetState.loading() => GLoading();
factory GetState.error(String message) => GError(message);
factory GetState.empty() => GEmpty();
factory GetState.success(T data) => GSuccess(data);
}
class GLoading<T> extends GState<T> {}
class GLoading<T> extends GetState<T> {}
class GSuccess<T> extends GState<T> {
class GSuccess<T> extends GetState<T> {
final T data;
GSuccess(this.data);
}
class GError<T, S> extends GState<T> {
class GError<T, S> extends GetState<T> {
final S? error;
GError([this.error]);
}
class GEmpty<T> extends GState<T> {}
class GEmpty<T> extends GetState<T> {}
extension StatusDataExt<T> on GState<T> {
extension StatusDataExt<T> on GetState<T> {
bool get isLoading => this is GLoading;
bool get isSuccess => this is GSuccess;
bool get isError => this is GError;
... ...
... ... @@ -72,6 +72,8 @@ mixin ScrollMixin on GetLifeCycleMixin {
abstract class RxController with GetLifeCycleMixin {}
abstract class StateController<T> extends GetxController with StateMixin<T> {}
abstract class SuperController<T> extends FullLifeCycleController
with FullLifeCycleMixin, StateMixin<T> {}
... ...
... ... @@ -176,7 +176,9 @@ class TaskManager {
T Function() builder) {
_remove = disposers;
_setter = setState;
final result = builder();
print(disposers.isEmpty);
if (disposers.isEmpty) {
throw ObxError();
}
... ...