Showing
7 changed files
with
57 additions
and
171 deletions
@@ -3,7 +3,7 @@ import 'package:get/get.dart'; | @@ -3,7 +3,7 @@ import 'package:get/get.dart'; | ||
3 | import '../../domain/adapters/repository_adapter.dart'; | 3 | import '../../domain/adapters/repository_adapter.dart'; |
4 | import '../../domain/entity/cases_model.dart'; | 4 | import '../../domain/entity/cases_model.dart'; |
5 | 5 | ||
6 | -class HomeController extends SuperController<CasesModel> { | 6 | +class HomeController extends StateController<CasesModel> { |
7 | HomeController({required this.homeRepository}); | 7 | HomeController({required this.homeRepository}); |
8 | 8 | ||
9 | final IHomeRepository homeRepository; | 9 | final IHomeRepository homeRepository; |
@@ -13,7 +13,7 @@ class HomeController extends SuperController<CasesModel> { | @@ -13,7 +13,7 @@ class HomeController extends SuperController<CasesModel> { | ||
13 | super.onInit(); | 13 | super.onInit(); |
14 | 14 | ||
15 | //Loading, Success, Error handle with 1 line of code | 15 | //Loading, Success, Error handle with 1 line of code |
16 | - append(() => homeRepository.getCases); | 16 | + listenFuture(() => homeRepository.getCases); |
17 | } | 17 | } |
18 | 18 | ||
19 | Country getCountryById(String id) { | 19 | Country getCountryById(String id) { |
@@ -24,61 +24,4 @@ class HomeController extends SuperController<CasesModel> { | @@ -24,61 +24,4 @@ class HomeController extends SuperController<CasesModel> { | ||
24 | 24 | ||
25 | return state.countries.first; | 25 | return state.countries.first; |
26 | } | 26 | } |
27 | - | ||
28 | - @override | ||
29 | - void onReady() { | ||
30 | - print('The build method is done. ' | ||
31 | - 'Your controller is ready to call dialogs and snackbars'); | ||
32 | - super.onReady(); | ||
33 | - } | ||
34 | - | ||
35 | - @override | ||
36 | - void onClose() { | ||
37 | - print('onClose called'); | ||
38 | - super.onClose(); | ||
39 | - } | ||
40 | - | ||
41 | - @override | ||
42 | - void didChangeMetrics() { | ||
43 | - print('the window size did change'); | ||
44 | - super.didChangeMetrics(); | ||
45 | - } | ||
46 | - | ||
47 | - @override | ||
48 | - void didChangePlatformBrightness() { | ||
49 | - print('platform change ThemeMode'); | ||
50 | - super.didChangePlatformBrightness(); | ||
51 | - } | ||
52 | - | ||
53 | - @override | ||
54 | - Future<bool> didPushRoute(String route) { | ||
55 | - print('the route $route will be open'); | ||
56 | - return super.didPushRoute(route); | ||
57 | - } | ||
58 | - | ||
59 | - @override | ||
60 | - Future<bool> didPopRoute() { | ||
61 | - print('the current route will be closed'); | ||
62 | - return super.didPopRoute(); | ||
63 | - } | ||
64 | - | ||
65 | - @override | ||
66 | - void onDetached() { | ||
67 | - print('onDetached called'); | ||
68 | - } | ||
69 | - | ||
70 | - @override | ||
71 | - void onInactive() { | ||
72 | - print('onInative called'); | ||
73 | - } | ||
74 | - | ||
75 | - @override | ||
76 | - void onPaused() { | ||
77 | - print('onPaused called'); | ||
78 | - } | ||
79 | - | ||
80 | - @override | ||
81 | - void onResumed() { | ||
82 | - print('onResumed called'); | ||
83 | - } | ||
84 | } | 27 | } |
1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
2 | import 'package:get/get.dart'; | 2 | import 'package:get/get.dart'; |
3 | 3 | ||
4 | +import 'app/routes/app_pages.dart'; | ||
5 | +import 'services/auth_service.dart'; | ||
6 | + | ||
4 | void main() { | 7 | void main() { |
5 | runApp( | 8 | runApp( |
6 | - GetMaterialApp( | ||
7 | - home: Home(), | 9 | + GetMaterialApp.router( |
10 | + title: "Application", | ||
11 | + initialBinding: BindingsBuilder( | ||
12 | + () { | ||
13 | + Get.put(AuthService()); | ||
14 | + }, | ||
15 | + ), | ||
16 | + getPages: AppPages.routes, | ||
17 | + // routeInformationParser: GetInformationParser( | ||
18 | + // // initialRoute: Routes.HOME, | ||
19 | + // ), | ||
20 | + // routerDelegate: GetDelegate( | ||
21 | + // backButtonPopMode: PopMode.History, | ||
22 | + // preventDuplicateHandlingMode: | ||
23 | + // PreventDuplicateHandlingMode.ReorderRoutes, | ||
24 | + // ), | ||
8 | ), | 25 | ), |
9 | ); | 26 | ); |
10 | } | 27 | } |
11 | - | ||
12 | -class Controller extends GetxController { | ||
13 | - final count = 0.reactive; | ||
14 | - void increment() { | ||
15 | - count.value++; | ||
16 | - update(); | ||
17 | - } | ||
18 | -} | ||
19 | - | ||
20 | -class Home extends ObxStatelessWidget { | ||
21 | - const Home({Key? key}) : super(key: key); | ||
22 | - @override | ||
23 | - Widget build(BuildContext context) { | ||
24 | - final controller = Get.put(Controller()); | ||
25 | - return Scaffold( | ||
26 | - appBar: AppBar(title: Text("counter")), | ||
27 | - body: Center( | ||
28 | - child: Column( | ||
29 | - mainAxisAlignment: MainAxisAlignment.center, | ||
30 | - children: [ | ||
31 | - Observer(builder: (context) { | ||
32 | - print('builder'); | ||
33 | - return Text( | ||
34 | - '${controller.count.value}', | ||
35 | - style: TextStyle(fontSize: 30), | ||
36 | - ); | ||
37 | - }), | ||
38 | - // ElevatedButton( | ||
39 | - // child: Text('Next Route'), | ||
40 | - // onPressed: () { | ||
41 | - // Get.to(() => Second()); | ||
42 | - // }, | ||
43 | - // ), | ||
44 | - ], | ||
45 | - ), | ||
46 | - ), | ||
47 | - floatingActionButton: FloatingActionButton( | ||
48 | - child: Icon(Icons.add), | ||
49 | - onPressed: controller.increment, | ||
50 | - ), | ||
51 | - ); | ||
52 | - } | ||
53 | -} |
@@ -96,6 +96,7 @@ extension MapExtension<K, V> on Map<K, V> { | @@ -96,6 +96,7 @@ extension MapExtension<K, V> on Map<K, V> { | ||
96 | final map = (this as RxMap); | 96 | final map = (this as RxMap); |
97 | if (map.value == val) return; | 97 | if (map.value == val) return; |
98 | map.value = val; | 98 | map.value = val; |
99 | + // ignore: invalid_use_of_protected_member | ||
99 | map.refresh(); | 100 | map.refresh(); |
100 | } else { | 101 | } else { |
101 | if (this == val) return; | 102 | if (this == val) return; |
@@ -4,10 +4,8 @@ import 'dart:async'; | @@ -4,10 +4,8 @@ import 'dart:async'; | ||
4 | import 'dart:collection'; | 4 | import 'dart:collection'; |
5 | 5 | ||
6 | import 'package:flutter/foundation.dart'; | 6 | import 'package:flutter/foundation.dart'; |
7 | -import 'package:get/get_state_manager/src/rx_flutter/rx_notifier.dart'; | ||
8 | -import 'package:get/get_state_manager/src/simple/list_notifier.dart'; | ||
9 | 7 | ||
10 | -import '../rx_stream/rx_stream.dart'; | 8 | +import '../../../get_state_manager/src/rx_flutter/rx_notifier.dart'; |
11 | import '../rx_typedefs/rx_typedefs.dart'; | 9 | import '../rx_typedefs/rx_typedefs.dart'; |
12 | 10 | ||
13 | part 'rx_core/rx_impl.dart'; | 11 | part 'rx_core/rx_impl.dart'; |
@@ -8,13 +8,14 @@ import '../../get_state_manager.dart'; | @@ -8,13 +8,14 @@ import '../../get_state_manager.dart'; | ||
8 | import '../simple/list_notifier.dart'; | 8 | import '../simple/list_notifier.dart'; |
9 | 9 | ||
10 | extension _NullOrEmpty on Object { | 10 | extension _NullOrEmpty on Object { |
11 | - bool _isNullOrEmpty(dynamic val) { | ||
12 | - if (val == null) return true; | 11 | + bool _isEmpty() { |
12 | + final val = this; | ||
13 | + // if (val == null) return true; | ||
13 | var result = false; | 14 | var result = false; |
14 | if (val is Iterable) { | 15 | if (val is Iterable) { |
15 | result = val.isEmpty; | 16 | result = val.isEmpty; |
16 | } else if (val is String) { | 17 | } else if (val is String) { |
17 | - result = val.isEmpty; | 18 | + result = val.trim().isEmpty; |
18 | } else if (val is Map) { | 19 | } else if (val is Map) { |
19 | result = val.isEmpty; | 20 | result = val.isEmpty; |
20 | } | 21 | } |
@@ -24,15 +25,17 @@ extension _NullOrEmpty on Object { | @@ -24,15 +25,17 @@ extension _NullOrEmpty on Object { | ||
24 | 25 | ||
25 | mixin StateMixin<T> on ListNotifier { | 26 | mixin StateMixin<T> on ListNotifier { |
26 | late T _value; | 27 | late T _value; |
27 | - RxStatus? _status; | 28 | + GetState? _status; |
28 | 29 | ||
29 | void _fillEmptyStatus() { | 30 | void _fillEmptyStatus() { |
30 | - _status = _isNullOrEmpty(_value) ? RxStatus.loading() : RxStatus.success(); | 31 | + _status = (value == null || value!._isEmpty()) |
32 | + ? GetState.loading() | ||
33 | + : GetState.success(_status); | ||
31 | } | 34 | } |
32 | 35 | ||
33 | - RxStatus get status { | 36 | + GetState get status { |
34 | reportRead(); | 37 | reportRead(); |
35 | - return _status ??= _status = RxStatus.loading(); | 38 | + return _status ??= _status = GetState.loading(); |
36 | } | 39 | } |
37 | 40 | ||
38 | T get state => value; | 41 | T get state => value; |
@@ -51,7 +54,7 @@ mixin StateMixin<T> on ListNotifier { | @@ -51,7 +54,7 @@ mixin StateMixin<T> on ListNotifier { | ||
51 | } | 54 | } |
52 | 55 | ||
53 | @protected | 56 | @protected |
54 | - void change(T newState, {RxStatus? status}) { | 57 | + void change(T newState, {GetState? status}) { |
55 | var _canUpdate = false; | 58 | var _canUpdate = false; |
56 | if (status != null) { | 59 | if (status != null) { |
57 | _status = status; | 60 | _status = status; |
@@ -66,12 +69,17 @@ mixin StateMixin<T> on ListNotifier { | @@ -66,12 +69,17 @@ mixin StateMixin<T> on ListNotifier { | ||
66 | } | 69 | } |
67 | } | 70 | } |
68 | 71 | ||
69 | - void append(Future<T> Function() body(), {String? errorMessage}) { | 72 | + void listenFuture(Future<T> Function() body(), |
73 | + {String? errorMessage, bool useEmpty = true}) { | ||
70 | final compute = body(); | 74 | final compute = body(); |
71 | compute().then((newValue) { | 75 | compute().then((newValue) { |
72 | - change(newValue, status: RxStatus.success()); | 76 | + if ((newValue == null || newValue._isEmpty()) && useEmpty) { |
77 | + change(newValue, status: GetState.loading()); | ||
78 | + } else { | ||
79 | + change(newValue, status: GetState.success(newValue)); | ||
80 | + } | ||
73 | }, onError: (err) { | 81 | }, onError: (err) { |
74 | - change(state, status: RxStatus.error(errorMessage ?? err.toString())); | 82 | + change(state, status: GetState.error(errorMessage ?? err.toString())); |
75 | }); | 83 | }); |
76 | } | 84 | } |
77 | } | 85 | } |
@@ -186,10 +194,6 @@ class Value<T> extends ListNotifier | @@ -186,10 +194,6 @@ class Value<T> extends ListNotifier | ||
186 | dynamic toJson() => (value as dynamic)?.toJson(); | 194 | dynamic toJson() => (value as dynamic)?.toJson(); |
187 | } | 195 | } |
188 | 196 | ||
189 | -extension ReactiveT<T> on T { | ||
190 | - Value<T> get reactive => Value<T>(this); | ||
191 | -} | ||
192 | - | ||
193 | abstract class GetNotifier<T> extends Value<T> with GetLifeCycleMixin { | 197 | abstract class GetNotifier<T> extends Value<T> with GetLifeCycleMixin { |
194 | GetNotifier(T initial) : super(initial); | 198 | GetNotifier(T initial) : super(initial); |
195 | } | 199 | } |
@@ -218,70 +222,32 @@ extension StateExt<T> on StateMixin<T> { | @@ -218,70 +222,32 @@ extension StateExt<T> on StateMixin<T> { | ||
218 | } | 222 | } |
219 | } | 223 | } |
220 | 224 | ||
221 | -class RxStatus { | ||
222 | - final bool isLoading; | ||
223 | - final bool isError; | ||
224 | - final bool isSuccess; | ||
225 | - final bool isEmpty; | ||
226 | - final bool isLoadingMore; | ||
227 | - final String? errorMessage; | ||
228 | - | ||
229 | - RxStatus._({ | ||
230 | - this.isEmpty = false, | ||
231 | - this.isLoading = false, | ||
232 | - this.isError = false, | ||
233 | - this.isSuccess = false, | ||
234 | - this.errorMessage, | ||
235 | - this.isLoadingMore = false, | ||
236 | - }); | ||
237 | - | ||
238 | - factory RxStatus.loading() { | ||
239 | - return RxStatus._(isLoading: true); | ||
240 | - } | ||
241 | - | ||
242 | - factory RxStatus.loadingMore() { | ||
243 | - return RxStatus._(isSuccess: true, isLoadingMore: true); | ||
244 | - } | ||
245 | - | ||
246 | - factory RxStatus.success() { | ||
247 | - return RxStatus._(isSuccess: true); | ||
248 | - } | ||
249 | - | ||
250 | - factory RxStatus.error([String? message]) { | ||
251 | - return RxStatus._(isError: true, errorMessage: message); | ||
252 | - } | ||
253 | - | ||
254 | - factory RxStatus.empty() { | ||
255 | - return RxStatus._(isEmpty: true); | ||
256 | - } | ||
257 | -} | ||
258 | - | ||
259 | typedef NotifierBuilder<T> = Widget Function(T state); | 225 | typedef NotifierBuilder<T> = Widget Function(T state); |
260 | 226 | ||
261 | -abstract class GState<T> { | ||
262 | - const GState(); | ||
263 | - factory GState.loading() => GLoading(); | ||
264 | - factory GState.error(String message) => GError(message); | ||
265 | - factory GState.empty() => GEmpty(); | ||
266 | - factory GState.success(T data) => GSuccess(data); | 227 | +abstract class GetState<T> { |
228 | + const GetState(); | ||
229 | + factory GetState.loading() => GLoading(); | ||
230 | + factory GetState.error(String message) => GError(message); | ||
231 | + factory GetState.empty() => GEmpty(); | ||
232 | + factory GetState.success(T data) => GSuccess(data); | ||
267 | } | 233 | } |
268 | 234 | ||
269 | -class GLoading<T> extends GState<T> {} | 235 | +class GLoading<T> extends GetState<T> {} |
270 | 236 | ||
271 | -class GSuccess<T> extends GState<T> { | 237 | +class GSuccess<T> extends GetState<T> { |
272 | final T data; | 238 | final T data; |
273 | 239 | ||
274 | GSuccess(this.data); | 240 | GSuccess(this.data); |
275 | } | 241 | } |
276 | 242 | ||
277 | -class GError<T, S> extends GState<T> { | 243 | +class GError<T, S> extends GetState<T> { |
278 | final S? error; | 244 | final S? error; |
279 | GError([this.error]); | 245 | GError([this.error]); |
280 | } | 246 | } |
281 | 247 | ||
282 | -class GEmpty<T> extends GState<T> {} | 248 | +class GEmpty<T> extends GetState<T> {} |
283 | 249 | ||
284 | -extension StatusDataExt<T> on GState<T> { | 250 | +extension StatusDataExt<T> on GetState<T> { |
285 | bool get isLoading => this is GLoading; | 251 | bool get isLoading => this is GLoading; |
286 | bool get isSuccess => this is GSuccess; | 252 | bool get isSuccess => this is GSuccess; |
287 | bool get isError => this is GError; | 253 | bool get isError => this is GError; |
@@ -72,6 +72,8 @@ mixin ScrollMixin on GetLifeCycleMixin { | @@ -72,6 +72,8 @@ mixin ScrollMixin on GetLifeCycleMixin { | ||
72 | 72 | ||
73 | abstract class RxController with GetLifeCycleMixin {} | 73 | abstract class RxController with GetLifeCycleMixin {} |
74 | 74 | ||
75 | +abstract class StateController<T> extends GetxController with StateMixin<T> {} | ||
76 | + | ||
75 | abstract class SuperController<T> extends FullLifeCycleController | 77 | abstract class SuperController<T> extends FullLifeCycleController |
76 | with FullLifeCycleMixin, StateMixin<T> {} | 78 | with FullLifeCycleMixin, StateMixin<T> {} |
77 | 79 |
@@ -176,7 +176,9 @@ class TaskManager { | @@ -176,7 +176,9 @@ class TaskManager { | ||
176 | T Function() builder) { | 176 | T Function() builder) { |
177 | _remove = disposers; | 177 | _remove = disposers; |
178 | _setter = setState; | 178 | _setter = setState; |
179 | + | ||
179 | final result = builder(); | 180 | final result = builder(); |
181 | + print(disposers.isEmpty); | ||
180 | if (disposers.isEmpty) { | 182 | if (disposers.isEmpty) { |
181 | throw ObxError(); | 183 | throw ObxError(); |
182 | } | 184 | } |
-
Please register or login to post a comment