Jonny Borges
Committed by GitHub

Merge branch 'master' into master

Showing 35 changed files with 533 additions and 285 deletions
No preview for this file type
1 import 'package:get/get.dart'; 1 import 'package:get/get.dart';
  2 +
2 import '../domain/entity/cases_model.dart'; 3 import '../domain/entity/cases_model.dart';
3 4
4 // ignore: one_member_abstracts 5 // ignore: one_member_abstracts
@@ -12,6 +13,7 @@ class HomeProvider extends GetConnect implements IHomeProvider { @@ -12,6 +13,7 @@ class HomeProvider extends GetConnect implements IHomeProvider {
12 httpClient.defaultDecoder = 13 httpClient.defaultDecoder =
13 (val) => CasesModel.fromJson(val as Map<String, dynamic>); 14 (val) => CasesModel.fromJson(val as Map<String, dynamic>);
14 httpClient.baseUrl = 'https://api.covid19api.com'; 15 httpClient.baseUrl = 'https://api.covid19api.com';
  16 + super.onInit();
15 } 17 }
16 18
17 @override 19 @override
@@ -19,10 +19,10 @@ class HomeController extends SuperController<CasesModel> { @@ -19,10 +19,10 @@ class HomeController extends SuperController<CasesModel> {
19 Country getCountryById(String id) { 19 Country getCountryById(String id) {
20 final index = int.tryParse(id); 20 final index = int.tryParse(id);
21 if (index != null) { 21 if (index != null) {
22 - return state!.countries[index]; 22 + return state.countries[index];
23 } 23 }
24 24
25 - return state!.countries.first; 25 + return state.countries.first;
26 } 26 }
27 27
28 @override 28 @override
@@ -28,9 +28,9 @@ class CountryView extends GetView<HomeController> { @@ -28,9 +28,9 @@ class CountryView extends GetView<HomeController> {
28 ), 28 ),
29 body: Center( 29 body: Center(
30 child: ListView.builder( 30 child: ListView.builder(
31 - itemCount: controller.state!.countries.length, 31 + itemCount: controller.state.countries.length,
32 itemBuilder: (context, index) { 32 itemBuilder: (context, index) {
33 - final country = controller.state!.countries[index]; 33 + final country = controller.state.countries[index];
34 return ListTile( 34 return ListTile(
35 onTap: () { 35 onTap: () {
36 //Get.rootDelegate.toNamed('/home/country'); 36 //Get.rootDelegate.toNamed('/home/country');
1 import 'dart:io'; 1 import 'dart:io';
2 import 'dart:math'; 2 import 'dart:math';
  3 +
3 import 'package:flutter/material.dart'; 4 import 'package:flutter/material.dart';
4 import 'package:flutter_test/flutter_test.dart'; 5 import 'package:flutter_test/flutter_test.dart';
5 import 'package:get/get.dart'; 6 import 'package:get/get.dart';
@@ -81,8 +82,8 @@ void main() { @@ -81,8 +82,8 @@ void main() {
81 } 82 }
82 83
83 if (controller.status.isSuccess) { 84 if (controller.status.isSuccess) {
84 - expect(controller.state!.global.totalDeaths, 100);  
85 - expect(controller.state!.global.totalConfirmed, 200); 85 + expect(controller.state.global.totalDeaths, 100);
  86 + expect(controller.state.global.totalConfirmed, 200);
86 } 87 }
87 }); 88 });
88 89
@@ -100,9 +100,7 @@ class GetConnect extends GetConnectInterface { @@ -100,9 +100,7 @@ class GetConnect extends GetConnectInterface {
100 this.maxAuthRetries = 1, 100 this.maxAuthRetries = 1,
101 this.allowAutoSignedCert = false, 101 this.allowAutoSignedCert = false,
102 this.withCredentials = false, 102 this.withCredentials = false,
103 - }) {  
104 - $configureLifeCycle();  
105 - } 103 + });
106 104
107 bool allowAutoSignedCert; 105 bool allowAutoSignedCert;
108 String userAgent; 106 String userAgent;
@@ -28,6 +28,7 @@ class GetHttpClient { @@ -28,6 +28,7 @@ class GetHttpClient {
28 int maxAuthRetries; 28 int maxAuthRetries;
29 29
30 bool sendUserAgent; 30 bool sendUserAgent;
  31 + bool sendContentLength;
31 32
32 Decoder? defaultDecoder; 33 Decoder? defaultDecoder;
33 34
@@ -47,6 +48,7 @@ class GetHttpClient { @@ -47,6 +48,7 @@ class GetHttpClient {
47 this.followRedirects = true, 48 this.followRedirects = true,
48 this.maxRedirects = 5, 49 this.maxRedirects = 5,
49 this.sendUserAgent = false, 50 this.sendUserAgent = false,
  51 + this.sendContentLength = true,
50 this.maxAuthRetries = 1, 52 this.maxAuthRetries = 1,
51 bool allowAutoSignedCert = false, 53 bool allowAutoSignedCert = false,
52 this.baseUrl, 54 this.baseUrl,
@@ -111,7 +113,7 @@ class GetHttpClient { @@ -111,7 +113,7 @@ class GetHttpClient {
111 113
112 if (body is FormData) { 114 if (body is FormData) {
113 bodyBytes = await body.toBytes(); 115 bodyBytes = await body.toBytes();
114 - headers['content-length'] = bodyBytes.length.toString(); 116 + _setContentLenght(headers, bodyBytes.length);
115 headers['content-type'] = 117 headers['content-type'] =
116 'multipart/form-data; boundary=${body.boundary}'; 118 'multipart/form-data; boundary=${body.boundary}';
117 } else if (contentType != null && 119 } else if (contentType != null &&
@@ -124,21 +126,21 @@ class GetHttpClient { @@ -124,21 +126,21 @@ class GetHttpClient {
124 }); 126 });
125 var formData = parts.join('&'); 127 var formData = parts.join('&');
126 bodyBytes = utf8.encode(formData); 128 bodyBytes = utf8.encode(formData);
127 - headers['content-length'] = bodyBytes.length.toString(); 129 + _setContentLenght(headers, bodyBytes.length);
128 headers['content-type'] = contentType; 130 headers['content-type'] = contentType;
129 } else if (body is Map || body is List) { 131 } else if (body is Map || body is List) {
130 var jsonString = json.encode(body); 132 var jsonString = json.encode(body);
131 -  
132 bodyBytes = utf8.encode(jsonString); 133 bodyBytes = utf8.encode(jsonString);
133 - headers['content-length'] = bodyBytes.length.toString(); 134 + _setContentLenght(headers, bodyBytes.length);
134 headers['content-type'] = contentType ?? defaultContentType; 135 headers['content-type'] = contentType ?? defaultContentType;
135 } else if (body is String) { 136 } else if (body is String) {
136 bodyBytes = utf8.encode(body); 137 bodyBytes = utf8.encode(body);
137 - headers['content-length'] = bodyBytes.length.toString(); 138 + _setContentLenght(headers, bodyBytes.length);
  139 +
138 headers['content-type'] = contentType ?? defaultContentType; 140 headers['content-type'] = contentType ?? defaultContentType;
139 } else if (body == null) { 141 } else if (body == null) {
  142 + _setContentLenght(headers, 0);
140 headers['content-type'] = contentType ?? defaultContentType; 143 headers['content-type'] = contentType ?? defaultContentType;
141 - headers['content-length'] = '0';  
142 } else { 144 } else {
143 if (!errorSafety) { 145 if (!errorSafety) {
144 throw UnexpectedFormat('body cannot be ${body.runtimeType}'); 146 throw UnexpectedFormat('body cannot be ${body.runtimeType}');
@@ -162,6 +164,12 @@ class GetHttpClient { @@ -162,6 +164,12 @@ class GetHttpClient {
162 ); 164 );
163 } 165 }
164 166
  167 + void _setContentLenght(Map<String, String> headers, int contentLength) {
  168 + if (sendContentLength) {
  169 + headers['content-length'] = '$contentLength';
  170 + }
  171 + }
  172 +
165 Stream<List<int>> _trackProgress( 173 Stream<List<int>> _trackProgress(
166 List<int> bodyBytes, 174 List<int> bodyBytes,
167 Progress? uploadProgress, 175 Progress? uploadProgress,
@@ -110,11 +110,12 @@ class BaseWebSocket { @@ -110,11 +110,12 @@ class BaseWebSocket {
110 return true; 110 return true;
111 }; 111 };
112 112
113 - var request = await client.getUrl(Uri.parse(url));  
114 - request.headers.add('Connection', 'Upgrade');  
115 - request.headers.add('Upgrade', 'websocket');  
116 - request.headers.add('Sec-WebSocket-Version', '13');  
117 - request.headers.add('Sec-WebSocket-Key', key.toLowerCase()); 113 + var request = await client.getUrl(Uri.parse(url))
  114 + ..headers.add('Connection', 'Upgrade')
  115 + ..headers.add('Upgrade', 'websocket')
  116 + ..headers.add('Cache-Control', 'no-cache')
  117 + ..headers.add('Sec-WebSocket-Version', '13')
  118 + ..headers.add('Sec-WebSocket-Key', key.toLowerCase());
118 119
119 var response = await request.close(); 120 var response = await request.close();
120 // ignore: close_sinks 121 // ignore: close_sinks
@@ -205,7 +205,8 @@ class GetInstance { @@ -205,7 +205,8 @@ class GetInstance {
205 if (_singl[key]!.isSingleton!) { 205 if (_singl[key]!.isSingleton!) {
206 _singl[key]!.isInit = true; 206 _singl[key]!.isInit = true;
207 if (Get.smartManagement != SmartManagement.onlyBuilder) { 207 if (Get.smartManagement != SmartManagement.onlyBuilder) {
208 - RouterReportManager.reportDependencyLinkedToRoute(_getKey(S, name)); 208 + RouterReportManager.instance
  209 + .reportDependencyLinkedToRoute(_getKey(S, name));
209 } 210 }
210 } 211 }
211 } 212 }
@@ -257,7 +258,7 @@ class GetInstance { @@ -257,7 +258,7 @@ class GetInstance {
257 Get.log('Instance "$S" with tag "$tag" has been initialized'); 258 Get.log('Instance "$S" with tag "$tag" has been initialized');
258 } 259 }
259 if (!_singl[key]!.isSingleton!) { 260 if (!_singl[key]!.isSingleton!) {
260 - RouterReportManager.appendRouteByCreate(i); 261 + RouterReportManager.instance.appendRouteByCreate(i);
261 } 262 }
262 } 263 }
263 return i; 264 return i;
@@ -323,7 +324,7 @@ class GetInstance { @@ -323,7 +324,7 @@ class GetInstance {
323 {@deprecated bool clearFactory = true, bool clearRouteBindings = true}) { 324 {@deprecated bool clearFactory = true, bool clearRouteBindings = true}) {
324 // if (clearFactory) _factory.clear(); 325 // if (clearFactory) _factory.clear();
325 // deleteAll(force: true); 326 // deleteAll(force: true);
326 - if (clearRouteBindings) RouterReportManager.clearRouteKeys(); 327 + if (clearRouteBindings) RouterReportManager.instance.clearRouteKeys();
327 _singl.clear(); 328 _singl.clear();
328 329
329 return true; 330 return true;
1 -import '../../get_core/get_core.dart';  
2 -  
3 -/// Special callable class to keep the contract of a regular method, and avoid  
4 -/// overrides if you extend the class that uses it, as Dart has no final  
5 -/// methods.  
6 -/// Used in `DisposableInterface` to avoid the danger of overriding onStart.  
7 -class InternalFinalCallback<T> {  
8 - ValueUpdater<T>? _callback;  
9 -  
10 - InternalFinalCallback({ValueUpdater<T>? callback}) : _callback = callback;  
11 -  
12 - T call() => _callback!.call();  
13 -} 1 +import 'package:flutter/foundation.dart';
  2 +import 'package:flutter/scheduler.dart';
14 3
15 /// The [GetLifeCycle] 4 /// The [GetLifeCycle]
16 /// 5 ///
@@ -22,24 +11,10 @@ class InternalFinalCallback<T> { @@ -22,24 +11,10 @@ class InternalFinalCallback<T> {
22 /// } 11 /// }
23 /// ``` 12 /// ```
24 mixin GetLifeCycleBase { 13 mixin GetLifeCycleBase {
25 - /// Called at the exact moment the widget is allocated in memory.  
26 - /// It uses an internal "callable" type, to avoid any @overrides in subclases.  
27 - /// This method should be internal and is required to define the  
28 - /// lifetime cycle of the subclass.  
29 - final onStart = InternalFinalCallback<void>();  
30 -  
31 - // /// The `configureLifeCycle` works as a constructor for the [GetLifeCycle]  
32 - // ///  
33 - // /// This method must be invoked in the constructor of the implementation  
34 - // void configureLifeCycle() {  
35 - // if (_initialized) return;  
36 - // }  
37 -  
38 - /// Internal callback that starts the cycle of this controller.  
39 - final onDelete = InternalFinalCallback<void>();  
40 -  
41 /// Called immediately after the widget is allocated in memory. 14 /// Called immediately after the widget is allocated in memory.
42 /// You might use this to initialize something for the controller. 15 /// You might use this to initialize something for the controller.
  16 + @protected
  17 + @mustCallSuper
43 void onInit() {} 18 void onInit() {}
44 19
45 /// Called 1 frame after onInit(). It is the perfect place to enter 20 /// Called 1 frame after onInit(). It is the perfect place to enter
@@ -60,8 +35,14 @@ mixin GetLifeCycleBase { @@ -60,8 +35,14 @@ mixin GetLifeCycleBase {
60 /// Checks whether the controller has already been initialized. 35 /// Checks whether the controller has already been initialized.
61 bool get initialized => _initialized; 36 bool get initialized => _initialized;
62 37
63 - // Internal callback that starts the cycle of this controller.  
64 - void _onStart() { 38 + /// Called at the exact moment the widget is allocated in memory.
  39 + /// It uses an internal "callable" type, to avoid any @overrides in subclases.
  40 + /// This method should be internal and is required to define the
  41 + /// lifetime cycle of the subclass.
  42 + // @protected
  43 + @mustCallSuper
  44 + void onStart() {
  45 + // _checkIfAlreadyConfigured();
65 if (_initialized) return; 46 if (_initialized) return;
66 onInit(); 47 onInit();
67 _initialized = true; 48 _initialized = true;
@@ -72,31 +53,28 @@ mixin GetLifeCycleBase { @@ -72,31 +53,28 @@ mixin GetLifeCycleBase {
72 /// Checks whether the controller has already been closed. 53 /// Checks whether the controller has already been closed.
73 bool get isClosed => _isClosed; 54 bool get isClosed => _isClosed;
74 55
75 - // Internal callback that starts the cycle of this controller.  
76 - void _onDelete() { 56 + // Called when the controller is removed from memory.
  57 + @mustCallSuper
  58 + void onDelete() {
77 if (_isClosed) return; 59 if (_isClosed) return;
78 _isClosed = true; 60 _isClosed = true;
79 onClose(); 61 onClose();
80 } 62 }
81 63
82 - void $configureLifeCycle() {  
83 - _checkIfAlreadyConfigured();  
84 - onStart._callback = _onStart;  
85 - onDelete._callback = _onDelete;  
86 - }  
87 -  
88 - void _checkIfAlreadyConfigured() {  
89 - if (_initialized) {  
90 - throw """You can only call configureLifeCycle once.  
91 -The proper place to insert it is in your class's constructor  
92 -that inherits GetLifeCycle.""";  
93 - }  
94 - } 64 +// void _checkIfAlreadyConfigured() {
  65 +// if (_initialized) {
  66 +// throw """You can only call configureLifeCycle once.
  67 +// The proper place to insert it is in your class's constructor
  68 +// that inherits GetLifeCycle.""";
  69 +// }
  70 +// }
95 } 71 }
96 72
97 abstract class GetLifeCycle with GetLifeCycleBase { 73 abstract class GetLifeCycle with GetLifeCycleBase {
98 - GetLifeCycle() {  
99 - $configureLifeCycle(); 74 + @override
  75 + void onInit() {
  76 + SchedulerBinding.instance?.addPostFrameCallback((_) => onReady());
  77 + super.onInit();
100 } 78 }
101 } 79 }
102 80
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
  2 +
2 import '../../../get.dart'; 3 import '../../../get.dart';
3 import '../router_report.dart'; 4 import '../router_report.dart';
4 5
@@ -21,7 +22,7 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> { @@ -21,7 +22,7 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> {
21 this.enterBottomSheetDuration = const Duration(milliseconds: 250), 22 this.enterBottomSheetDuration = const Duration(milliseconds: 250),
22 this.exitBottomSheetDuration = const Duration(milliseconds: 200), 23 this.exitBottomSheetDuration = const Duration(milliseconds: 200),
23 }) : super(settings: settings) { 24 }) : super(settings: settings) {
24 - RouterReportManager.reportCurrentRoute(this); 25 + RouterReportManager.instance.reportCurrentRoute(this);
25 } 26 }
26 final bool? isPersistent; 27 final bool? isPersistent;
27 final WidgetBuilder? builder; 28 final WidgetBuilder? builder;
@@ -56,7 +57,7 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> { @@ -56,7 +57,7 @@ class GetModalBottomSheetRoute<T> extends PopupRoute<T> {
56 57
57 @override 58 @override
58 void dispose() { 59 void dispose() {
59 - RouterReportManager.reportRouteDispose(this); 60 + RouterReportManager.instance.reportRouteDispose(this);
60 super.dispose(); 61 super.dispose();
61 } 62 }
62 63
1 import 'package:flutter/widgets.dart'; 1 import 'package:flutter/widgets.dart';
  2 +
2 import '../router_report.dart'; 3 import '../router_report.dart';
3 4
4 class GetDialogRoute<T> extends PopupRoute<T> { 5 class GetDialogRoute<T> extends PopupRoute<T> {
@@ -17,7 +18,7 @@ class GetDialogRoute<T> extends PopupRoute<T> { @@ -17,7 +18,7 @@ class GetDialogRoute<T> extends PopupRoute<T> {
17 _transitionDuration = transitionDuration, 18 _transitionDuration = transitionDuration,
18 _transitionBuilder = transitionBuilder, 19 _transitionBuilder = transitionBuilder,
19 super(settings: settings) { 20 super(settings: settings) {
20 - RouterReportManager.reportCurrentRoute(this); 21 + RouterReportManager.instance.reportCurrentRoute(this);
21 } 22 }
22 23
23 final RoutePageBuilder widget; 24 final RoutePageBuilder widget;
@@ -28,7 +29,7 @@ class GetDialogRoute<T> extends PopupRoute<T> { @@ -28,7 +29,7 @@ class GetDialogRoute<T> extends PopupRoute<T> {
28 29
29 @override 30 @override
30 void dispose() { 31 void dispose() {
31 - RouterReportManager.reportRouteDispose(this); 32 + RouterReportManager.instance.reportRouteDispose(this);
32 super.dispose(); 33 super.dispose();
33 } 34 }
34 35
@@ -511,6 +511,7 @@ extension GetNavigation on GetInterface { @@ -511,6 +511,7 @@ extension GetNavigation on GetInterface {
511 Bindings? binding, 511 Bindings? binding,
512 bool preventDuplicates = true, 512 bool preventDuplicates = true,
513 bool? popGesture, 513 bool? popGesture,
  514 + bool showCupertinoParallax = true,
514 double Function(BuildContext context)? gestureWidth, 515 double Function(BuildContext context)? gestureWidth,
515 }) { 516 }) {
516 // var routeName = "/${page.runtimeType}"; 517 // var routeName = "/${page.runtimeType}";
@@ -525,6 +526,7 @@ extension GetNavigation on GetInterface { @@ -525,6 +526,7 @@ extension GetNavigation on GetInterface {
525 page: _resolvePage(page, 'to'), 526 page: _resolvePage(page, 'to'),
526 routeName: routeName, 527 routeName: routeName,
527 gestureWidth: gestureWidth, 528 gestureWidth: gestureWidth,
  529 + showCupertinoParallax: showCupertinoParallax,
528 settings: RouteSettings( 530 settings: RouteSettings(
529 name: routeName, 531 name: routeName,
530 arguments: arguments, 532 arguments: arguments,
@@ -7,28 +7,30 @@ import '../../get.dart'; @@ -7,28 +7,30 @@ import '../../get.dart';
7 class RouterReportManager<T> { 7 class RouterReportManager<T> {
8 /// Holds a reference to `Get.reference` when the Instance was 8 /// Holds a reference to `Get.reference` when the Instance was
9 /// created to manage the memory. 9 /// created to manage the memory.
10 - static final Map<Route?, List<String>> _routesKey = {}; 10 + final Map<T?, List<String>> _routesKey = {};
11 11
12 /// Stores the onClose() references of instances created with `Get.create()` 12 /// Stores the onClose() references of instances created with `Get.create()`
13 /// using the `Get.reference`. 13 /// using the `Get.reference`.
14 /// Experimental feature to keep the lifecycle and memory management with 14 /// Experimental feature to keep the lifecycle and memory management with
15 /// non-singleton instances. 15 /// non-singleton instances.
16 - static final Map<Route?, HashSet<Function>> _routesByCreate = {}; 16 + final Map<T?, HashSet<Function>> _routesByCreate = {};
  17 +
  18 + static late final RouterReportManager instance = RouterReportManager();
17 19
18 void printInstanceStack() { 20 void printInstanceStack() {
19 Get.log(_routesKey.toString()); 21 Get.log(_routesKey.toString());
20 } 22 }
21 23
22 - static Route? _current; 24 + T? _current;
23 25
24 // ignore: use_setters_to_change_properties 26 // ignore: use_setters_to_change_properties
25 - static void reportCurrentRoute(Route newRoute) { 27 + void reportCurrentRoute(T newRoute) {
26 _current = newRoute; 28 _current = newRoute;
27 } 29 }
28 30
29 /// Links a Class instance [S] (or [tag]) to the current route. 31 /// Links a Class instance [S] (or [tag]) to the current route.
30 /// Requires usage of `GetMaterialApp`. 32 /// Requires usage of `GetMaterialApp`.
31 - static void reportDependencyLinkedToRoute(String depedencyKey) { 33 + void reportDependencyLinkedToRoute(String depedencyKey) {
32 if (_current == null) return; 34 if (_current == null) return;
33 if (_routesKey.containsKey(_current)) { 35 if (_routesKey.containsKey(_current)) {
34 _routesKey[_current!]!.add(depedencyKey); 36 _routesKey[_current!]!.add(depedencyKey);
@@ -37,18 +39,18 @@ class RouterReportManager<T> { @@ -37,18 +39,18 @@ class RouterReportManager<T> {
37 } 39 }
38 } 40 }
39 41
40 - static void clearRouteKeys() { 42 + void clearRouteKeys() {
41 _routesKey.clear(); 43 _routesKey.clear();
42 _routesByCreate.clear(); 44 _routesByCreate.clear();
43 } 45 }
44 46
45 - static void appendRouteByCreate(GetLifeCycleBase i) { 47 + void appendRouteByCreate(GetLifeCycleBase i) {
46 _routesByCreate[_current] ??= HashSet<Function>(); 48 _routesByCreate[_current] ??= HashSet<Function>();
47 // _routesByCreate[Get.reference]!.add(i.onDelete as Function); 49 // _routesByCreate[Get.reference]!.add(i.onDelete as Function);
48 _routesByCreate[_current]!.add(i.onDelete); 50 _routesByCreate[_current]!.add(i.onDelete);
49 } 51 }
50 52
51 - static void reportRouteDispose(Route disposed) { 53 + void reportRouteDispose(T disposed) {
52 if (Get.smartManagement != SmartManagement.onlyBuilder) { 54 if (Get.smartManagement != SmartManagement.onlyBuilder) {
53 WidgetsBinding.instance!.addPostFrameCallback((_) { 55 WidgetsBinding.instance!.addPostFrameCallback((_) {
54 _removeDependencyByRoute(disposed); 56 _removeDependencyByRoute(disposed);
@@ -56,7 +58,7 @@ class RouterReportManager<T> { @@ -56,7 +58,7 @@ class RouterReportManager<T> {
56 } 58 }
57 } 59 }
58 60
59 - static void reportRouteWillDispose(Route disposed) { 61 + void reportRouteWillDispose(T disposed) {
60 final keysToRemove = <String>[]; 62 final keysToRemove = <String>[];
61 63
62 _routesKey[disposed]?.forEach(keysToRemove.add); 64 _routesKey[disposed]?.forEach(keysToRemove.add);
@@ -85,7 +87,7 @@ class RouterReportManager<T> { @@ -85,7 +87,7 @@ class RouterReportManager<T> {
85 /// using `Get.smartManagement` as [SmartManagement.full] or 87 /// using `Get.smartManagement` as [SmartManagement.full] or
86 /// [SmartManagement.keepFactory] 88 /// [SmartManagement.keepFactory]
87 /// Meant for internal usage of `GetPageRoute` and `GetDialogRoute` 89 /// Meant for internal usage of `GetPageRoute` and `GetDialogRoute`
88 - static void _removeDependencyByRoute(Route routeName) { 90 + void _removeDependencyByRoute(T routeName) {
89 final keysToRemove = <String>[]; 91 final keysToRemove = <String>[];
90 92
91 _routesKey[routeName]?.forEach(keysToRemove.add); 93 _routesKey[routeName]?.forEach(keysToRemove.add);
@@ -8,18 +8,20 @@ mixin PageRouteReportMixin<T> on Route<T> { @@ -8,18 +8,20 @@ mixin PageRouteReportMixin<T> on Route<T> {
8 @override 8 @override
9 void install() { 9 void install() {
10 super.install(); 10 super.install();
11 - RouterReportManager.reportCurrentRoute(this); 11 + RouterReportManager.instance.reportCurrentRoute(this);
12 } 12 }
13 13
14 @override 14 @override
15 void dispose() { 15 void dispose() {
16 super.dispose(); 16 super.dispose();
17 - RouterReportManager.reportRouteDispose(this); 17 + RouterReportManager.instance.reportRouteDispose(this);
18 } 18 }
19 } 19 }
20 20
21 -class GetPageRoute<T> extends PageRoute<T>  
22 - with GetPageRouteTransitionMixin<T>, PageRouteReportMixin { 21 +class GetPageRoute<T> extends PageRoute<T> //MaterialPageRoute<T>
  22 + with
  23 + GetPageRouteTransitionMixin<T>,
  24 + PageRouteReportMixin {
23 /// Creates a page route for use in an iOS designed app. 25 /// Creates a page route for use in an iOS designed app.
24 /// 26 ///
25 /// The [builder], [maintainState], and [fullscreenDialog] arguments must not 27 /// The [builder], [maintainState], and [fullscreenDialog] arguments must not
@@ -47,7 +49,11 @@ class GetPageRoute<T> extends PageRoute<T> @@ -47,7 +49,11 @@ class GetPageRoute<T> extends PageRoute<T>
47 this.maintainState = true, 49 this.maintainState = true,
48 bool fullscreenDialog = false, 50 bool fullscreenDialog = false,
49 this.middlewares, 51 this.middlewares,
50 - }) : super(settings: settings, fullscreenDialog: fullscreenDialog); 52 + }) : super(
  53 + settings: settings,
  54 + fullscreenDialog: fullscreenDialog,
  55 + // builder: (context) => Container(),
  56 + );
51 57
52 @override 58 @override
53 final Duration transitionDuration; 59 final Duration transitionDuration;
@@ -322,7 +322,6 @@ Cannot read the previousTitle for a route that has not yet been installed''', @@ -322,7 +322,6 @@ Cannot read the previousTitle for a route that has not yet been installed''',
322 bool canTransitionTo(TransitionRoute<dynamic> nextRoute) { 322 bool canTransitionTo(TransitionRoute<dynamic> nextRoute) {
323 // Don't perform outgoing animation if the next route is a 323 // Don't perform outgoing animation if the next route is a
324 // fullscreen dialog. 324 // fullscreen dialog.
325 -  
326 return (nextRoute is GetPageRouteTransitionMixin && 325 return (nextRoute is GetPageRouteTransitionMixin &&
327 !nextRoute.fullscreenDialog && 326 !nextRoute.fullscreenDialog &&
328 nextRoute.showCupertinoParallax) || 327 nextRoute.showCupertinoParallax) ||
  1 +// import 'package:flutter/material.dart';
  2 +// import 'package:get/get_navigation/src/router_report.dart';
  3 +// import 'package:get/instance_manager.dart';
  4 +
  5 +// class Dependencies {
  6 +// void lazyPut<S>(InstanceBuilderCallback<S> builder,
  7 +// {String? tag, bool fenix = false}) {
  8 +// GetInstance().lazyPut<S>(builder, tag: tag, fenix: fenix);
  9 +// }
  10 +
  11 +// S call<S>() {
  12 +// return find<S>();
  13 +// }
  14 +
  15 +// Future<S> putAsync<S>(AsyncInstanceBuilderCallback<S> builder,
  16 +// {String? tag, bool permanent = false}) async =>
  17 +// GetInstance().putAsync<S>(builder, tag: tag, permanent: permanent);
  18 +
  19 +// void create<S>(InstanceBuilderCallback<S> builder,
  20 +// {String? tag, bool permanent = true}) =>
  21 +// GetInstance().create<S>(builder, tag: tag, permanent: permanent);
  22 +
  23 +// S find<S>({String? tag}) => GetInstance().find<S>(tag: tag);
  24 +
  25 +// S put<S>(S dependency,
  26 +// {String? tag,
  27 +// bool permanent = false,
  28 +// InstanceBuilderCallback<S>? builder}) =>
  29 +// GetInstance().put<S>(dependency, tag: tag, permanent: permanent);
  30 +
  31 +// Future<bool> delete<S>({String? tag, bool force = false}) async =>
  32 +// GetInstance().delete<S>(tag: tag, force: force);
  33 +
  34 +// Future<void> deleteAll({bool force = false}) async =>
  35 +// GetInstance().deleteAll(force: force);
  36 +
  37 +// void reloadAll({bool force = false}) => GetInstance().reloadAll(force: force);
  38 +
  39 +// void reload<S>({String? tag, String? key, bool force = false}) =>
  40 +// GetInstance().reload<S>(tag: tag, key: key, force: force);
  41 +
  42 +// bool isRegistered<S>({String? tag}) =>
  43 +// GetInstance().isRegistered<S>(tag: tag);
  44 +
  45 +// bool isPrepared<S>({String? tag}) => GetInstance().isPrepared<S>(tag: tag);
  46 +
  47 +// void replace<P>(P child, {String? tag}) {
  48 +// final info = GetInstance().getInstanceInfo<P>(tag: tag);
  49 +// final permanent = (info.isPermanent ?? false);
  50 +// delete<P>(tag: tag, force: permanent);
  51 +// put(child, tag: tag, permanent: permanent);
  52 +// }
  53 +
  54 +// void lazyReplace<P>(InstanceBuilderCallback<P> builder,
  55 +// {String? tag, bool? fenix}) {
  56 +// final info = GetInstance().getInstanceInfo<P>(tag: tag);
  57 +// final permanent = (info.isPermanent ?? false);
  58 +// delete<P>(tag: tag, force: permanent);
  59 +// lazyPut(builder, tag: tag, fenix: fenix ?? permanent);
  60 +// }
  61 +// }
  62 +
  63 +// abstract class Module extends StatefulWidget {
  64 +// Module({Key? key}) : super(key: key);
  65 +
  66 +// Widget view(BuildContext context);
  67 +
  68 +// void dependencies(Dependencies i);
  69 +
  70 +// @override
  71 +// _ModuleState createState() => _ModuleState();
  72 +// }
  73 +
  74 +// class _ModuleState extends State<Module> {
  75 +// @override
  76 +// void initState() {
  77 +// RouterReportManager.instance.reportCurrentRoute(this);
  78 +// widget.dependencies(Dependencies());
  79 +// super.initState();
  80 +// }
  81 +
  82 +// @override
  83 +// void dispose() {
  84 +// RouterReportManager.instance.reportRouteDispose(this);
  85 +// super.dispose();
  86 +// }
  87 +
  88 +// @override
  89 +// Widget build(BuildContext context) {
  90 +// return widget.view(context);
  91 +// }
  92 +// }
@@ -52,7 +52,7 @@ class GetObserver extends NavigatorObserver { @@ -52,7 +52,7 @@ class GetObserver extends NavigatorObserver {
52 Get.log("CLOSE TO ROUTE ${currentRoute.name}"); 52 Get.log("CLOSE TO ROUTE ${currentRoute.name}");
53 } 53 }
54 if (previousRoute != null) { 54 if (previousRoute != null) {
55 - RouterReportManager.reportCurrentRoute(previousRoute); 55 + RouterReportManager.instance.reportCurrentRoute(previousRoute);
56 } 56 }
57 57
58 // Here we use a 'inverse didPush set', meaning that we use 58 // Here we use a 'inverse didPush set', meaning that we use
@@ -97,7 +97,7 @@ class GetObserver extends NavigatorObserver { @@ -97,7 +97,7 @@ class GetObserver extends NavigatorObserver {
97 Get.log("GOING TO ROUTE ${newRoute.name}"); 97 Get.log("GOING TO ROUTE ${newRoute.name}");
98 } 98 }
99 99
100 - RouterReportManager.reportCurrentRoute(route); 100 + RouterReportManager.instance.reportCurrentRoute(route);
101 _routeSend?.update((value) { 101 _routeSend?.update((value) {
102 // Only PageRoute is allowed to change current value 102 // Only PageRoute is allowed to change current value
103 if (route is PageRoute) { 103 if (route is PageRoute) {
@@ -142,7 +142,7 @@ class GetObserver extends NavigatorObserver { @@ -142,7 +142,7 @@ class GetObserver extends NavigatorObserver {
142 }); 142 });
143 143
144 if (route is GetPageRoute) { 144 if (route is GetPageRoute) {
145 - RouterReportManager.reportRouteWillDispose(route); 145 + RouterReportManager.instance.reportRouteWillDispose(route);
146 } 146 }
147 routing?.call(_routeSend); 147 routing?.call(_routeSend);
148 } 148 }
@@ -158,7 +158,7 @@ class GetObserver extends NavigatorObserver { @@ -158,7 +158,7 @@ class GetObserver extends NavigatorObserver {
158 Get.log("NEW ROUTE $newName"); 158 Get.log("NEW ROUTE $newName");
159 159
160 if (newRoute != null) { 160 if (newRoute != null) {
161 - RouterReportManager.reportCurrentRoute(newRoute); 161 + RouterReportManager.instance.reportCurrentRoute(newRoute);
162 } 162 }
163 163
164 _routeSend?.update((value) { 164 _routeSend?.update((value) {
@@ -178,7 +178,7 @@ class GetObserver extends NavigatorObserver { @@ -178,7 +178,7 @@ class GetObserver extends NavigatorObserver {
178 value.isDialog = currentRoute.isDialog ? false : value.isDialog; 178 value.isDialog = currentRoute.isDialog ? false : value.isDialog;
179 }); 179 });
180 if (oldRoute is GetPageRoute) { 180 if (oldRoute is GetPageRoute) {
181 - RouterReportManager.reportRouteWillDispose(oldRoute); 181 + RouterReportManager.instance.reportRouteWillDispose(oldRoute);
182 } 182 }
183 183
184 routing?.call(_routeSend); 184 routing?.call(_routeSend);
@@ -87,11 +87,19 @@ class SnackbarController { @@ -87,11 +87,19 @@ class SnackbarController {
87 } 87 }
88 } 88 }
89 89
  90 + bool _isTesting = false;
  91 +
90 void _configureOverlay() { 92 void _configureOverlay() {
91 - _overlayState = Overlay.of(Get.overlayContext!); 93 + final overlayContext = Get.overlayContext;
  94 + _isTesting = overlayContext == null;
  95 + _overlayState =
  96 + _isTesting ? OverlayState() : Overlay.of(Get.overlayContext!);
92 _overlayEntries.clear(); 97 _overlayEntries.clear();
93 _overlayEntries.addAll(_createOverlayEntries(_getBodyWidget())); 98 _overlayEntries.addAll(_createOverlayEntries(_getBodyWidget()));
94 - _overlayState!.insertAll(_overlayEntries); 99 + if (!_isTesting) {
  100 + _overlayState!.insertAll(_overlayEntries);
  101 + }
  102 +
95 _configureSnackBarDisplay(); 103 _configureSnackBarDisplay();
96 } 104 }
97 105
@@ -316,8 +324,10 @@ class SnackbarController { @@ -316,8 +324,10 @@ class SnackbarController {
316 } 324 }
317 325
318 void _removeOverlay() { 326 void _removeOverlay() {
319 - for (var element in _overlayEntries) {  
320 - element.remove(); 327 + if (!_isTesting) {
  328 + for (var element in _overlayEntries) {
  329 + element.remove();
  330 + }
321 } 331 }
322 332
323 assert(!_transitionCompleter.isCompleted, 333 assert(!_transitionCompleter.isCompleted,
@@ -14,6 +14,22 @@ class GetStream<T> { @@ -14,6 +14,22 @@ class GetStream<T> {
14 FutureOr<void> Function()? onCancel; 14 FutureOr<void> Function()? onCancel;
15 15
16 GetStream({this.onListen, this.onPause, this.onResume, this.onCancel}); 16 GetStream({this.onListen, this.onPause, this.onResume, this.onCancel});
  17 +
  18 + factory GetStream.fromValue(T value,
  19 + {Function()? onListen,
  20 + Function()? onPause,
  21 + Function()? onResume,
  22 + FutureOr<void> Function()? onCancel}) {
  23 + final valuedStream = GetStream<T>(
  24 + onListen: onListen,
  25 + onPause: onPause,
  26 + onResume: onResume,
  27 + onCancel: onCancel)
  28 + .._value = value;
  29 +
  30 + return valuedStream;
  31 + }
  32 +
17 List<LightSubscription<T>>? _onData = <LightSubscription<T>>[]; 33 List<LightSubscription<T>>? _onData = <LightSubscription<T>>[];
18 34
19 bool? _isBusy = false; 35 bool? _isBusy = false;
@@ -87,9 +103,12 @@ class GetStream<T> { @@ -87,9 +103,12 @@ class GetStream<T> {
87 _isBusy = false; 103 _isBusy = false;
88 } 104 }
89 105
90 - T? _value; 106 + late T _value;
91 107
92 - T? get value => _value; 108 + T get value {
  109 + RxInterface.proxy?.addListener(this);
  110 + return _value;
  111 + }
93 112
94 void add(T event) { 113 void add(T event) {
95 assert(!isClosed, 'You cannot add event to closed Stream'); 114 assert(!isClosed, 'You cannot add event to closed Stream');
@@ -109,7 +128,7 @@ class GetStream<T> { @@ -109,7 +128,7 @@ class GetStream<T> {
109 _notifyDone(); 128 _notifyDone();
110 _onData = null; 129 _onData = null;
111 _isBusy = null; 130 _isBusy = null;
112 - _value = null; 131 + // _value = null;
113 } 132 }
114 133
115 LightSubscription<T> listen(void Function(T event) onData, 134 LightSubscription<T> listen(void Function(T event) onData,
@@ -2,7 +2,10 @@ library rx_stream; @@ -2,7 +2,10 @@ library rx_stream;
2 2
3 import 'dart:async'; 3 import 'dart:async';
4 4
  5 +import 'package:get/get_state_manager/src/simple/list_notifier.dart';
  6 +
5 import '../rx_typedefs/rx_typedefs.dart'; 7 import '../rx_typedefs/rx_typedefs.dart';
  8 +import '../rx_types/rx_types.dart';
6 9
7 part 'get_stream.dart'; 10 part 'get_stream.dart';
8 part 'mini_stream.dart'; 11 part 'mini_stream.dart';
@@ -5,7 +5,7 @@ part of rx_types; @@ -5,7 +5,7 @@ part of rx_types;
5 /// of those `Widgets` and Rx values. 5 /// of those `Widgets` and Rx values.
6 6
7 mixin RxObjectMixin<T> on NotifyManager<T> { 7 mixin RxObjectMixin<T> on NotifyManager<T> {
8 - late T _value; 8 + //late T _value;
9 9
10 /// Makes a direct update of [value] adding it to the Stream 10 /// Makes a direct update of [value] adding it to the Stream
11 /// useful when you make use of Rx for custom Types to referesh your UI. 11 /// useful when you make use of Rx for custom Types to referesh your UI.
@@ -91,24 +91,25 @@ mixin RxObjectMixin<T> on NotifyManager<T> { @@ -91,24 +91,25 @@ mixin RxObjectMixin<T> on NotifyManager<T> {
91 91
92 @override 92 @override
93 // ignore: avoid_equals_and_hash_code_on_mutable_classes 93 // ignore: avoid_equals_and_hash_code_on_mutable_classes
94 - int get hashCode => _value.hashCode; 94 + int get hashCode => value.hashCode;
95 95
96 /// Updates the [value] and adds it to the stream, updating the observer 96 /// Updates the [value] and adds it to the stream, updating the observer
97 /// Widget, only if it's different from the previous value. 97 /// Widget, only if it's different from the previous value.
98 set value(T val) { 98 set value(T val) {
99 if (subject.isClosed) return; 99 if (subject.isClosed) return;
100 sentToStream = false; 100 sentToStream = false;
101 - if (_value == val && !firstRebuild) return; 101 + if (value == val && !firstRebuild) return;
102 firstRebuild = false; 102 firstRebuild = false;
103 - _value = val; 103 + // _value = val;
104 sentToStream = true; 104 sentToStream = true;
105 - subject.add(_value); 105 + subject.add(val);
106 } 106 }
107 107
108 /// Returns the current [value] 108 /// Returns the current [value]
109 T get value { 109 T get value {
110 - RxInterface.proxy?.addListener(subject);  
111 - return _value; 110 + return subject.value;
  111 + //RxInterface.proxy?.addListener(subject);
  112 + // return _value;
112 } 113 }
113 114
114 Stream<T> get stream => subject.stream; 115 Stream<T> get stream => subject.stream;
@@ -192,7 +193,7 @@ mixin NotifyManager<T> { @@ -192,7 +193,7 @@ mixin NotifyManager<T> {
192 /// Base Rx class that manages all the stream logic for any Type. 193 /// Base Rx class that manages all the stream logic for any Type.
193 abstract class _RxImpl<T> extends RxNotifier<T> with RxObjectMixin<T> { 194 abstract class _RxImpl<T> extends RxNotifier<T> with RxObjectMixin<T> {
194 _RxImpl(T initial) { 195 _RxImpl(T initial) {
195 - _value = initial; 196 + subject = GetStream.fromValue(initial);
196 } 197 }
197 198
198 void addError(Object error, [StackTrace? stackTrace]) { 199 void addError(Object error, [StackTrace? stackTrace]) {
@@ -222,8 +223,8 @@ abstract class _RxImpl<T> extends RxNotifier<T> with RxObjectMixin<T> { @@ -222,8 +223,8 @@ abstract class _RxImpl<T> extends RxNotifier<T> with RxObjectMixin<T> {
222 /// print( person ); 223 /// print( person );
223 /// ``` 224 /// ```
224 void update(void fn(T? val)) { 225 void update(void fn(T? val)) {
225 - fn(_value);  
226 - subject.add(_value); 226 + fn(value);
  227 + subject.add(value);
227 } 228 }
228 229
229 /// Following certain practices on Rx data, we might want to react to certain 230 /// Following certain practices on Rx data, we might want to react to certain
@@ -295,7 +296,7 @@ extension RxBoolExt on Rx<bool> { @@ -295,7 +296,7 @@ extension RxBoolExt on Rx<bool> {
295 /// not really a dart thing since we have '..' operator 296 /// not really a dart thing since we have '..' operator
296 // ignore: avoid_returning_this 297 // ignore: avoid_returning_this
297 Rx<bool> toggle() { 298 Rx<bool> toggle() {
298 - subject.add(_value = !_value); 299 + subject.add(!value);
299 return this; 300 return this;
300 } 301 }
301 } 302 }
@@ -327,8 +328,8 @@ extension RxnBoolExt on Rx<bool?> { @@ -327,8 +328,8 @@ extension RxnBoolExt on Rx<bool?> {
327 /// not really a dart thing since we have '..' operator 328 /// not really a dart thing since we have '..' operator
328 // ignore: avoid_returning_this 329 // ignore: avoid_returning_this
329 Rx<bool?>? toggle() { 330 Rx<bool?>? toggle() {
330 - if (_value != null) {  
331 - subject.add(_value = !_value!); 331 + if (value != null) {
  332 + subject.add(!value!);
332 return this; 333 return this;
333 } 334 }
334 } 335 }
1 part of rx_types; 1 part of rx_types;
2 2
3 extension RxStringExt on Rx<String> { 3 extension RxStringExt on Rx<String> {
4 - String operator +(String val) => _value + val; 4 + String operator +(String val) => value + val;
5 5
6 int compareTo(String other) { 6 int compareTo(String other) {
7 return value.compareTo(other); 7 return value.compareTo(other);
@@ -125,7 +125,7 @@ extension RxStringExt on Rx<String> { @@ -125,7 +125,7 @@ extension RxStringExt on Rx<String> {
125 } 125 }
126 126
127 extension RxnStringExt on Rx<String?> { 127 extension RxnStringExt on Rx<String?> {
128 - String operator +(String val) => (_value ?? '') + val; 128 + String operator +(String val) => (value ?? '') + val;
129 129
130 int? compareTo(String other) { 130 int? compareTo(String other) {
131 return value?.compareTo(other); 131 return value?.compareTo(other);
@@ -5,7 +5,7 @@ class RxList<E> extends ListMixin<E> @@ -5,7 +5,7 @@ class RxList<E> extends ListMixin<E>
5 with NotifyManager<List<E>>, RxObjectMixin<List<E>> 5 with NotifyManager<List<E>>, RxObjectMixin<List<E>>
6 implements RxInterface<List<E>> { 6 implements RxInterface<List<E>> {
7 RxList([List<E> initial = const []]) { 7 RxList([List<E> initial = const []]) {
8 - _value = List.from(initial); 8 + subject = GetStream.fromValue(List.from(initial));
9 } 9 }
10 10
11 factory RxList.filled(int length, E fill, {bool growable = false}) { 11 factory RxList.filled(int length, E fill, {bool growable = false}) {
@@ -42,7 +42,7 @@ class RxList<E> extends ListMixin<E> @@ -42,7 +42,7 @@ class RxList<E> extends ListMixin<E>
42 42
43 @override 43 @override
44 void operator []=(int index, E val) { 44 void operator []=(int index, E val) {
45 - _value[index] = val; 45 + value[index] = val;
46 refresh(); 46 refresh();
47 } 47 }
48 48
@@ -62,25 +62,25 @@ class RxList<E> extends ListMixin<E> @@ -62,25 +62,25 @@ class RxList<E> extends ListMixin<E>
62 62
63 @override 63 @override
64 void add(E item) { 64 void add(E item) {
65 - _value.add(item); 65 + value.add(item);
66 refresh(); 66 refresh();
67 } 67 }
68 68
69 @override 69 @override
70 void addAll(Iterable<E> item) { 70 void addAll(Iterable<E> item) {
71 - _value.addAll(item); 71 + value.addAll(item);
72 refresh(); 72 refresh();
73 } 73 }
74 74
75 @override 75 @override
76 void removeWhere(bool test(E element)) { 76 void removeWhere(bool test(E element)) {
77 - _value.removeWhere(test); 77 + value.removeWhere(test);
78 refresh(); 78 refresh();
79 } 79 }
80 80
81 @override 81 @override
82 void retainWhere(bool test(E element)) { 82 void retainWhere(bool test(E element)) {
83 - _value.retainWhere(test); 83 + value.retainWhere(test);
84 refresh(); 84 refresh();
85 } 85 }
86 86
@@ -91,18 +91,18 @@ class RxList<E> extends ListMixin<E> @@ -91,18 +91,18 @@ class RxList<E> extends ListMixin<E>
91 @protected 91 @protected
92 List<E> get value { 92 List<E> get value {
93 RxInterface.proxy?.addListener(subject); 93 RxInterface.proxy?.addListener(subject);
94 - return _value; 94 + return subject.value;
95 } 95 }
96 96
97 @override 97 @override
98 set length(int newLength) { 98 set length(int newLength) {
99 - _value.length = newLength; 99 + value.length = newLength;
100 refresh(); 100 refresh();
101 } 101 }
102 102
103 @override 103 @override
104 void insertAll(int index, Iterable<E> iterable) { 104 void insertAll(int index, Iterable<E> iterable) {
105 - _value.insertAll(index, iterable); 105 + value.insertAll(index, iterable);
106 refresh(); 106 refresh();
107 } 107 }
108 108
@@ -121,7 +121,7 @@ class RxList<E> extends ListMixin<E> @@ -121,7 +121,7 @@ class RxList<E> extends ListMixin<E>
121 121
122 @override 122 @override
123 void sort([int compare(E a, E b)?]) { 123 void sort([int compare(E a, E b)?]) {
124 - _value.sort(compare); 124 + value.sort(compare);
125 refresh(); 125 refresh();
126 } 126 }
127 } 127 }
@@ -4,7 +4,7 @@ class RxMap<K, V> extends MapMixin<K, V> @@ -4,7 +4,7 @@ class RxMap<K, V> extends MapMixin<K, V>
4 with NotifyManager<Map<K, V>>, RxObjectMixin<Map<K, V>> 4 with NotifyManager<Map<K, V>>, RxObjectMixin<Map<K, V>>
5 implements RxInterface<Map<K, V>> { 5 implements RxInterface<Map<K, V>> {
6 RxMap([Map<K, V> initial = const {}]) { 6 RxMap([Map<K, V> initial = const {}]) {
7 - _value = Map.from(initial); 7 + subject = GetStream.fromValue(Map.from(initial));
8 } 8 }
9 9
10 factory RxMap.from(Map<K, V> other) { 10 factory RxMap.from(Map<K, V> other) {
@@ -32,14 +32,14 @@ class RxMap<K, V> extends MapMixin<K, V> @@ -32,14 +32,14 @@ class RxMap<K, V> extends MapMixin<K, V>
32 } 32 }
33 33
34 @override 34 @override
35 - void operator []=(K key, V value) {  
36 - _value[key] = value; 35 + void operator []=(K key, V val) {
  36 + value[key] = val;
37 refresh(); 37 refresh();
38 } 38 }
39 39
40 @override 40 @override
41 void clear() { 41 void clear() {
42 - _value.clear(); 42 + value.clear();
43 refresh(); 43 refresh();
44 } 44 }
45 45
@@ -48,7 +48,7 @@ class RxMap<K, V> extends MapMixin<K, V> @@ -48,7 +48,7 @@ class RxMap<K, V> extends MapMixin<K, V>
48 48
49 @override 49 @override
50 V? remove(Object? key) { 50 V? remove(Object? key) {
51 - final val = _value.remove(key); 51 + final val = value.remove(key);
52 refresh(); 52 refresh();
53 return val; 53 return val;
54 } 54 }
@@ -56,8 +56,9 @@ class RxMap<K, V> extends MapMixin<K, V> @@ -56,8 +56,9 @@ class RxMap<K, V> extends MapMixin<K, V>
56 @override 56 @override
57 @protected 57 @protected
58 Map<K, V> get value { 58 Map<K, V> get value {
59 - RxInterface.proxy?.addListener(subject);  
60 - return _value; 59 + return subject.value;
  60 + // RxInterface.proxy?.addListener(subject);
  61 + // return _value;
61 } 62 }
62 } 63 }
63 64
@@ -82,7 +83,7 @@ extension MapExtension<K, V> on Map<K, V> { @@ -82,7 +83,7 @@ extension MapExtension<K, V> on Map<K, V> {
82 if (this is RxMap) { 83 if (this is RxMap) {
83 final map = (this as RxMap); 84 final map = (this as RxMap);
84 // map._value; 85 // map._value;
85 - map._value.clear(); 86 + map.value.clear();
86 this[key] = val; 87 this[key] = val;
87 } else { 88 } else {
88 clear(); 89 clear();
@@ -92,12 +93,12 @@ extension MapExtension<K, V> on Map<K, V> { @@ -92,12 +93,12 @@ extension MapExtension<K, V> on Map<K, V> {
92 93
93 void assignAll(Map<K, V> val) { 94 void assignAll(Map<K, V> val) {
94 if (val is RxMap && this is RxMap) { 95 if (val is RxMap && this is RxMap) {
95 - if ((val as RxMap)._value == (this as RxMap)._value) return; 96 + if ((val as RxMap).value == (this as RxMap).value) return;
96 } 97 }
97 if (this is RxMap) { 98 if (this is RxMap) {
98 final map = (this as RxMap); 99 final map = (this as RxMap);
99 - if (map._value == val) return;  
100 - map._value = val; 100 + if (map.value == val) return;
  101 + map.value = val;
101 map.refresh(); 102 map.refresh();
102 } else { 103 } else {
103 if (this == val) return; 104 if (this == val) return;
@@ -4,7 +4,7 @@ class RxSet<E> extends SetMixin<E> @@ -4,7 +4,7 @@ class RxSet<E> extends SetMixin<E>
4 with NotifyManager<Set<E>>, RxObjectMixin<Set<E>> 4 with NotifyManager<Set<E>>, RxObjectMixin<Set<E>>
5 implements RxInterface<Set<E>> { 5 implements RxInterface<Set<E>> {
6 RxSet([Set<E> initial = const {}]) { 6 RxSet([Set<E> initial = const {}]) {
7 - _value = Set.from(initial); 7 + subject = GetStream.fromValue(Set.from(initial));
8 } 8 }
9 9
10 /// Special override to push() element(s) in a reactive way 10 /// Special override to push() element(s) in a reactive way
@@ -23,21 +23,22 @@ class RxSet<E> extends SetMixin<E> @@ -23,21 +23,22 @@ class RxSet<E> extends SetMixin<E>
23 @override 23 @override
24 @protected 24 @protected
25 Set<E> get value { 25 Set<E> get value {
26 - RxInterface.proxy?.addListener(subject);  
27 - return _value; 26 + return subject.value;
  27 + // RxInterface.proxy?.addListener(subject);
  28 + // return _value;
28 } 29 }
29 30
30 @override 31 @override
31 @protected 32 @protected
32 set value(Set<E> val) { 33 set value(Set<E> val) {
33 - if (_value == val) return;  
34 - _value = val; 34 + if (value == val) return;
  35 + value = val;
35 refresh(); 36 refresh();
36 } 37 }
37 38
38 @override 39 @override
39 bool add(E value) { 40 bool add(E value) {
40 - final hasAdded = _value.add(value); 41 + final hasAdded = value.add(value);
41 if (hasAdded) { 42 if (hasAdded) {
42 refresh(); 43 refresh();
43 } 44 }
@@ -62,7 +63,7 @@ class RxSet<E> extends SetMixin<E> @@ -62,7 +63,7 @@ class RxSet<E> extends SetMixin<E>
62 63
63 @override 64 @override
64 bool remove(Object? item) { 65 bool remove(Object? item) {
65 - var hasRemoved = _value.remove(item); 66 + var hasRemoved = value.remove(item);
66 if (hasRemoved) { 67 if (hasRemoved) {
67 refresh(); 68 refresh();
68 } 69 }
@@ -76,31 +77,31 @@ class RxSet<E> extends SetMixin<E> @@ -76,31 +77,31 @@ class RxSet<E> extends SetMixin<E>
76 77
77 @override 78 @override
78 void addAll(Iterable<E> item) { 79 void addAll(Iterable<E> item) {
79 - _value.addAll(item); 80 + value.addAll(item);
80 refresh(); 81 refresh();
81 } 82 }
82 83
83 @override 84 @override
84 void clear() { 85 void clear() {
85 - _value.clear(); 86 + value.clear();
86 refresh(); 87 refresh();
87 } 88 }
88 89
89 @override 90 @override
90 void removeAll(Iterable<Object?> elements) { 91 void removeAll(Iterable<Object?> elements) {
91 - _value.removeAll(elements); 92 + value.removeAll(elements);
92 refresh(); 93 refresh();
93 } 94 }
94 95
95 @override 96 @override
96 void retainAll(Iterable<Object?> elements) { 97 void retainAll(Iterable<Object?> elements) {
97 - _value.retainAll(elements); 98 + value.retainAll(elements);
98 refresh(); 99 refresh();
99 } 100 }
100 101
101 @override 102 @override
102 void retainWhere(bool Function(E) E) { 103 void retainWhere(bool Function(E) E) {
103 - _value.retainWhere(E); 104 + value.retainWhere(E);
104 refresh(); 105 refresh();
105 } 106 }
106 } 107 }
@@ -4,6 +4,7 @@ import 'dart:async'; @@ -4,6 +4,7 @@ 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/simple/list_notifier.dart';
7 import '../rx_stream/rx_stream.dart'; 8 import '../rx_stream/rx_stream.dart';
8 import '../rx_typedefs/rx_typedefs.dart'; 9 import '../rx_typedefs/rx_typedefs.dart';
9 10
@@ -14,9 +14,6 @@ typedef GetXControllerBuilder<T extends DisposableInterface> = Widget Function( @@ -14,9 +14,6 @@ typedef GetXControllerBuilder<T extends DisposableInterface> = Widget Function(
14 class GetX<T extends DisposableInterface> extends StatefulWidget { 14 class GetX<T extends DisposableInterface> extends StatefulWidget {
15 final GetXControllerBuilder<T> builder; 15 final GetXControllerBuilder<T> builder;
16 final bool global; 16 final bool global;
17 -  
18 - // final Stream Function(T) stream;  
19 - // final StreamController Function(T) streamController;  
20 final bool autoRemove; 17 final bool autoRemove;
21 final bool assignId; 18 final bool assignId;
22 final void Function(GetXState<T> state)? initState, 19 final void Function(GetXState<T> state)? initState,
@@ -7,7 +7,7 @@ import '../../get_state_manager.dart'; @@ -7,7 +7,7 @@ import '../../get_state_manager.dart';
7 import '../simple/list_notifier.dart'; 7 import '../simple/list_notifier.dart';
8 8
9 mixin StateMixin<T> on ListNotifierMixin { 9 mixin StateMixin<T> on ListNotifierMixin {
10 - T? _value; 10 + late T _value;
11 RxStatus? _status; 11 RxStatus? _status;
12 12
13 bool _isNullOrEmpty(dynamic val) { 13 bool _isNullOrEmpty(dynamic val) {
@@ -32,23 +32,23 @@ mixin StateMixin<T> on ListNotifierMixin { @@ -32,23 +32,23 @@ mixin StateMixin<T> on ListNotifierMixin {
32 return _status ??= _status = RxStatus.loading(); 32 return _status ??= _status = RxStatus.loading();
33 } 33 }
34 34
35 - T? get state => value; 35 + T get state => value;
36 36
37 @protected 37 @protected
38 - T? get value { 38 + T get value {
39 notifyChildrens(); 39 notifyChildrens();
40 return _value; 40 return _value;
41 } 41 }
42 42
43 @protected 43 @protected
44 - set value(T? newValue) { 44 + set value(T newValue) {
45 if (_value == newValue) return; 45 if (_value == newValue) return;
46 _value = newValue; 46 _value = newValue;
47 refresh(); 47 refresh();
48 } 48 }
49 49
50 @protected 50 @protected
51 - void change(T? newState, {RxStatus? status}) { 51 + void change(T newState, {RxStatus? status}) {
52 var _canUpdate = false; 52 var _canUpdate = false;
53 if (status != null) { 53 if (status != null) {
54 _status = status; 54 _status = status;
@@ -82,13 +82,13 @@ class Value<T> extends ListNotifier @@ -82,13 +82,13 @@ class Value<T> extends ListNotifier
82 } 82 }
83 83
84 @override 84 @override
85 - T? get value { 85 + T get value {
86 notifyChildrens(); 86 notifyChildrens();
87 return _value; 87 return _value;
88 } 88 }
89 89
90 @override 90 @override
91 - set value(T? newValue) { 91 + set value(T newValue) {
92 if (_value == newValue) return; 92 if (_value == newValue) return;
93 _value = newValue; 93 _value = newValue;
94 refresh(); 94 refresh();
@@ -119,9 +119,7 @@ extension ReactiveT<T> on T { @@ -119,9 +119,7 @@ extension ReactiveT<T> on T {
119 typedef Condition = bool Function(); 119 typedef Condition = bool Function();
120 120
121 abstract class GetNotifier<T> extends Value<T> with GetLifeCycleBase { 121 abstract class GetNotifier<T> extends Value<T> with GetLifeCycleBase {
122 - GetNotifier(T initial) : super(initial) {  
123 - $configureLifeCycle();  
124 - } 122 + GetNotifier(T initial) : super(initial);
125 123
126 @override 124 @override
127 @mustCallSuper 125 @mustCallSuper
@@ -194,3 +192,44 @@ class RxStatus { @@ -194,3 +192,44 @@ class RxStatus {
194 } 192 }
195 193
196 typedef NotifierBuilder<T> = Widget Function(T state); 194 typedef NotifierBuilder<T> = Widget Function(T state);
  195 +
  196 +abstract class GState<T> {
  197 + const GState();
  198 + factory GState.loading() => GLoading();
  199 + factory GState.error(String message) => GError(message);
  200 + factory GState.empty() => GEmpty();
  201 + factory GState.success(T data) => GSuccess(data);
  202 +}
  203 +
  204 +class GLoading<T> extends GState<T> {}
  205 +
  206 +class GSuccess<T> extends GState<T> {
  207 + final T data;
  208 +
  209 + GSuccess(this.data);
  210 +}
  211 +
  212 +class GError<T, S> extends GState<T> {
  213 + final S? error;
  214 + GError([this.error]);
  215 +}
  216 +
  217 +class GEmpty<T> extends GState<T> {}
  218 +
  219 +extension StatusDataExt<T> on GState<T> {
  220 + bool get isLoading => this is GLoading;
  221 + bool get isSuccess => this is GSuccess;
  222 + bool get isError => this is GError;
  223 + bool get isEmpty => this is GEmpty;
  224 + String get errorMessage {
  225 + final isError = this is GError;
  226 + if (isError) {
  227 + final err = this as GError;
  228 + if (err.error != null && err.error is String) {
  229 + return err.error as String;
  230 + }
  231 + }
  232 +
  233 + return '';
  234 + }
  235 +}
1 import 'dart:async'; 1 import 'dart:async';
  2 +
2 import 'package:flutter/foundation.dart'; 3 import 'package:flutter/foundation.dart';
3 import 'package:flutter/widgets.dart'; 4 import 'package:flutter/widgets.dart';
  5 +
4 import '../../../get_rx/src/rx_types/rx_types.dart'; 6 import '../../../get_rx/src/rx_types/rx_types.dart';
5 7
6 typedef WidgetCallback = Widget Function(); 8 typedef WidgetCallback = Widget Function();
@@ -54,6 +56,15 @@ class _ObxState extends State<ObxWidget> { @@ -54,6 +56,15 @@ class _ObxState extends State<ObxWidget> {
54 RxInterface.notifyChildren(_observer, widget.build); 56 RxInterface.notifyChildren(_observer, widget.build);
55 } 57 }
56 58
  59 +
  60 +
  61 +
  62 +
  63 +
  64 +
  65 +
  66 +
  67 +
57 /// The simplest reactive widget in GetX. 68 /// The simplest reactive widget in GetX.
58 /// 69 ///
59 /// Just pass your Rx variable in the root scope of the callback to have it 70 /// Just pass your Rx variable in the root scope of the callback to have it
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
  2 +
2 import '../../../get_instance/src/get_instance.dart'; 3 import '../../../get_instance/src/get_instance.dart';
3 import '../../../instance_manager.dart'; 4 import '../../../instance_manager.dart';
4 import '../../get_state_manager.dart'; 5 import '../../get_state_manager.dart';
5 -import 'list_notifier.dart';  
6 -  
7 -/// Complies with `GetStateUpdater`  
8 -///  
9 -/// This mixin's function represents a `GetStateUpdater`, and might be used  
10 -/// by `GetBuilder()`, `SimpleBuilder()` (or similar) to comply  
11 -/// with [GetStateUpdate] signature. REPLACING the [StateSetter].  
12 -/// Avoids the potential (but extremely unlikely) issue of having  
13 -/// the Widget in a dispose() state, and abstracts the  
14 -/// API from the ugly fn((){}).  
15 -mixin GetStateUpdaterMixin<T extends StatefulWidget> on State<T> {  
16 - // To avoid the creation of an anonym function to be GC later.  
17 - // ignore: prefer_function_declarations_over_variables  
18 -  
19 - /// Experimental method to replace setState((){});  
20 - /// Used with GetStateUpdate.  
21 - void getUpdate() {  
22 - if (mounted) setState(() {});  
23 - }  
24 -}  
25 6
26 typedef GetControllerBuilder<T extends DisposableInterface> = Widget Function( 7 typedef GetControllerBuilder<T extends DisposableInterface> = Widget Function(
27 T controller); 8 T controller);
28 9
29 -// class _InheritedGetxController<T extends GetxController>  
30 -// extends InheritedWidget {  
31 -// final T model;  
32 -// final int version;  
33 -  
34 -// _InheritedGetxController({  
35 -// Key key,  
36 -// @required Widget child,  
37 -// @required this.model,  
38 -// }) : version = model.notifierVersion,  
39 -// super(key: key, child: child);  
40 -  
41 -// @override  
42 -// bool updateShouldNotify(_InheritedGetxController<T> oldWidget) =>  
43 -// (oldWidget.version != version);  
44 -// } 10 +extension WatchExt on BuildContext {
  11 + T listen<T extends GetxController>() {
  12 + return Scope.of(this, rebuild: true);
  13 + }
  14 +}
  15 +
  16 +extension ReadExt on BuildContext {
  17 + T find<T extends GetxController>() {
  18 + return Scope.of(this);
  19 + }
  20 +}
45 21
46 -// extension WatchEtx on GetxController {  
47 -// T watch<T extends GetxController>() {  
48 -// final instance = Get.find<T>();  
49 -// _GetBuilderState._currentState.watch(instance.update);  
50 -// return instance; 22 +// extension FilterExt on BuildContext {
  23 +// T filter<T extends GetxController>(Object Function(T value)? filter) {
  24 +// return Scope.of(this, filter: filter, rebuild: true);
51 // } 25 // }
52 // } 26 // }
53 27
54 -class GetBuilder<T extends GetxController> extends StatefulWidget { 28 +class GetBuilder<T extends GetxController> extends StatelessWidget {
55 final GetControllerBuilder<T> builder; 29 final GetControllerBuilder<T> builder;
56 final bool global; 30 final bool global;
57 final Object? id; 31 final Object? id;
@@ -59,10 +33,10 @@ class GetBuilder<T extends GetxController> extends StatefulWidget { @@ -59,10 +33,10 @@ class GetBuilder<T extends GetxController> extends StatefulWidget {
59 final bool autoRemove; 33 final bool autoRemove;
60 final bool assignId; 34 final bool assignId;
61 final Object Function(T value)? filter; 35 final Object Function(T value)? filter;
62 - final void Function(GetBuilderState<T> state)? initState, 36 + final void Function(ScopeElement<T> state)? initState,
63 dispose, 37 dispose,
64 didChangeDependencies; 38 didChangeDependencies;
65 - final void Function(GetBuilder oldWidget, GetBuilderState<T> state)? 39 + final void Function(Scope<T> oldWidget, ScopeElement<T> state)?
66 didUpdateWidget; 40 didUpdateWidget;
67 final T? init; 41 final T? init;
68 42
@@ -82,40 +56,127 @@ class GetBuilder<T extends GetxController> extends StatefulWidget { @@ -82,40 +56,127 @@ class GetBuilder<T extends GetxController> extends StatefulWidget {
82 this.didUpdateWidget, 56 this.didUpdateWidget,
83 }) : super(key: key); 57 }) : super(key: key);
84 58
85 - // static T of<T extends GetxController>(  
86 - // BuildContext context, {  
87 - // bool rebuild = false,  
88 - // }) {  
89 - // var widget = rebuild  
90 - // ? context  
91 - // .dependOnInheritedWidgetOfExactType<_InheritedGetxController<T>>()  
92 - // : context  
93 - // .getElementForInheritedWidgetOfExactType<  
94 - // _InheritedGetxController<T>>()  
95 - // ?.widget;  
96 -  
97 - // if (widget == null) {  
98 - // throw 'Error: Could not find the correct dependency.';  
99 - // } else {  
100 - // return (widget as _InheritedGetxController<T>).model;  
101 - // }  
102 - // } 59 + @override
  60 + Widget build(BuildContext context) {
  61 + return Scope<T>(
  62 + init: init,
  63 + global: global,
  64 + autoRemove: autoRemove,
  65 + assignId: assignId,
  66 + initState: initState,
  67 + filter: filter,
  68 + tag: tag,
  69 + dispose: dispose,
  70 + id: id,
  71 + didChangeDependencies: didChangeDependencies,
  72 + didUpdateWidget: didUpdateWidget,
  73 + child: Builder(builder: (context) {
  74 + final controller = Scope.of<T>(context, rebuild: true);
  75 + return builder(controller);
  76 + }),
  77 + );
  78 + // return widget.builder(controller!);
  79 + }
  80 +}
  81 +
  82 +class Scope<T extends GetxController> extends InheritedWidget {
  83 + /// Create an inherited widget that updates its dependents when [controller]
  84 + /// sends notifications.
  85 + ///
  86 + /// The [child] argument is required
  87 + const Scope({
  88 + Key? key,
  89 + required Widget child,
  90 + this.init,
  91 + this.global = true,
  92 + this.autoRemove = true,
  93 + this.assignId = false,
  94 + this.initState,
  95 + this.filter,
  96 + this.tag,
  97 + this.dispose,
  98 + this.id,
  99 + this.didChangeDependencies,
  100 + this.didUpdateWidget,
  101 + }) : super(key: key, child: child);
  102 +
  103 + /// The [Listenable] object to which to listen.
  104 + ///
  105 + /// Whenever this object sends change notifications, the dependents of this
  106 + /// widget are triggered.
  107 + ///
  108 + /// By default, whenever the [controller] is changed (including when changing to
  109 + /// or from null), if the old controller is not equal to the new controller (as
  110 + /// determined by the `==` operator), notifications are sent. This behavior
  111 + /// can be overridden by overriding [updateShouldNotify].
  112 + ///
  113 + /// While the [controller] is null, no notifications are sent, since the null
  114 + /// object cannot itself send notifications.
  115 + final T? init;
  116 +
  117 + final bool global;
  118 + final Object? id;
  119 + final String? tag;
  120 + final bool autoRemove;
  121 + final bool assignId;
  122 + final Object Function(T value)? filter;
  123 + final void Function(ScopeElement<T> state)? initState,
  124 + dispose,
  125 + didChangeDependencies;
  126 + final void Function(Scope<T> oldWidget, ScopeElement<T> state)?
  127 + didUpdateWidget;
  128 +
  129 + static T of<T extends GetxController>(
  130 + BuildContext context, {
  131 + bool rebuild = false,
  132 + // Object Function(T value)? filter,
  133 + }) {
  134 + final inheritedElement = context
  135 + .getElementForInheritedWidgetOfExactType<Scope<T>>() as ScopeElement<T>;
  136 +
  137 + if (rebuild) {
  138 + // var newFilter = filter?.call(inheritedElement.controller!);
  139 + // if (newFilter != null) {
  140 + // context.dependOnInheritedElement(inheritedElement, aspect: newFilter);
  141 + // } else {
  142 + context.dependOnInheritedElement(inheritedElement);
  143 + // }
  144 + }
  145 +
  146 + var widget = inheritedElement.controller;
  147 +
  148 + if (widget == null) {
  149 + throw 'Error: Could not find the correct dependency.';
  150 + } else {
  151 + return widget;
  152 + }
  153 + }
103 154
104 @override 155 @override
105 - GetBuilderState<T> createState() => GetBuilderState<T>(); 156 + bool updateShouldNotify(Scope<T> oldWidget) {
  157 + return oldWidget.id != id ||
  158 + oldWidget.global != global ||
  159 + oldWidget.autoRemove != autoRemove ||
  160 + oldWidget.assignId != assignId;
  161 + }
  162 +
  163 + @override
  164 + InheritedElement createElement() => ScopeElement<T>(this);
106 } 165 }
107 166
108 -class GetBuilderState<T extends GetxController> extends State<GetBuilder<T>>  
109 - with GetStateUpdaterMixin { 167 +/// The ScopeElement is responsible for injecting dependencies into the widget
  168 +/// tree so that they can be observed
  169 +class ScopeElement<T extends GetxController> extends InheritedElement {
  170 + ScopeElement(Scope<T> widget) : super(widget) {
  171 + initState();
  172 + }
  173 +
110 T? controller; 174 T? controller;
111 bool? _isCreator = false; 175 bool? _isCreator = false;
112 VoidCallback? _remove; 176 VoidCallback? _remove;
113 Object? _filter; 177 Object? _filter;
114 178
115 - @override  
116 void initState() { 179 void initState() {
117 - // _GetBuilderState._currentState = this;  
118 - super.initState();  
119 widget.initState?.call(this); 180 widget.initState?.call(this);
120 181
121 var isRegistered = GetInstance().isRegistered<T>(tag: widget.tag); 182 var isRegistered = GetInstance().isRegistered<T>(tag: widget.tag);
@@ -169,9 +230,7 @@ class GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> @@ -169,9 +230,7 @@ class GetBuilderState<T extends GetxController> extends State<GetBuilder<T>>
169 } 230 }
170 } 231 }
171 232
172 - @override  
173 void dispose() { 233 void dispose() {
174 - super.dispose();  
175 widget.dispose?.call(this); 234 widget.dispose?.call(this);
176 if (_isCreator! || widget.assignId) { 235 if (_isCreator! || widget.assignId) {
177 if (widget.autoRemove && GetInstance().isRegistered<T>(tag: widget.tag)) { 236 if (widget.autoRemove && GetInstance().isRegistered<T>(tag: widget.tag)) {
@@ -188,39 +247,49 @@ class GetBuilderState<T extends GetxController> extends State<GetBuilder<T>> @@ -188,39 +247,49 @@ class GetBuilderState<T extends GetxController> extends State<GetBuilder<T>>
188 } 247 }
189 248
190 @override 249 @override
  250 + Scope<T> get widget => super.widget as Scope<T>;
  251 +
  252 + var _dirty = false;
  253 +
  254 + @override
  255 + void update(Scope<T> newWidget) {
  256 + final oldNotifier = widget.id;
  257 + final newNotifier = newWidget.id;
  258 + if (oldNotifier != newNotifier) {
  259 + _subscribeToController();
  260 + }
  261 + widget.didUpdateWidget?.call(widget, this);
  262 + super.update(newWidget);
  263 + }
  264 +
  265 + @override
191 void didChangeDependencies() { 266 void didChangeDependencies() {
192 super.didChangeDependencies(); 267 super.didChangeDependencies();
193 widget.didChangeDependencies?.call(this); 268 widget.didChangeDependencies?.call(this);
194 } 269 }
195 270
196 @override 271 @override
197 - void didUpdateWidget(GetBuilder oldWidget) {  
198 - super.didUpdateWidget(oldWidget as GetBuilder<T>);  
199 - // to avoid conflicts when modifying a "grouped" id list.  
200 - if (oldWidget.id != widget.id) {  
201 - _subscribeToController(); 272 + Widget build() {
  273 + if (_dirty) {
  274 + notifyClients(widget);
202 } 275 }
203 - widget.didUpdateWidget?.call(oldWidget, this); 276 + return super.build();
204 } 277 }
205 278
206 - @override  
207 - Widget build(BuildContext context) {  
208 - // return _InheritedGetxController<T>(  
209 - // model: controller,  
210 - // child: widget.builder(controller),  
211 - // );  
212 - return widget.builder(controller!); 279 + void getUpdate() {
  280 + _dirty = true;
  281 + markNeedsBuild();
213 } 282 }
214 -}  
215 283
216 -// extension FindExt on BuildContext {  
217 -// T find<T extends GetxController>() {  
218 -// return GetBuilder.of<T>(this, rebuild: false);  
219 -// }  
220 -// } 284 + @override
  285 + void notifyClients(Scope<T> oldWidget) {
  286 + super.notifyClients(oldWidget);
  287 + _dirty = false;
  288 + }
221 289
222 -// extension ObserverEtx on BuildContext {  
223 -// T obs<T extends GetxController>() {  
224 -// return GetBuilder.of<T>(this, rebuild: true);  
225 -// }  
226 -// } 290 + @override
  291 + void unmount() {
  292 + dispose();
  293 + super.unmount();
  294 + }
  295 +}
@@ -159,15 +159,11 @@ class TaskManager { @@ -159,15 +159,11 @@ class TaskManager {
159 } 159 }
160 } 160 }
161 161
162 - Widget exchange(  
163 - List<VoidCallback> disposers,  
164 - GetStateUpdate setState,  
165 - Widget Function(BuildContext) builder,  
166 - BuildContext context,  
167 - ) { 162 + T exchange<T>(List<VoidCallback> disposers, GetStateUpdate setState,
  163 + T Function() builder) {
168 _remove = disposers; 164 _remove = disposers;
169 _setter = setState; 165 _setter = setState;
170 - final result = builder(context); 166 + final result = builder();
171 _remove = null; 167 _remove = null;
172 _setter = null; 168 _setter = null;
173 return result; 169 return result;
@@ -8,8 +8,11 @@ class MixinBuilder<T extends GetxController> extends StatelessWidget { @@ -8,8 +8,11 @@ class MixinBuilder<T extends GetxController> extends StatelessWidget {
8 final bool global; 8 final bool global;
9 final String? id; 9 final String? id;
10 final bool autoRemove; 10 final bool autoRemove;
11 - final void Function(State state)? initState, dispose, didChangeDependencies;  
12 - final void Function(GetBuilder oldWidget, State state)? didUpdateWidget; 11 + final void Function(ScopeElement<T> state)? initState,
  12 + dispose,
  13 + didChangeDependencies;
  14 + final void Function(Scope<T> oldWidget, ScopeElement<T> state)?
  15 + didUpdateWidget;
13 final T? init; 16 final T? init;
14 17
15 const MixinBuilder({ 18 const MixinBuilder({
1 import 'dart:async'; 1 import 'dart:async';
  2 +
2 import 'package:flutter/widgets.dart'; 3 import 'package:flutter/widgets.dart';
3 -import 'get_state.dart'; 4 +
4 import 'list_notifier.dart'; 5 import 'list_notifier.dart';
5 6
6 typedef ValueBuilderUpdateCallback<T> = void Function(T snapshot); 7 typedef ValueBuilderUpdateCallback<T> = void Function(T snapshot);
@@ -74,35 +75,39 @@ class _ValueBuilderState<T> extends State<ValueBuilder<T?>> { @@ -74,35 +75,39 @@ class _ValueBuilderState<T> extends State<ValueBuilder<T?>> {
74 } 75 }
75 } 76 }
76 77
  78 +class ObxElement = StatelessElement with ObserverComponent;
  79 +
77 // It's a experimental feature 80 // It's a experimental feature
78 -class SimpleBuilder extends StatefulWidget {  
79 - final Widget Function(BuildContext) builder; 81 +class SimpleBuilder extends ObxStatelessWidget {
  82 + final WidgetBuilder builder;
80 83
81 const SimpleBuilder({Key? key, required this.builder}) : super(key: key); 84 const SimpleBuilder({Key? key, required this.builder}) : super(key: key);
82 85
83 @override 86 @override
84 - _SimpleBuilderState createState() => _SimpleBuilderState(); 87 + Widget build(BuildContext context) => builder(context);
85 } 88 }
86 89
87 -class _SimpleBuilderState extends State<SimpleBuilder>  
88 - with GetStateUpdaterMixin { 90 +/// A StatelessWidget than can listen reactive changes.
  91 +abstract class ObxStatelessWidget extends StatelessWidget {
  92 + /// Initializes [key] for subclasses.
  93 + const ObxStatelessWidget({Key? key}) : super(key: key);
  94 + @override
  95 + StatelessElement createElement() => ObxElement(this);
  96 +}
  97 +
  98 +/// a Component that can track changes in a reactive variable
  99 +mixin ObserverComponent on ComponentElement {
89 final disposers = <Disposer>[]; 100 final disposers = <Disposer>[];
90 101
91 @override 102 @override
92 - void dispose() {  
93 - super.dispose(); 103 + Widget build() =>
  104 + TaskManager.instance.exchange(disposers, markNeedsBuild, super.build);
  105 +
  106 + @override
  107 + void unmount() {
  108 + super.unmount();
94 for (final disposer in disposers) { 109 for (final disposer in disposers) {
95 disposer(); 110 disposer();
96 } 111 }
97 } 112 }
98 -  
99 - @override  
100 - Widget build(BuildContext context) {  
101 - return TaskManager.instance.exchange(  
102 - disposers,  
103 - getUpdate,  
104 - widget.builder,  
105 - context,  
106 - );  
107 - }  
108 } 113 }
No preview for this file type