Jonny Borges
Committed by GitHub

Merge pull request #2051 from jonataslaw/4.6.0

bump to 4.6.0
## [4.5.1] - Big Update
## [4.6.0]
Add useInheritedMediaQuery to GetMaterialApp and GetCupertinoApp (@davidhole)
Add Circular reveal Transition (@parmarravi)
Add request to failed response (@heftekharm)
Fix internationalization with only country code (@codercengiz)
Add GetTickerProviderStateMixin when multiple AnimationController objects are used (@NatsuOnFire)
Add the followRedirects and maxRedirects fields to the Request object (@wei53881)
Fix to rx.trigger fires twice (@gslender)
Add proxy setting support to GetConnect (@jtans)
Fix markAsDirty used on permanent controllers (@zenalex)
Update Korean readme (@dumbokim)
## [4.5.1]
Fix Snackbar when it have action and icon the same time
## [4.5.0] - Big Update
To have a context-free, page-agnostic snackbar, we used OverlayRoute to display a partial route.
To have a page-agnostic snackbar, we used OverlayRoute to display a partial route.
However this had several problems:
1: There was no possibility to close the page without closing the snackbar
... ...
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
... ...
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
... ...
class Logger {
mixin Logger {
// Sample of abstract logging function
static void write(String text, {bool isError = false}) {
Future.microtask(() => print('** $text. isError: [$isError]'));
... ...
... ... @@ -125,18 +125,17 @@ class GetConnect extends GetConnectInterface {
@override
GetHttpClient get httpClient => _httpClient ??= GetHttpClient(
userAgent: userAgent,
sendUserAgent: sendUserAgent,
timeout: timeout,
followRedirects: followRedirects,
maxRedirects: maxRedirects,
maxAuthRetries: maxAuthRetries,
allowAutoSignedCert: allowAutoSignedCert,
baseUrl: baseUrl,
trustedCertificates: trustedCertificates,
withCredentials: withCredentials,
findProxy: findProxy
);
userAgent: userAgent,
sendUserAgent: sendUserAgent,
timeout: timeout,
followRedirects: followRedirects,
maxRedirects: maxRedirects,
maxAuthRetries: maxAuthRetries,
allowAutoSignedCert: allowAutoSignedCert,
baseUrl: baseUrl,
trustedCertificates: trustedCertificates,
withCredentials: withCredentials,
findProxy: findProxy);
@override
Future<Response<T>> get<T>(
... ...
... ... @@ -199,16 +199,16 @@ class GetHttpClient {
int requestNumber = 1,
Map<String, String>? headers,
}) async {
var request = await handler();
var request = await handler();
headers?.forEach((key, value) {
request.headers[key] = value;
});
headers?.forEach((key, value) {
request.headers[key] = value;
});
if (authenticate) await _modifier.authenticator!(request);
final newRequest = await _modifier.modifyRequest<T>(request);
if (authenticate) await _modifier.authenticator!(request);
final newRequest = await _modifier.modifyRequest<T>(request);
_httpClient.timeout = timeout;
_httpClient.timeout = timeout;
try {
var response = await _httpClient.send<T>(newRequest);
... ...
import '../../get_core/src/get_interface.dart';
import '../../route_manager.dart';
import 'get_instance.dart';
... ...
... ... @@ -9,9 +9,6 @@ import '../../get_utils/get_utils.dart';
import '../get_navigation.dart';
import 'dialog/dialog_route.dart';
import 'root/parse_route.dart';
import 'root/root_controller.dart';
import 'routes/transitions_type.dart';
import 'snackbar/snackbar_controller.dart';
/// It replaces the Flutter Navigator, but needs no context.
/// You can to use navigator.push(YourRoute()) rather
... ...
import 'package:flutter/material.dart';
import '../../../get.dart';
import 'get_router_delegate.dart';
class RouterOutlet<TDelegate extends RouterDelegate<T>, T extends Object>
extends StatefulWidget {
... ...
... ... @@ -7,7 +7,6 @@ import '../../../get_instance/get_instance.dart';
import '../../../get_state_manager/get_state_manager.dart';
import '../../../get_utils/get_utils.dart';
import '../../get_navigation.dart';
import 'root_controller.dart';
class GetCupertinoApp extends StatelessWidget {
final GlobalKey<NavigatorState>? navigatorKey;
... ...
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
... ... @@ -7,7 +6,6 @@ import '../../../get_instance/get_instance.dart';
import '../../../get_state_manager/get_state_manager.dart';
import '../../../get_utils/get_utils.dart';
import '../../get_navigation.dart';
import 'root_controller.dart';
class GetMaterialApp extends StatelessWidget {
final GlobalKey<NavigatorState>? navigatorKey;
... ...
import '../../get_navigation.dart';
import '../routes/get_route.dart';
class RouteDecoder {
final List<GetPage> treeBranch;
... ...
import 'package:flutter/material.dart';
import '../../../get.dart';
import '../../../get_state_manager/get_state_manager.dart';
import '../../../get_utils/get_utils.dart';
import '../routes/custom_transition.dart';
import '../routes/observers/route_observer.dart';
import '../routes/transitions_type.dart';
class GetMaterialController extends SuperController {
bool testMode = false;
... ...
... ... @@ -20,8 +20,8 @@ class CircularRevealClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
final Offset center = this.centerAlignment?.alongSize(size) ??
this.centerOffset ??
final center = centerAlignment?.alongSize(size) ??
centerOffset ??
Offset(size.width / 2, size.height / 2);
final minRadius = this.minRadius ?? 0;
final maxRadius = this.maxRadius ?? calcMaxRadius(size, center);
... ... @@ -44,4 +44,3 @@ class CircularRevealClipper extends CustomClipper<Path> {
return sqrt(w * w + h * h);
}
}
... ...
... ... @@ -2,10 +2,7 @@ import 'package:flutter/material.dart';
import '../../../get.dart';
import '../router_report.dart';
import 'custom_transition.dart';
import 'get_transition_mixin.dart';
import 'route_middleware.dart';
import 'transitions_type.dart';
mixin PageRouteReportMixin<T> on Route<T> {
@override
... ...
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'circular_reveal_clipper.dart';
class LeftToRightFadeTransition {
Widget buildTransitions(
BuildContext context,
... ... @@ -185,7 +187,6 @@ class SizeTransitions {
}
}
class CircularRevealTransition {
Widget buildTransitions(
BuildContext context,
... ... @@ -197,7 +198,7 @@ class CircularRevealTransition {
return ClipPath(
clipper: CircularRevealClipper(
fraction: animation.value,
centerAlignment: Alignment.center,
centerAlignment: Alignment.center,
centerOffset: Offset.zero,
minRadius: 0,
maxRadius: 800,
... ... @@ -206,4 +207,3 @@ class CircularRevealTransition {
);
}
}
... ...
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import '../../../get_core/src/get_main.dart';
import '../../../get_instance/get_instance.dart';
import '../../get_navigation.dart';
import 'custom_transition.dart';
import 'transitions_type.dart';
class GetPage<T> extends Page<T> {
final GetPageBuilder page;
... ...
... ... @@ -8,7 +8,6 @@ import 'package:flutter/material.dart';
import '../../../get.dart';
import 'default_transitions.dart';
import 'transitions_type.dart';
const double _kBackGestureWidth = 20.0;
const int _kMaxDroppedSwipePageForwardAnimationTime =
... ... @@ -619,8 +618,8 @@ Cannot read the previousTitle for a route that has not yet been installed''',
onStartPopGesture: () => _startPopGesture<T>(route),
child: child)
: child);
case Transition.ciruclarReveal:
case Transition.circularReveal:
return CircularRevealTransition().buildTransitions(
context,
route.curve,
... ... @@ -629,11 +628,11 @@ Cannot read the previousTitle for a route that has not yet been installed''',
secondaryAnimation,
route.popGesture ?? Get.defaultPopGesture
? CupertinoBackGestureDetector<T>(
gestureWidth: route.gestureWidth?.call(context) ??
_kBackGestureWidth,
enabledCallback: () => _isPopGestureEnabled<T>(route),
onStartPopGesture: () => _startPopGesture<T>(route),
child: child)
gestureWidth: route.gestureWidth?.call(context) ??
_kBackGestureWidth,
enabledCallback: () => _isPopGestureEnabled<T>(route),
onStartPopGesture: () => _startPopGesture<T>(route),
child: child)
: child);
default:
... ...
... ... @@ -5,7 +5,6 @@ import '../../../../instance_manager.dart';
import '../../../get_navigation.dart';
import '../../dialog/dialog_route.dart';
import '../../router_report.dart';
import '../default_route.dart';
/// Extracts the name of a route based on it's instance type
/// or null if not possible.
... ...
... ... @@ -15,7 +15,8 @@ enum Transition {
cupertino,
cupertinoDialog,
size,
native
circularReveal,
native,
}
typedef GetPageBuilder = Widget Function();
... ...
... ... @@ -113,7 +113,8 @@ mixin GetTickerProviderStateMixin on GetxController implements TickerProvider {
@override
Ticker createTicker(TickerCallback onTick) {
_tickers ??= <_WidgetTicker>{};
final result = _WidgetTicker(onTick, this, debugLabel: kDebugMode ? 'created by ${describeIdentity(this)}' : null);
final result = _WidgetTicker(onTick, this,
debugLabel: kDebugMode ? 'created by ${describeIdentity(this)}' : null);
_tickers!.add(result);
return result;
}
... ... @@ -143,13 +144,13 @@ mixin GetTickerProviderStateMixin on GetxController implements TickerProvider {
ErrorSummary('$this was disposed with an active Ticker.'),
ErrorDescription(
'$runtimeType created a Ticker via its GetTickerProviderStateMixin, but at the time '
'dispose() was called on the mixin, that Ticker was still active. All Tickers must '
'be disposed before calling super.dispose().',
'dispose() was called on the mixin, that Ticker was still active. All Tickers must '
'be disposed before calling super.dispose().',
),
ErrorHint(
'Tickers used by AnimationControllers '
'should be disposed by calling dispose() on the AnimationController itself. '
'Otherwise, the ticker will leak.',
'should be disposed by calling dispose() on the AnimationController itself. '
'Otherwise, the ticker will leak.',
),
ticker.describeForError('The offending ticker was'),
]);
... ... @@ -160,11 +161,11 @@ mixin GetTickerProviderStateMixin on GetxController implements TickerProvider {
}());
super.onClose();
}
}
class _WidgetTicker extends Ticker {
_WidgetTicker(TickerCallback onTick, this._creator, { String? debugLabel }) : super(onTick, debugLabel: debugLabel);
_WidgetTicker(TickerCallback onTick, this._creator, {String? debugLabel})
: super(onTick, debugLabel: debugLabel);
final GetTickerProviderStateMixin _creator;
... ...
import 'package:flutter/widgets.dart';
import '../../../get.dart';
import 'get_view.dart';
mixin GetResponsiveMixin on Widget {
ResponsiveScreen get screen;
... ...
import 'dart:collection';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
// This callback remove the listener on addListener function
... ...
import 'package:flutter/material.dart';
import '../../get_state_manager.dart';
import 'get_state.dart';
class MixinBuilder<T extends GetxController> extends StatelessWidget {
@required
... ...
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import '../platform/platform.dart';
... ...
... ... @@ -68,8 +68,8 @@ extension Trans on String {
Map<String, String>? get _getSimilarLanguageTranslation {
final translationsWithNoCountry = Get.translations
.map((key, value) => MapEntry(key.split("_").first, value));
final containsKey =
translationsWithNoCountry.containsKey(Get.locale!.languageCode.split("_").first);
final containsKey = translationsWithNoCountry
.containsKey(Get.locale!.languageCode.split("_").first);
if (!containsKey) {
return null;
... ...
name: get
description: Open screens/snackbars/dialogs without context, manage states and inject dependencies easily with GetX.
version: 4.5.1
version: 4.6.0
homepage: https://github.com/jonataslaw/getx
environment:
... ...
// ignore_for_file: avoid_classes_with_only_static_members
import 'package:flutter_test/flutter_test.dart';
import 'package:get/get.dart';
... ... @@ -146,8 +148,8 @@ void main() {
Get.create<Service>(() => Api());
final ct1 = Get.find<Service>();
final ct2 = Get.find<Service>();
expect(ct1 is Service, true);
expect(ct2 is Service, true);
// expect(ct1 is Service, true);
// expect(ct2 is Service, true);
expect(ct1 == ct2, false);
Get.reset();
});
... ...
... ... @@ -336,7 +336,10 @@ void main() {
testWidgets("Get.back navigates back", (tester) async {
await tester.pumpWidget(
Wrapper(child: FirstScreen()),
Wrapper(
child: FirstScreen(),
defaultTransition: Transition.circularReveal,
),
);
Get.to(SecondScreen());
... ...
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:get/get.dart';
... ...
... ... @@ -114,6 +114,23 @@ void main() {
expect(1, timesCalled);
});
test('Rx different value will call the listener when `trigger`', () async {
var reactiveInteger = RxInt(0);
var timesCalled = 0;
reactiveInteger.listen((newInt) {
timesCalled++;
});
// we call 3
reactiveInteger.trigger(1);
// then repeat twice
reactiveInteger.trigger(2);
reactiveInteger.trigger(3);
await Future.delayed(Duration(milliseconds: 100));
expect(3, timesCalled);
});
test('Rx same value will call the listener when `trigger`', () async {
var reactiveInteger = RxInt(2);
var timesCalled = 0;
... ... @@ -125,10 +142,11 @@ void main() {
reactiveInteger.trigger(3);
// then repeat twice
reactiveInteger.trigger(3);
reactiveInteger.trigger(3);
reactiveInteger.trigger(1);
await Future.delayed(Duration(milliseconds: 100));
expect(3, timesCalled);
expect(4, timesCalled);
});
test('Rx String with non null values', () async {
... ...