Ahmed Fwela

Merge branch 'master' of git://github.com/jonataslaw/getx

Showing 39 changed files with 413 additions and 133 deletions
No preview for this file type
@@ -23,7 +23,7 @@ jobs: @@ -23,7 +23,7 @@ jobs:
23 # https://github.com/marketplace/actions/flutter-action 23 # https://github.com/marketplace/actions/flutter-action
24 - uses: subosito/flutter-action@v1 24 - uses: subosito/flutter-action@v1
25 with: 25 with:
26 - flutter-version: "2.2.3" 26 + flutter-version: "2.8.0"
27 channel: "stable" 27 channel: "stable"
28 - run: flutter pub get 28 - run: flutter pub get
29 #- run: flutter analyze 29 #- run: flutter analyze
1 -## [4.5.1] - Big Update 1 +## [4.6.1]
  2 +Fix GetConnect on Flutter web
  3 +
  4 +## [4.6.0]
  5 +Add useInheritedMediaQuery to GetMaterialApp and GetCupertinoApp (@davidhole)
  6 +Add Circular reveal Transition (@parmarravi)
  7 +Add request to failed response (@heftekharm)
  8 +Fix internationalization with only country code (@codercengiz)
  9 +Add GetTickerProviderStateMixin when multiple AnimationController objects are used (@NatsuOnFire)
  10 +Add the followRedirects and maxRedirects fields to the Request object (@wei53881)
  11 +Fix to rx.trigger fires twice (@gslender)
  12 +Add proxy setting support to GetConnect (@jtans)
  13 +Fix markAsDirty used on permanent controllers (@zenalex)
  14 +Update Korean readme (@dumbokim)
  15 +
  16 +
  17 +## [4.5.1]
2 Fix Snackbar when it have action and icon the same time 18 Fix Snackbar when it have action and icon the same time
3 19
4 ## [4.5.0] - Big Update 20 ## [4.5.0] - Big Update
5 -To have a context-free, page-agnostic snackbar, we used OverlayRoute to display a partial route. 21 +To have a page-agnostic snackbar, we used OverlayRoute to display a partial route.
6 However this had several problems: 22 However this had several problems:
7 23
8 1: There was no possibility to close the page without closing the snackbar 24 1: There was no possibility to close the page without closing the snackbar
@@ -328,7 +328,7 @@ Text(controller.textFromApi); @@ -328,7 +328,7 @@ Text(controller.textFromApi);
328 328
329 ### 종속성 관리에 대한 자세한 내용 329 ### 종속성 관리에 대한 자세한 내용
330 330
331 -**종속성 관리에 대한 더 제사한 사항은 [여기](./documentation/kr_KO/dependency_management.md)에 있습니다.** 331 +**종속성 관리에 대한 더 자세한 사항은 [여기](./documentation/kr_KO/dependency_management.md)에 있습니다.**
332 332
333 # 기능들 333 # 기능들
334 334
@@ -1092,6 +1092,73 @@ class SettingsService extends GetxService { @@ -1092,6 +1092,73 @@ class SettingsService extends GetxService {
1092 따라서 앱 실행중 절대로 유지되어야 하는 클래스 인스턴스가 필요하면 1092 따라서 앱 실행중 절대로 유지되어야 하는 클래스 인스턴스가 필요하면
1093 `GetxService`를 사용하세요. 1093 `GetxService`를 사용하세요.
1094 1094
  1095 +### 테스트
  1096 +
  1097 +당신은 당신의 컨트롤러들을 생성주기를 포함하여 다른 어떤 클래스처럼 테스트할 수 있습니다 :
  1098 +
  1099 +```dart
  1100 +class Controller extends GetxController {
  1101 + @override
  1102 + void onInit() {
  1103 + super.onInit();
  1104 + //name2로 값 변경
  1105 + name.value = 'name2';
  1106 + }
  1107 +
  1108 + @override
  1109 + void onClose() {
  1110 + name.value = '';
  1111 + super.onClose();
  1112 + }
  1113 +
  1114 + final name = 'name1'.obs;
  1115 +
  1116 + void changeName() => name.value = 'name3';
  1117 +}
  1118 +
  1119 +void main() {
  1120 + test('''
  1121 +Test the state of the reactive variable "name" across all of its lifecycles''',
  1122 + () {
  1123 + /// 당신은 생성주기를 제외하고 컨트롤러를 테스트할 수 있습니다,
  1124 + /// 그러나 당신이 사용하지 않는다면 추천되지 않습니다
  1125 + /// GetX 종속성 주입
  1126 + final controller = Controller();
  1127 + expect(controller.name.value, 'name1');
  1128 +
  1129 + /// 당신이 그것을 사용한다면, 당신은 모든 것을 테스트할 수 있습니다,
  1130 + /// 각각의 생성주기 이후 어플리케이션의 상태를 포함하여.
  1131 + Get.put(controller); // onInit was called
  1132 + expect(controller.name.value, 'name2');
  1133 +
  1134 + /// 당신의 함수를 테스트하세요
  1135 + controller.changeName();
  1136 + expect(controller.name.value, 'name3');
  1137 +
  1138 + /// onClose 호출됨
  1139 + Get.delete<Controller>();
  1140 +
  1141 + expect(controller.name.value, '');
  1142 + });
  1143 +}
  1144 +```
  1145 +
  1146 +#### 팁들
  1147 +
  1148 +##### Mockito 또는 mocktail
  1149 +당신이 당신의 GetxController/GetxService를 모킹하려고 한다면, 당신은 GetxController를 extend 하고, Mock과 mixin 하라, 그렇게 되면
  1150 +
  1151 +```dart
  1152 +class NotificationServiceMock extends GetxService with Mock implements NotificationService {}
  1153 +```
  1154 +
  1155 +##### Get.reset() 사용하기
  1156 +당신이 위젯 또는 테스트 그룹을 테스트하고 있다면, 당신의 테스트의 마지막 또는 해제 때 당신의 이전 테스트에서 모든 설정을 리셋하기 위해 Get.rest을 사용하십시오
  1157 +
  1158 +##### Get.testMode
  1159 +당신이 당신의 컨트롤러에서 당신의 네비게이션을 사용하고 있다면, 당신의 메인의 시작에 `Get.testMode = true` 를 사용하십시오.
  1160 +
  1161 +
1095 # 2.0의 주요 변경점 1162 # 2.0의 주요 변경점
1096 1163
1097 1- Rx 타입들: 1164 1- Rx 타입들:
1 -import 'package:flutter/foundation.dart';  
2 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
3 import 'package:get/get.dart'; 2 import 'package:get/get.dart';
4 3
1 -import 'dart:ui';  
2 -  
3 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
4 import 'package:get/get.dart'; 2 import 'package:get/get.dart';
5 3
1 -class Logger { 1 +mixin Logger {
2 // Sample of abstract logging function 2 // Sample of abstract logging function
3 static void write(String text, {bool isError = false}) { 3 static void write(String text, {bool isError = false}) {
4 Future.microtask(() => print('** $text. isError: [$isError]')); 4 Future.microtask(() => print('** $text. isError: [$isError]'));
@@ -115,6 +115,7 @@ class GetConnect extends GetConnectInterface { @@ -115,6 +115,7 @@ class GetConnect extends GetConnectInterface {
115 Decoder? defaultDecoder; 115 Decoder? defaultDecoder;
116 Duration timeout; 116 Duration timeout;
117 List<TrustedCertificate>? trustedCertificates; 117 List<TrustedCertificate>? trustedCertificates;
  118 + String Function(Uri url)? findProxy;
118 GetHttpClient? _httpClient; 119 GetHttpClient? _httpClient;
119 List<GetSocket>? _sockets; 120 List<GetSocket>? _sockets;
120 bool withCredentials; 121 bool withCredentials;
@@ -134,7 +135,7 @@ class GetConnect extends GetConnectInterface { @@ -134,7 +135,7 @@ class GetConnect extends GetConnectInterface {
134 baseUrl: baseUrl, 135 baseUrl: baseUrl,
135 trustedCertificates: trustedCertificates, 136 trustedCertificates: trustedCertificates,
136 withCredentials: withCredentials, 137 withCredentials: withCredentials,
137 - ); 138 + findProxy: findProxy);
138 139
139 @override 140 @override
140 Future<Response<T>> get<T>( 141 Future<Response<T>> get<T>(
@@ -39,6 +39,8 @@ class GetHttpClient { @@ -39,6 +39,8 @@ class GetHttpClient {
39 39
40 final GetModifier _modifier; 40 final GetModifier _modifier;
41 41
  42 + String Function(Uri url)? findProxy;
  43 +
42 GetHttpClient({ 44 GetHttpClient({
43 this.userAgent = 'getx-client', 45 this.userAgent = 'getx-client',
44 this.timeout = const Duration(seconds: 8), 46 this.timeout = const Duration(seconds: 8),
@@ -50,10 +52,12 @@ class GetHttpClient { @@ -50,10 +52,12 @@ class GetHttpClient {
50 this.baseUrl, 52 this.baseUrl,
51 List<TrustedCertificate>? trustedCertificates, 53 List<TrustedCertificate>? trustedCertificates,
52 bool withCredentials = false, 54 bool withCredentials = false,
  55 + String Function(Uri url)? findProxy,
53 }) : _httpClient = HttpRequestImpl( 56 }) : _httpClient = HttpRequestImpl(
54 allowAutoSignedCert: allowAutoSignedCert, 57 allowAutoSignedCert: allowAutoSignedCert,
55 trustedCertificates: trustedCertificates, 58 trustedCertificates: trustedCertificates,
56 withCredentials: withCredentials, 59 withCredentials: withCredentials,
  60 + findProxy: findProxy,
57 ), 61 ),
58 _modifier = GetModifier(); 62 _modifier = GetModifier();
59 63
@@ -195,7 +199,6 @@ class GetHttpClient { @@ -195,7 +199,6 @@ class GetHttpClient {
195 int requestNumber = 1, 199 int requestNumber = 1,
196 Map<String, String>? headers, 200 Map<String, String>? headers,
197 }) async { 201 }) async {
198 - try {  
199 var request = await handler(); 202 var request = await handler();
200 203
201 headers?.forEach((key, value) { 204 headers?.forEach((key, value) {
@@ -206,6 +209,7 @@ class GetHttpClient { @@ -206,6 +209,7 @@ class GetHttpClient {
206 final newRequest = await _modifier.modifyRequest<T>(request); 209 final newRequest = await _modifier.modifyRequest<T>(request);
207 210
208 _httpClient.timeout = timeout; 211 _httpClient.timeout = timeout;
  212 + try {
209 var response = await _httpClient.send<T>(newRequest); 213 var response = await _httpClient.send<T>(newRequest);
210 214
211 final newResponse = 215 final newResponse =
@@ -242,7 +246,7 @@ class GetHttpClient { @@ -242,7 +246,7 @@ class GetHttpClient {
242 throw GetHttpException(err.toString()); 246 throw GetHttpException(err.toString());
243 } else { 247 } else {
244 return Response<T>( 248 return Response<T>(
245 - request: null, 249 + request: newRequest,
246 headers: null, 250 headers: null,
247 statusCode: null, 251 statusCode: null,
248 body: null, 252 body: null,
@@ -268,6 +272,8 @@ class GetHttpClient { @@ -268,6 +272,8 @@ class GetHttpClient {
268 headers: headers, 272 headers: headers,
269 decoder: decoder ?? (defaultDecoder as Decoder<T>?), 273 decoder: decoder ?? (defaultDecoder as Decoder<T>?),
270 contentLength: 0, 274 contentLength: 0,
  275 + followRedirects: followRedirects,
  276 + maxRedirects: maxRedirects,
271 )); 277 ));
272 } 278 }
273 279
@@ -14,6 +14,7 @@ class HttpRequestImpl implements HttpRequestBase { @@ -14,6 +14,7 @@ class HttpRequestImpl implements HttpRequestBase {
14 bool allowAutoSignedCert = true, 14 bool allowAutoSignedCert = true,
15 List<TrustedCertificate>? trustedCertificates, 15 List<TrustedCertificate>? trustedCertificates,
16 this.withCredentials = false, 16 this.withCredentials = false,
  17 + String Function(Uri url)? findProxy,
17 }); 18 });
18 19
19 /// The currently active XHRs. 20 /// The currently active XHRs.
@@ -17,6 +17,7 @@ class HttpRequestImpl extends HttpRequestBase { @@ -17,6 +17,7 @@ class HttpRequestImpl extends HttpRequestBase {
17 bool allowAutoSignedCert = true, 17 bool allowAutoSignedCert = true,
18 List<TrustedCertificate>? trustedCertificates, 18 List<TrustedCertificate>? trustedCertificates,
19 bool withCredentials = false, 19 bool withCredentials = false,
  20 + String Function(Uri url)? findProxy,
20 }) { 21 }) {
21 _httpClient = io.HttpClient(); 22 _httpClient = io.HttpClient();
22 if (trustedCertificates != null) { 23 if (trustedCertificates != null) {
@@ -29,6 +30,7 @@ class HttpRequestImpl extends HttpRequestBase { @@ -29,6 +30,7 @@ class HttpRequestImpl extends HttpRequestBase {
29 30
30 _httpClient = io.HttpClient(context: _securityContext); 31 _httpClient = io.HttpClient(context: _securityContext);
31 _httpClient!.badCertificateCallback = (_, __, ___) => allowAutoSignedCert; 32 _httpClient!.badCertificateCallback = (_, __, ___) => allowAutoSignedCert;
  33 + _httpClient!.findProxy = findProxy;
32 } 34 }
33 35
34 @override 36 @override
@@ -8,6 +8,7 @@ class HttpRequestImpl extends HttpRequestBase { @@ -8,6 +8,7 @@ class HttpRequestImpl extends HttpRequestBase {
8 bool allowAutoSignedCert = true, 8 bool allowAutoSignedCert = true,
9 List<TrustedCertificate>? trustedCertificates, 9 List<TrustedCertificate>? trustedCertificates,
10 bool withCredentials = false, 10 bool withCredentials = false,
  11 + String Function(Uri url)? findProxy,
11 }); 12 });
12 @override 13 @override
13 void close() {} 14 void close() {}
1 -import '../../get_core/src/get_interface.dart';  
2 import '../../route_manager.dart'; 1 import '../../route_manager.dart';
3 import 'get_instance.dart'; 2 import 'get_instance.dart';
4 3
@@ -232,7 +232,7 @@ class GetInstance { @@ -232,7 +232,7 @@ class GetInstance {
232 final newKey = key ?? _getKey(S, tag); 232 final newKey = key ?? _getKey(S, tag);
233 if (_singl.containsKey(newKey)) { 233 if (_singl.containsKey(newKey)) {
234 final dep = _singl[newKey]; 234 final dep = _singl[newKey];
235 - if (dep != null) { 235 + if (dep != null && !dep.permanent) {
236 dep.isDirty = true; 236 dep.isDirty = true;
237 } 237 }
238 } 238 }
@@ -9,9 +9,6 @@ import '../../get_utils/get_utils.dart'; @@ -9,9 +9,6 @@ import '../../get_utils/get_utils.dart';
9 import '../get_navigation.dart'; 9 import '../get_navigation.dart';
10 import 'dialog/dialog_route.dart'; 10 import 'dialog/dialog_route.dart';
11 import 'root/parse_route.dart'; 11 import 'root/parse_route.dart';
12 -import 'root/root_controller.dart';  
13 -import 'routes/transitions_type.dart';  
14 -import 'snackbar/snackbar_controller.dart';  
15 12
16 /// It replaces the Flutter Navigator, but needs no context. 13 /// It replaces the Flutter Navigator, but needs no context.
17 /// You can to use navigator.push(YourRoute()) rather 14 /// You can to use navigator.push(YourRoute()) rather
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 2
3 import '../../../get.dart'; 3 import '../../../get.dart';
4 -import 'get_navigator.dart';  
5 -import 'get_router_delegate.dart';  
6 4
7 class RouterOutlet<TDelegate extends RouterDelegate<T>, T extends Object> 5 class RouterOutlet<TDelegate extends RouterDelegate<T>, T extends Object>
8 extends StatefulWidget { 6 extends StatefulWidget {
1 import 'package:flutter/cupertino.dart'; 1 import 'package:flutter/cupertino.dart';
2 import 'package:flutter/foundation.dart'; 2 import 'package:flutter/foundation.dart';
3 import 'package:flutter/material.dart'; 3 import 'package:flutter/material.dart';
  4 +
4 import '../../../get_core/get_core.dart'; 5 import '../../../get_core/get_core.dart';
5 import '../../../get_instance/get_instance.dart'; 6 import '../../../get_instance/get_instance.dart';
6 import '../../../get_state_manager/get_state_manager.dart'; 7 import '../../../get_state_manager/get_state_manager.dart';
7 import '../../../get_utils/get_utils.dart'; 8 import '../../../get_utils/get_utils.dart';
8 import '../../get_navigation.dart'; 9 import '../../get_navigation.dart';
9 -import 'root_controller.dart';  
10 10
11 class GetCupertinoApp extends StatelessWidget { 11 class GetCupertinoApp extends StatelessWidget {
  12 + final GlobalKey<NavigatorState>? navigatorKey;
  13 +
  14 + final Widget? home;
  15 + final Map<String, WidgetBuilder>? routes;
  16 + final String? initialRoute;
  17 + final RouteFactory? onGenerateRoute;
  18 + final InitialRouteListFactory? onGenerateInitialRoutes;
  19 + final RouteFactory? onUnknownRoute;
  20 + final List<NavigatorObserver>? navigatorObservers;
  21 + final TransitionBuilder? builder;
  22 + final String title;
  23 + final GenerateAppTitle? onGenerateTitle;
  24 + final CustomTransition? customTransition;
  25 + final Color? color;
  26 + final Map<String, Map<String, String>>? translationsKeys;
  27 + final Translations? translations;
  28 + final TextDirection? textDirection;
  29 + final Locale? locale;
  30 + final Locale? fallbackLocale;
  31 + final Iterable<LocalizationsDelegate<dynamic>>? localizationsDelegates;
  32 + final LocaleListResolutionCallback? localeListResolutionCallback;
  33 + final LocaleResolutionCallback? localeResolutionCallback;
  34 + final Iterable<Locale> supportedLocales;
  35 + final bool showPerformanceOverlay;
  36 + final bool checkerboardRasterCacheImages;
  37 + final bool checkerboardOffscreenLayers;
  38 + final bool showSemanticsDebugger;
  39 + final bool debugShowCheckedModeBanner;
  40 + final Map<LogicalKeySet, Intent>? shortcuts;
  41 + final ThemeData? highContrastTheme;
  42 + final ThemeData? highContrastDarkTheme;
  43 + final Map<Type, Action<Intent>>? actions;
  44 + final Function(Routing?)? routingCallback;
  45 + final Transition? defaultTransition;
  46 + final bool? opaqueRoute;
  47 + final VoidCallback? onInit;
  48 + final VoidCallback? onReady;
  49 + final VoidCallback? onDispose;
  50 + final bool? enableLog;
  51 + final LogWriterCallback? logWriterCallback;
  52 + final bool? popGesture;
  53 + final SmartManagement smartManagement;
  54 + final Bindings? initialBinding;
  55 + final Duration? transitionDuration;
  56 + final bool? defaultGlobalState;
  57 + final List<GetPage>? getPages;
  58 + final GetPage? unknownRoute;
  59 + final RouteInformationProvider? routeInformationProvider;
  60 + final RouteInformationParser<Object>? routeInformationParser;
  61 + final RouterDelegate<Object>? routerDelegate;
  62 + final BackButtonDispatcher? backButtonDispatcher;
  63 + final CupertinoThemeData? theme;
  64 + final bool useInheritedMediaQuery;
12 const GetCupertinoApp({ 65 const GetCupertinoApp({
13 Key? key, 66 Key? key,
14 this.theme, 67 this.theme,
@@ -46,6 +99,7 @@ class GetCupertinoApp extends StatelessWidget { @@ -46,6 +99,7 @@ class GetCupertinoApp extends StatelessWidget {
46 this.shortcuts, 99 this.shortcuts,
47 this.smartManagement = SmartManagement.full, 100 this.smartManagement = SmartManagement.full,
48 this.initialBinding, 101 this.initialBinding,
  102 + this.useInheritedMediaQuery = false,
49 this.unknownRoute, 103 this.unknownRoute,
50 this.routingCallback, 104 this.routingCallback,
51 this.defaultTransition, 105 this.defaultTransition,
@@ -66,58 +120,6 @@ class GetCupertinoApp extends StatelessWidget { @@ -66,58 +120,6 @@ class GetCupertinoApp extends StatelessWidget {
66 backButtonDispatcher = null, 120 backButtonDispatcher = null,
67 super(key: key); 121 super(key: key);
68 122
69 - final GlobalKey<NavigatorState>? navigatorKey;  
70 - final Widget? home;  
71 - final Map<String, WidgetBuilder>? routes;  
72 - final String? initialRoute;  
73 - final RouteFactory? onGenerateRoute;  
74 - final InitialRouteListFactory? onGenerateInitialRoutes;  
75 - final RouteFactory? onUnknownRoute;  
76 - final List<NavigatorObserver>? navigatorObservers;  
77 - final TransitionBuilder? builder;  
78 - final String title;  
79 - final GenerateAppTitle? onGenerateTitle;  
80 - final CustomTransition? customTransition;  
81 - final Color? color;  
82 - final Map<String, Map<String, String>>? translationsKeys;  
83 - final Translations? translations;  
84 - final TextDirection? textDirection;  
85 - final Locale? locale;  
86 - final Locale? fallbackLocale;  
87 - final Iterable<LocalizationsDelegate<dynamic>>? localizationsDelegates;  
88 - final LocaleListResolutionCallback? localeListResolutionCallback;  
89 - final LocaleResolutionCallback? localeResolutionCallback;  
90 - final Iterable<Locale> supportedLocales;  
91 - final bool showPerformanceOverlay;  
92 - final bool checkerboardRasterCacheImages;  
93 - final bool checkerboardOffscreenLayers;  
94 - final bool showSemanticsDebugger;  
95 - final bool debugShowCheckedModeBanner;  
96 - final Map<LogicalKeySet, Intent>? shortcuts;  
97 - final ThemeData? highContrastTheme;  
98 - final ThemeData? highContrastDarkTheme;  
99 - final Map<Type, Action<Intent>>? actions;  
100 - final Function(Routing?)? routingCallback;  
101 - final Transition? defaultTransition;  
102 - final bool? opaqueRoute;  
103 - final VoidCallback? onInit;  
104 - final VoidCallback? onReady;  
105 - final VoidCallback? onDispose;  
106 - final bool? enableLog;  
107 - final LogWriterCallback? logWriterCallback;  
108 - final bool? popGesture;  
109 - final SmartManagement smartManagement;  
110 - final Bindings? initialBinding;  
111 - final Duration? transitionDuration;  
112 - final bool? defaultGlobalState;  
113 - final List<GetPage>? getPages;  
114 - final GetPage? unknownRoute;  
115 - final RouteInformationProvider? routeInformationProvider;  
116 - final RouteInformationParser<Object>? routeInformationParser;  
117 - final RouterDelegate<Object>? routerDelegate;  
118 - final BackButtonDispatcher? backButtonDispatcher;  
119 - final CupertinoThemeData? theme;  
120 -  
121 GetCupertinoApp.router({ 123 GetCupertinoApp.router({
122 Key? key, 124 Key? key,
123 this.theme, 125 this.theme,
@@ -128,6 +130,7 @@ class GetCupertinoApp extends StatelessWidget { @@ -128,6 +130,7 @@ class GetCupertinoApp extends StatelessWidget {
128 this.builder, 130 this.builder,
129 this.title = '', 131 this.title = '',
130 this.onGenerateTitle, 132 this.onGenerateTitle,
  133 + this.useInheritedMediaQuery = false,
131 this.color, 134 this.color,
132 this.highContrastTheme, 135 this.highContrastTheme,
133 this.highContrastDarkTheme, 136 this.highContrastDarkTheme,
@@ -183,31 +186,6 @@ class GetCupertinoApp extends StatelessWidget { @@ -183,31 +186,6 @@ class GetCupertinoApp extends StatelessWidget {
183 Get.routeInformationParser = routeInformationParser; 186 Get.routeInformationParser = routeInformationParser;
184 } 187 }
185 188
186 - Route<dynamic> generator(RouteSettings settings) {  
187 - return PageRedirect(settings: settings, unknownRoute: unknownRoute).page();  
188 - }  
189 -  
190 - List<Route<dynamic>> initialRoutesGenerate(String name) {  
191 - return [  
192 - PageRedirect(  
193 - settings: RouteSettings(name: name),  
194 - unknownRoute: unknownRoute,  
195 - ).page()  
196 - ];  
197 - }  
198 -  
199 - Widget defaultBuilder(BuildContext context, Widget? child) {  
200 - return Directionality(  
201 - textDirection: textDirection ??  
202 - (rtlLanguages.contains(Get.locale?.languageCode)  
203 - ? TextDirection.rtl  
204 - : TextDirection.ltr),  
205 - child: builder == null  
206 - ? (child ?? Material())  
207 - : builder!(context, child ?? Material()),  
208 - );  
209 - }  
210 -  
211 @override 189 @override
212 Widget build(BuildContext context) => GetBuilder<GetMaterialController>( 190 Widget build(BuildContext context) => GetBuilder<GetMaterialController>(
213 init: Get.rootController, 191 init: Get.rootController,
@@ -271,6 +249,7 @@ class GetCupertinoApp extends StatelessWidget { @@ -271,6 +249,7 @@ class GetCupertinoApp extends StatelessWidget {
271 showSemanticsDebugger: showSemanticsDebugger, 249 showSemanticsDebugger: showSemanticsDebugger,
272 debugShowCheckedModeBanner: debugShowCheckedModeBanner, 250 debugShowCheckedModeBanner: debugShowCheckedModeBanner,
273 shortcuts: shortcuts, 251 shortcuts: shortcuts,
  252 + useInheritedMediaQuery: useInheritedMediaQuery,
274 ) 253 )
275 : CupertinoApp( 254 : CupertinoApp(
276 key: _.unikey, 255 key: _.unikey,
@@ -310,7 +289,33 @@ class GetCupertinoApp extends StatelessWidget { @@ -310,7 +289,33 @@ class GetCupertinoApp extends StatelessWidget {
310 showSemanticsDebugger: showSemanticsDebugger, 289 showSemanticsDebugger: showSemanticsDebugger,
311 debugShowCheckedModeBanner: debugShowCheckedModeBanner, 290 debugShowCheckedModeBanner: debugShowCheckedModeBanner,
312 shortcuts: shortcuts, 291 shortcuts: shortcuts,
  292 + useInheritedMediaQuery: useInheritedMediaQuery,
313 // actions: actions, 293 // actions: actions,
314 ), 294 ),
315 ); 295 );
  296 +
  297 + Widget defaultBuilder(BuildContext context, Widget? child) {
  298 + return Directionality(
  299 + textDirection: textDirection ??
  300 + (rtlLanguages.contains(Get.locale?.languageCode)
  301 + ? TextDirection.rtl
  302 + : TextDirection.ltr),
  303 + child: builder == null
  304 + ? (child ?? Material())
  305 + : builder!(context, child ?? Material()),
  306 + );
  307 + }
  308 +
  309 + Route<dynamic> generator(RouteSettings settings) {
  310 + return PageRedirect(settings: settings, unknownRoute: unknownRoute).page();
  311 + }
  312 +
  313 + List<Route<dynamic>> initialRoutesGenerate(String name) {
  314 + return [
  315 + PageRedirect(
  316 + settings: RouteSettings(name: name),
  317 + unknownRoute: unknownRoute,
  318 + ).page()
  319 + ];
  320 + }
316 } 321 }
1 -import 'package:flutter/cupertino.dart';  
2 import 'package:flutter/foundation.dart'; 1 import 'package:flutter/foundation.dart';
3 import 'package:flutter/material.dart'; 2 import 'package:flutter/material.dart';
4 3
@@ -7,7 +6,6 @@ import '../../../get_instance/get_instance.dart'; @@ -7,7 +6,6 @@ import '../../../get_instance/get_instance.dart';
7 import '../../../get_state_manager/get_state_manager.dart'; 6 import '../../../get_state_manager/get_state_manager.dart';
8 import '../../../get_utils/get_utils.dart'; 7 import '../../../get_utils/get_utils.dart';
9 import '../../get_navigation.dart'; 8 import '../../get_navigation.dart';
10 -import 'root_controller.dart';  
11 9
12 class GetMaterialApp extends StatelessWidget { 10 class GetMaterialApp extends StatelessWidget {
13 final GlobalKey<NavigatorState>? navigatorKey; 11 final GlobalKey<NavigatorState>? navigatorKey;
@@ -67,6 +65,7 @@ class GetMaterialApp extends StatelessWidget { @@ -67,6 +65,7 @@ class GetMaterialApp extends StatelessWidget {
67 final RouteInformationParser<Object>? routeInformationParser; 65 final RouteInformationParser<Object>? routeInformationParser;
68 final RouterDelegate<Object>? routerDelegate; 66 final RouterDelegate<Object>? routerDelegate;
69 final BackButtonDispatcher? backButtonDispatcher; 67 final BackButtonDispatcher? backButtonDispatcher;
  68 + final bool useInheritedMediaQuery;
70 const GetMaterialApp({ 69 const GetMaterialApp({
71 Key? key, 70 Key? key,
72 this.navigatorKey, 71 this.navigatorKey,
@@ -78,6 +77,7 @@ class GetMaterialApp extends StatelessWidget { @@ -78,6 +77,7 @@ class GetMaterialApp extends StatelessWidget {
78 this.onGenerateRoute, 77 this.onGenerateRoute,
79 this.onGenerateInitialRoutes, 78 this.onGenerateInitialRoutes,
80 this.onUnknownRoute, 79 this.onUnknownRoute,
  80 + this.useInheritedMediaQuery = false,
81 List<NavigatorObserver> this.navigatorObservers = 81 List<NavigatorObserver> this.navigatorObservers =
82 const <NavigatorObserver>[], 82 const <NavigatorObserver>[],
83 this.builder, 83 this.builder,
@@ -142,6 +142,7 @@ class GetMaterialApp extends StatelessWidget { @@ -142,6 +142,7 @@ class GetMaterialApp extends StatelessWidget {
142 this.color, 142 this.color,
143 this.theme, 143 this.theme,
144 this.darkTheme, 144 this.darkTheme,
  145 + this.useInheritedMediaQuery = false,
145 this.highContrastTheme, 146 this.highContrastTheme,
146 this.highContrastDarkTheme, 147 this.highContrastDarkTheme,
147 this.themeMode = ThemeMode.system, 148 this.themeMode = ThemeMode.system,
@@ -271,6 +272,7 @@ class GetMaterialApp extends StatelessWidget { @@ -271,6 +272,7 @@ class GetMaterialApp extends StatelessWidget {
271 debugShowCheckedModeBanner: debugShowCheckedModeBanner, 272 debugShowCheckedModeBanner: debugShowCheckedModeBanner,
272 shortcuts: shortcuts, 273 shortcuts: shortcuts,
273 scrollBehavior: scrollBehavior, 274 scrollBehavior: scrollBehavior,
  275 + useInheritedMediaQuery: useInheritedMediaQuery,
274 ) 276 )
275 : MaterialApp( 277 : MaterialApp(
276 key: _.unikey, 278 key: _.unikey,
@@ -317,6 +319,7 @@ class GetMaterialApp extends StatelessWidget { @@ -317,6 +319,7 @@ class GetMaterialApp extends StatelessWidget {
317 debugShowCheckedModeBanner: debugShowCheckedModeBanner, 319 debugShowCheckedModeBanner: debugShowCheckedModeBanner,
318 shortcuts: shortcuts, 320 shortcuts: shortcuts,
319 scrollBehavior: scrollBehavior, 321 scrollBehavior: scrollBehavior,
  322 + useInheritedMediaQuery: useInheritedMediaQuery,
320 // actions: actions, 323 // actions: actions,
321 ), 324 ),
322 ); 325 );
1 import '../../get_navigation.dart'; 1 import '../../get_navigation.dart';
2 -import '../routes/get_route.dart';  
3 2
4 class RouteDecoder { 3 class RouteDecoder {
5 final List<GetPage> treeBranch; 4 final List<GetPage> treeBranch;
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 2
3 import '../../../get.dart'; 3 import '../../../get.dart';
4 -import '../../../get_state_manager/get_state_manager.dart';  
5 -import '../../../get_utils/get_utils.dart';  
6 -import '../routes/custom_transition.dart';  
7 -import '../routes/observers/route_observer.dart';  
8 -import '../routes/transitions_type.dart';  
9 4
10 class GetMaterialController extends SuperController { 5 class GetMaterialController extends SuperController {
11 bool testMode = false; 6 bool testMode = false;
  1 +import 'dart:math' show sqrt, max;
  2 +import 'dart:ui' show lerpDouble;
  3 +
  4 +import 'package:flutter/material.dart';
  5 +
  6 +class CircularRevealClipper extends CustomClipper<Path> {
  7 + final double fraction;
  8 + final Alignment? centerAlignment;
  9 + final Offset? centerOffset;
  10 + final double? minRadius;
  11 + final double? maxRadius;
  12 +
  13 + CircularRevealClipper({
  14 + required this.fraction,
  15 + this.centerAlignment,
  16 + this.centerOffset,
  17 + this.minRadius,
  18 + this.maxRadius,
  19 + });
  20 +
  21 + @override
  22 + Path getClip(Size size) {
  23 + final center = centerAlignment?.alongSize(size) ??
  24 + centerOffset ??
  25 + Offset(size.width / 2, size.height / 2);
  26 + final minRadius = this.minRadius ?? 0;
  27 + final maxRadius = this.maxRadius ?? calcMaxRadius(size, center);
  28 +
  29 + return Path()
  30 + ..addOval(
  31 + Rect.fromCircle(
  32 + center: center,
  33 + radius: lerpDouble(minRadius, maxRadius, fraction)!,
  34 + ),
  35 + );
  36 + }
  37 +
  38 + @override
  39 + bool shouldReclip(CustomClipper<Path> oldClipper) => true;
  40 +
  41 + static double calcMaxRadius(Size size, Offset center) {
  42 + final w = max(center.dx, size.width - center.dx);
  43 + final h = max(center.dy, size.height - center.dy);
  44 + return sqrt(w * w + h * h);
  45 + }
  46 +}
@@ -2,10 +2,7 @@ import 'package:flutter/material.dart'; @@ -2,10 +2,7 @@ import 'package:flutter/material.dart';
2 2
3 import '../../../get.dart'; 3 import '../../../get.dart';
4 import '../router_report.dart'; 4 import '../router_report.dart';
5 -import 'custom_transition.dart';  
6 import 'get_transition_mixin.dart'; 5 import 'get_transition_mixin.dart';
7 -import 'route_middleware.dart';  
8 -import 'transitions_type.dart';  
9 6
10 mixin PageRouteReportMixin<T> on Route<T> { 7 mixin PageRouteReportMixin<T> on Route<T> {
11 @override 8 @override
1 import 'package:flutter/cupertino.dart'; 1 import 'package:flutter/cupertino.dart';
2 import 'package:flutter/material.dart'; 2 import 'package:flutter/material.dart';
3 3
  4 +import 'circular_reveal_clipper.dart';
  5 +
4 class LeftToRightFadeTransition { 6 class LeftToRightFadeTransition {
5 Widget buildTransitions( 7 Widget buildTransitions(
6 BuildContext context, 8 BuildContext context,
@@ -184,3 +186,24 @@ class SizeTransitions { @@ -184,3 +186,24 @@ class SizeTransitions {
184 ); 186 );
185 } 187 }
186 } 188 }
  189 +
  190 +class CircularRevealTransition {
  191 + Widget buildTransitions(
  192 + BuildContext context,
  193 + Curve? curve,
  194 + Alignment? alignment,
  195 + Animation<double> animation,
  196 + Animation<double> secondaryAnimation,
  197 + Widget child) {
  198 + return ClipPath(
  199 + clipper: CircularRevealClipper(
  200 + fraction: animation.value,
  201 + centerAlignment: Alignment.center,
  202 + centerOffset: Offset.zero,
  203 + minRadius: 0,
  204 + maxRadius: 800,
  205 + ),
  206 + child: child,
  207 + );
  208 + }
  209 +}
1 import 'package:flutter/cupertino.dart'; 1 import 'package:flutter/cupertino.dart';
2 -import 'package:flutter/foundation.dart';  
3 import 'package:flutter/material.dart'; 2 import 'package:flutter/material.dart';
4 -import 'package:flutter/widgets.dart';  
5 3
6 import '../../../get_core/src/get_main.dart'; 4 import '../../../get_core/src/get_main.dart';
7 import '../../../get_instance/get_instance.dart'; 5 import '../../../get_instance/get_instance.dart';
8 import '../../get_navigation.dart'; 6 import '../../get_navigation.dart';
9 -import 'custom_transition.dart';  
10 -import 'transitions_type.dart';  
11 7
12 class GetPage<T> extends Page<T> { 8 class GetPage<T> extends Page<T> {
13 final GetPageBuilder page; 9 final GetPageBuilder page;
@@ -8,7 +8,6 @@ import 'package:flutter/material.dart'; @@ -8,7 +8,6 @@ import 'package:flutter/material.dart';
8 8
9 import '../../../get.dart'; 9 import '../../../get.dart';
10 import 'default_transitions.dart'; 10 import 'default_transitions.dart';
11 -import 'transitions_type.dart';  
12 11
13 const double _kBackGestureWidth = 20.0; 12 const double _kBackGestureWidth = 20.0;
14 const int _kMaxDroppedSwipePageForwardAnimationTime = 13 const int _kMaxDroppedSwipePageForwardAnimationTime =
@@ -620,6 +619,22 @@ Cannot read the previousTitle for a route that has not yet been installed''', @@ -620,6 +619,22 @@ Cannot read the previousTitle for a route that has not yet been installed''',
620 child: child) 619 child: child)
621 : child); 620 : child);
622 621
  622 + case Transition.circularReveal:
  623 + return CircularRevealTransition().buildTransitions(
  624 + context,
  625 + route.curve,
  626 + route.alignment,
  627 + animation,
  628 + secondaryAnimation,
  629 + route.popGesture ?? Get.defaultPopGesture
  630 + ? CupertinoBackGestureDetector<T>(
  631 + gestureWidth: route.gestureWidth?.call(context) ??
  632 + _kBackGestureWidth,
  633 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  634 + onStartPopGesture: () => _startPopGesture<T>(route),
  635 + child: child)
  636 + : child);
  637 +
623 default: 638 default:
624 if (Get.customTransition != null) { 639 if (Get.customTransition != null) {
625 return Get.customTransition!.buildTransition(context, route.curve, 640 return Get.customTransition!.buildTransition(context, route.curve,
@@ -5,7 +5,6 @@ import '../../../../instance_manager.dart'; @@ -5,7 +5,6 @@ import '../../../../instance_manager.dart';
5 import '../../../get_navigation.dart'; 5 import '../../../get_navigation.dart';
6 import '../../dialog/dialog_route.dart'; 6 import '../../dialog/dialog_route.dart';
7 import '../../router_report.dart'; 7 import '../../router_report.dart';
8 -import '../default_route.dart';  
9 8
10 /// Extracts the name of a route based on it's instance type 9 /// Extracts the name of a route based on it's instance type
11 /// or null if not possible. 10 /// or null if not possible.
@@ -17,7 +17,8 @@ enum Transition { @@ -17,7 +17,8 @@ enum Transition {
17 cupertino, 17 cupertino,
18 cupertinoDialog, 18 cupertinoDialog,
19 size, 19 size,
20 - native 20 + circularReveal,
  21 + native,
21 } 22 }
22 23
23 typedef GetPageBuilder = Widget Function(); 24 typedef GetPageBuilder = Widget Function();
@@ -67,6 +67,7 @@ mixin RxObjectMixin<T> on NotifyManager<T> { @@ -67,6 +67,7 @@ mixin RxObjectMixin<T> on NotifyManager<T> {
67 } 67 }
68 68
69 bool firstRebuild = true; 69 bool firstRebuild = true;
  70 + bool sentToStream = false;
70 71
71 /// Same as `toString()` but using a getter. 72 /// Same as `toString()` but using a getter.
72 String get string => value.toString(); 73 String get string => value.toString();
@@ -96,10 +97,11 @@ mixin RxObjectMixin<T> on NotifyManager<T> { @@ -96,10 +97,11 @@ mixin RxObjectMixin<T> on NotifyManager<T> {
96 /// Widget, only if it's different from the previous value. 97 /// Widget, only if it's different from the previous value.
97 set value(T val) { 98 set value(T val) {
98 if (subject.isClosed) return; 99 if (subject.isClosed) return;
  100 + sentToStream = false;
99 if (_value == val && !firstRebuild) return; 101 if (_value == val && !firstRebuild) return;
100 firstRebuild = false; 102 firstRebuild = false;
101 _value = val; 103 _value = val;
102 - 104 + sentToStream = true;
103 subject.add(_value); 105 subject.add(_value);
104 } 106 }
105 107
@@ -254,7 +256,7 @@ abstract class _RxImpl<T> extends RxNotifier<T> with RxObjectMixin<T> { @@ -254,7 +256,7 @@ abstract class _RxImpl<T> extends RxNotifier<T> with RxObjectMixin<T> {
254 value = v; 256 value = v;
255 // If it's not the first rebuild, the listeners have been called already 257 // If it's not the first rebuild, the listeners have been called already
256 // So we won't call them again. 258 // So we won't call them again.
257 - if (!firstRebuild) { 259 + if (!firstRebuild && !sentToStream) {
258 subject.add(v); 260 subject.add(v);
259 } 261 }
260 } 262 }
@@ -36,13 +36,13 @@ mixin GetSingleTickerProviderStateMixin on GetxController @@ -36,13 +36,13 @@ mixin GetSingleTickerProviderStateMixin on GetxController
36 if (_ticker == null) return true; 36 if (_ticker == null) return true;
37 throw FlutterError.fromParts(<DiagnosticsNode>[ 37 throw FlutterError.fromParts(<DiagnosticsNode>[
38 ErrorSummary( 38 ErrorSummary(
39 - '$runtimeType is a SingleTickerProviderStateMixin but multiple tickers were created.'), 39 + '$runtimeType is a GetSingleTickerProviderStateMixin but multiple tickers were created.'),
40 ErrorDescription( 40 ErrorDescription(
41 - 'A SingleTickerProviderStateMixin can only be used as a TickerProvider once.'), 41 + 'A GetSingleTickerProviderStateMixin can only be used as a TickerProvider once.'),
42 ErrorHint( 42 ErrorHint(
43 'If a State is used for multiple AnimationController objects, or if it is passed to other ' 43 'If a State is used for multiple AnimationController objects, or if it is passed to other '
44 'objects and those objects might use it more than one time in total, then instead of ' 44 'objects and those objects might use it more than one time in total, then instead of '
45 - 'mixing in a SingleTickerProviderStateMixin, use a regular TickerProviderStateMixin.', 45 + 'mixing in a GetSingleTickerProviderStateMixin, use a regular GetTickerProviderStateMixin.',
46 ), 46 ),
47 ]); 47 ]);
48 }()); 48 }());
@@ -66,7 +66,7 @@ mixin GetSingleTickerProviderStateMixin on GetxController @@ -66,7 +66,7 @@ mixin GetSingleTickerProviderStateMixin on GetxController
66 throw FlutterError.fromParts(<DiagnosticsNode>[ 66 throw FlutterError.fromParts(<DiagnosticsNode>[
67 ErrorSummary('$this was disposed with an active Ticker.'), 67 ErrorSummary('$this was disposed with an active Ticker.'),
68 ErrorDescription( 68 ErrorDescription(
69 - '$runtimeType created a Ticker via its SingleTickerProviderStateMixin, but at the time ' 69 + '$runtimeType created a Ticker via its GetSingleTickerProviderStateMixin, but at the time '
70 'dispose() was called on the mixin, that Ticker was still active. The Ticker must ' 70 'dispose() was called on the mixin, that Ticker was still active. The Ticker must '
71 'be disposed before calling super.dispose().', 71 'be disposed before calling super.dispose().',
72 ), 72 ),
@@ -82,6 +82,100 @@ mixin GetSingleTickerProviderStateMixin on GetxController @@ -82,6 +82,100 @@ mixin GetSingleTickerProviderStateMixin on GetxController
82 } 82 }
83 } 83 }
84 84
  85 +/// Used like `TickerProviderMixin` but only with Get Controllers.
  86 +/// Simplifies multiple AnimationController creation inside GetxController.
  87 +///
  88 +/// Example:
  89 +///```
  90 +///class SplashController extends GetxController with
  91 +/// GetTickerProviderStateMixin {
  92 +/// AnimationController first_controller;
  93 +/// AnimationController second_controller;
  94 +///
  95 +/// @override
  96 +/// void onInit() {
  97 +/// final duration = const Duration(seconds: 2);
  98 +/// first_controller =
  99 +/// AnimationController.unbounded(duration: duration, vsync: this);
  100 +/// second_controller =
  101 +/// AnimationController.unbounded(duration: duration, vsync: this);
  102 +/// first_controller.repeat();
  103 +/// first_controller.addListener(() =>
  104 +/// print("Animation Controller value: ${first_controller.value}"));
  105 +/// second_controller.addListener(() =>
  106 +/// print("Animation Controller value: ${second_controller.value}"));
  107 +/// }
  108 +/// ...
  109 +/// ```
  110 +mixin GetTickerProviderStateMixin on GetxController implements TickerProvider {
  111 + Set<Ticker>? _tickers;
  112 +
  113 + @override
  114 + Ticker createTicker(TickerCallback onTick) {
  115 + _tickers ??= <_WidgetTicker>{};
  116 + final result = _WidgetTicker(onTick, this,
  117 + debugLabel: kDebugMode ? 'created by ${describeIdentity(this)}' : null);
  118 + _tickers!.add(result);
  119 + return result;
  120 + }
  121 +
  122 + void _removeTicker(_WidgetTicker ticker) {
  123 + assert(_tickers != null);
  124 + assert(_tickers!.contains(ticker));
  125 + _tickers!.remove(ticker);
  126 + }
  127 +
  128 + void didChangeDependencies(BuildContext context) {
  129 + final muted = !TickerMode.of(context);
  130 + if (_tickers != null) {
  131 + for (final ticker in _tickers!) {
  132 + ticker.muted = muted;
  133 + }
  134 + }
  135 + }
  136 +
  137 + @override
  138 + void onClose() {
  139 + assert(() {
  140 + if (_tickers != null) {
  141 + for (final ticker in _tickers!) {
  142 + if (ticker.isActive) {
  143 + throw FlutterError.fromParts(<DiagnosticsNode>[
  144 + ErrorSummary('$this was disposed with an active Ticker.'),
  145 + ErrorDescription(
  146 + '$runtimeType created a Ticker via its GetTickerProviderStateMixin, but at the time '
  147 + 'dispose() was called on the mixin, that Ticker was still active. All Tickers must '
  148 + 'be disposed before calling super.dispose().',
  149 + ),
  150 + ErrorHint(
  151 + 'Tickers used by AnimationControllers '
  152 + 'should be disposed by calling dispose() on the AnimationController itself. '
  153 + 'Otherwise, the ticker will leak.',
  154 + ),
  155 + ticker.describeForError('The offending ticker was'),
  156 + ]);
  157 + }
  158 + }
  159 + }
  160 + return true;
  161 + }());
  162 + super.onClose();
  163 + }
  164 +}
  165 +
  166 +class _WidgetTicker extends Ticker {
  167 + _WidgetTicker(TickerCallback onTick, this._creator, {String? debugLabel})
  168 + : super(onTick, debugLabel: debugLabel);
  169 +
  170 + final GetTickerProviderStateMixin _creator;
  171 +
  172 + @override
  173 + void dispose() {
  174 + _creator._removeTicker(this);
  175 + super.dispose();
  176 + }
  177 +}
  178 +
85 @Deprecated('use GetSingleTickerProviderStateMixin') 179 @Deprecated('use GetSingleTickerProviderStateMixin')
86 180
87 /// Used like `SingleTickerProviderMixin` but only with Get Controllers. 181 /// Used like `SingleTickerProviderMixin` but only with Get Controllers.
1 import 'package:flutter/widgets.dart'; 1 import 'package:flutter/widgets.dart';
2 2
3 import '../../../get.dart'; 3 import '../../../get.dart';
4 -import 'get_view.dart';  
5 4
6 mixin GetResponsiveMixin on Widget { 5 mixin GetResponsiveMixin on Widget {
7 ResponsiveScreen get screen; 6 ResponsiveScreen get screen;
1 import 'dart:collection'; 1 import 'dart:collection';
2 -import 'package:flutter/foundation.dart'; 2 +
3 import 'package:flutter/widgets.dart'; 3 import 'package:flutter/widgets.dart';
4 4
5 // This callback remove the listener on addListener function 5 // This callback remove the listener on addListener function
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
  2 +
2 import '../../get_state_manager.dart'; 3 import '../../get_state_manager.dart';
3 -import 'get_state.dart';  
4 4
5 class MixinBuilder<T extends GetxController> extends StatelessWidget { 5 class MixinBuilder<T extends GetxController> extends StatelessWidget {
6 @required 6 @required
1 import 'package:collection/collection.dart'; 1 import 'package:collection/collection.dart';
2 import 'package:flutter/material.dart'; 2 import 'package:flutter/material.dart';
3 -import 'package:flutter/widgets.dart';  
4 3
5 extension ContextExtensionss on BuildContext { 4 extension ContextExtensionss on BuildContext {
6 /// The same of [MediaQuery.of(context).size] 5 /// The same of [MediaQuery.of(context).size]
@@ -68,14 +68,14 @@ extension Trans on String { @@ -68,14 +68,14 @@ extension Trans on String {
68 Map<String, String>? get _getSimilarLanguageTranslation { 68 Map<String, String>? get _getSimilarLanguageTranslation {
69 final translationsWithNoCountry = Get.translations 69 final translationsWithNoCountry = Get.translations
70 .map((key, value) => MapEntry(key.split("_").first, value)); 70 .map((key, value) => MapEntry(key.split("_").first, value));
71 - final containsKey =  
72 - translationsWithNoCountry.containsKey(Get.locale!.languageCode); 71 + final containsKey = translationsWithNoCountry
  72 + .containsKey(Get.locale!.languageCode.split("_").first);
73 73
74 if (!containsKey) { 74 if (!containsKey) {
75 return null; 75 return null;
76 } 76 }
77 77
78 - return translationsWithNoCountry[Get.locale!.languageCode]; 78 + return translationsWithNoCountry[Get.locale!.languageCode.split("_").first];
79 } 79 }
80 80
81 String get tr { 81 String get tr {
1 name: get 1 name: get
2 description: Open screens/snackbars/dialogs without context, manage states and inject dependencies easily with GetX. 2 description: Open screens/snackbars/dialogs without context, manage states and inject dependencies easily with GetX.
3 -version: 4.5.1 3 +version: 4.6.1
4 homepage: https://github.com/jonataslaw/getx 4 homepage: https://github.com/jonataslaw/getx
5 5
6 environment: 6 environment:
  1 +// ignore_for_file: avoid_classes_with_only_static_members
  2 +
1 import 'package:flutter_test/flutter_test.dart'; 3 import 'package:flutter_test/flutter_test.dart';
2 import 'package:get/get.dart'; 4 import 'package:get/get.dart';
3 5
@@ -146,8 +148,8 @@ void main() { @@ -146,8 +148,8 @@ void main() {
146 Get.create<Service>(() => Api()); 148 Get.create<Service>(() => Api());
147 final ct1 = Get.find<Service>(); 149 final ct1 = Get.find<Service>();
148 final ct2 = Get.find<Service>(); 150 final ct2 = Get.find<Service>();
149 - expect(ct1 is Service, true);  
150 - expect(ct2 is Service, true); 151 + // expect(ct1 is Service, true);
  152 + // expect(ct2 is Service, true);
151 expect(ct1 == ct2, false); 153 expect(ct1 == ct2, false);
152 Get.reset(); 154 Get.reset();
153 }); 155 });
@@ -336,7 +336,10 @@ void main() { @@ -336,7 +336,10 @@ void main() {
336 336
337 testWidgets("Get.back navigates back", (tester) async { 337 testWidgets("Get.back navigates back", (tester) async {
338 await tester.pumpWidget( 338 await tester.pumpWidget(
339 - Wrapper(child: FirstScreen()), 339 + Wrapper(
  340 + child: FirstScreen(),
  341 + defaultTransition: Transition.circularReveal,
  342 + ),
340 ); 343 );
341 344
342 Get.to(SecondScreen()); 345 Get.to(SecondScreen());
1 import 'package:flutter/cupertino.dart'; 1 import 'package:flutter/cupertino.dart';
2 -import 'package:flutter/material.dart';  
3 import 'package:flutter_test/flutter_test.dart'; 2 import 'package:flutter_test/flutter_test.dart';
4 import 'package:get/get.dart'; 3 import 'package:get/get.dart';
5 4
@@ -114,6 +114,23 @@ void main() { @@ -114,6 +114,23 @@ void main() {
114 expect(1, timesCalled); 114 expect(1, timesCalled);
115 }); 115 });
116 116
  117 + test('Rx different value will call the listener when `trigger`', () async {
  118 + var reactiveInteger = RxInt(0);
  119 + var timesCalled = 0;
  120 + reactiveInteger.listen((newInt) {
  121 + timesCalled++;
  122 + });
  123 +
  124 + // we call 3
  125 + reactiveInteger.trigger(1);
  126 + // then repeat twice
  127 + reactiveInteger.trigger(2);
  128 + reactiveInteger.trigger(3);
  129 +
  130 + await Future.delayed(Duration(milliseconds: 100));
  131 + expect(3, timesCalled);
  132 + });
  133 +
117 test('Rx same value will call the listener when `trigger`', () async { 134 test('Rx same value will call the listener when `trigger`', () async {
118 var reactiveInteger = RxInt(2); 135 var reactiveInteger = RxInt(2);
119 var timesCalled = 0; 136 var timesCalled = 0;
@@ -126,9 +143,10 @@ void main() { @@ -126,9 +143,10 @@ void main() {
126 // then repeat twice 143 // then repeat twice
127 reactiveInteger.trigger(3); 144 reactiveInteger.trigger(3);
128 reactiveInteger.trigger(3); 145 reactiveInteger.trigger(3);
  146 + reactiveInteger.trigger(1);
129 147
130 await Future.delayed(Duration(milliseconds: 100)); 148 await Future.delayed(Duration(milliseconds: 100));
131 - expect(3, timesCalled); 149 + expect(4, timesCalled);
132 }); 150 });
133 151
134 test('Rx String with non null values', () async { 152 test('Rx String with non null values', () async {