Jonny Borges

add transition mixin

@@ -494,6 +494,7 @@ extension GetNavigation on GetInterface { @@ -494,6 +494,7 @@ extension GetNavigation on GetInterface {
494 Bindings? binding, 494 Bindings? binding,
495 bool preventDuplicates = true, 495 bool preventDuplicates = true,
496 bool? popGesture, 496 bool? popGesture,
  497 + double gestureWidth = 20,
497 }) { 498 }) {
498 var routeName = "/${page.runtimeType.toString()}"; 499 var routeName = "/${page.runtimeType.toString()}";
499 if (preventDuplicates && routeName == currentRoute) { 500 if (preventDuplicates && routeName == currentRoute) {
@@ -504,6 +505,7 @@ extension GetNavigation on GetInterface { @@ -504,6 +505,7 @@ extension GetNavigation on GetInterface {
504 opaque: opaque ?? true, 505 opaque: opaque ?? true,
505 page: _resolve(page, 'to'), 506 page: _resolve(page, 'to'),
506 routeName: routeName, 507 routeName: routeName,
  508 + gestureWidth: gestureWidth,
507 settings: RouteSettings( 509 settings: RouteSettings(
508 // name: forceRouteName ? '${a.runtimeType}' : '', 510 // name: forceRouteName ? '${a.runtimeType}' : '',
509 arguments: arguments, 511 arguments: arguments,
@@ -862,6 +864,7 @@ you can only use widgets and widget functions here'''; @@ -862,6 +864,7 @@ you can only use widgets and widget functions here''';
862 bool fullscreenDialog = false, 864 bool fullscreenDialog = false,
863 bool preventDuplicates = true, 865 bool preventDuplicates = true,
864 Duration? duration, 866 Duration? duration,
  867 + double gestureWidth = 20,
865 }) { 868 }) {
866 var routeName = "/${page.runtimeType.toString()}"; 869 var routeName = "/${page.runtimeType.toString()}";
867 if (preventDuplicates && routeName == currentRoute) { 870 if (preventDuplicates && routeName == currentRoute) {
@@ -869,6 +872,7 @@ you can only use widgets and widget functions here'''; @@ -869,6 +872,7 @@ you can only use widgets and widget functions here''';
869 } 872 }
870 return global(id).currentState?.pushReplacement(GetPageRoute( 873 return global(id).currentState?.pushReplacement(GetPageRoute(
871 opaque: opaque, 874 opaque: opaque,
  875 + gestureWidth: gestureWidth,
872 page: _resolve(page, 'off'), 876 page: _resolve(page, 'off'),
873 binding: binding, 877 binding: binding,
874 settings: RouteSettings(arguments: arguments), 878 settings: RouteSettings(arguments: arguments),
@@ -923,6 +927,7 @@ you can only use widgets and widget functions here'''; @@ -923,6 +927,7 @@ you can only use widgets and widget functions here''';
923 Transition? transition, 927 Transition? transition,
924 Curve? curve, 928 Curve? curve,
925 Duration? duration, 929 Duration? duration,
  930 + double gestureWidth = 20,
926 }) { 931 }) {
927 var routeName = "/${page.runtimeType.toString()}"; 932 var routeName = "/${page.runtimeType.toString()}";
928 933
@@ -932,6 +937,7 @@ you can only use widgets and widget functions here'''; @@ -932,6 +937,7 @@ you can only use widgets and widget functions here''';
932 popGesture: popGesture ?? defaultPopGesture, 937 popGesture: popGesture ?? defaultPopGesture,
933 page: _resolve(page, 'offAll'), 938 page: _resolve(page, 'offAll'),
934 binding: binding, 939 binding: binding,
  940 + gestureWidth: gestureWidth,
935 settings: RouteSettings(arguments: arguments), 941 settings: RouteSettings(arguments: arguments),
936 fullscreenDialog: fullscreenDialog, 942 fullscreenDialog: fullscreenDialog,
937 routeName: routeName, 943 routeName: routeName,
@@ -1054,8 +1060,8 @@ you can only use widgets and widget functions here'''; @@ -1054,8 +1060,8 @@ you can only use widgets and widget functions here''';
1054 1060
1055 return _key; 1061 return _key;
1056 } 1062 }
1057 -  
1058 - /// Casts the stored router delegate to a desired type 1063 +
  1064 + /// Casts the stored router delegate to a desired type
1059 TDelegate? delegate<TDelegate extends RouterDelegate<TPage>, TPage>() => 1065 TDelegate? delegate<TDelegate extends RouterDelegate<TPage>, TPage>() =>
1060 _routerDelegate as TDelegate?; 1066 _routerDelegate as TDelegate?;
1061 1067
@@ -174,11 +174,17 @@ class GetCupertinoApp extends StatelessWidget { @@ -174,11 +174,17 @@ class GetCupertinoApp extends StatelessWidget {
174 super(key: key); 174 super(key: key);
175 175
176 Route<dynamic> generator(RouteSettings settings) { 176 Route<dynamic> generator(RouteSettings settings) {
177 - return PageRedirect(settings, unknownRoute).page(); 177 + return PageRedirect(settings: settings, unknownRoute: unknownRoute).page();
178 } 178 }
179 179
180 - List<Route<dynamic>> initialRoutesGenerate(String name) =>  
181 - [PageRedirect(RouteSettings(name: name), unknownRoute).page()]; 180 + List<Route<dynamic>> initialRoutesGenerate(String name) {
  181 + return [
  182 + PageRedirect(
  183 + settings: RouteSettings(name: name),
  184 + unknownRoute: unknownRoute,
  185 + ).page()
  186 + ];
  187 + }
182 188
183 @override 189 @override
184 Widget build(BuildContext context) => GetBuilder<GetMaterialController>( 190 Widget build(BuildContext context) => GetBuilder<GetMaterialController>(
@@ -183,11 +183,18 @@ class GetMaterialApp extends StatelessWidget { @@ -183,11 +183,18 @@ class GetMaterialApp extends StatelessWidget {
183 initialRoute = null, 183 initialRoute = null,
184 super(key: key); 184 super(key: key);
185 185
186 - Route<dynamic> generator(RouteSettings settings) =>  
187 - PageRedirect(settings, unknownRoute).page(); 186 + Route<dynamic> generator(RouteSettings settings) {
  187 + return PageRedirect(settings: settings, unknownRoute: unknownRoute).page();
  188 + }
188 189
189 - List<Route<dynamic>> initialRoutesGenerate(String name) =>  
190 - [PageRedirect(RouteSettings(name: name), unknownRoute).page()]; 190 + List<Route<dynamic>> initialRoutesGenerate(String name) {
  191 + return [
  192 + PageRedirect(
  193 + settings: RouteSettings(name: name),
  194 + unknownRoute: unknownRoute,
  195 + ).page()
  196 + ];
  197 + }
191 198
192 @override 199 @override
193 Widget build(BuildContext context) => GetBuilder<GetMaterialController>( 200 Widget build(BuildContext context) => GetBuilder<GetMaterialController>(
1 -import 'dart:math';  
2 -import 'dart:ui' show lerpDouble;  
3 -import 'package:flutter/cupertino.dart';  
4 -import 'package:flutter/gestures.dart';  
5 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
6 -import '../../../get_core/get_core.dart';  
7 -import '../../../get_instance/get_instance.dart';  
8 -import '../../get_navigation.dart'; 2 +
  3 +import '../../../get.dart';
9 import 'custom_transition.dart'; 4 import 'custom_transition.dart';
10 -import 'default_transitions.dart'; 5 +import 'get_transition_mixin.dart';
  6 +import 'route_middleware.dart';
11 import 'transitions_type.dart'; 7 import 'transitions_type.dart';
12 8
13 -class GetPageRoute<T> extends PageRoute<T> { 9 +class GetPageRoute<T> extends PageRoute<T> with GetPageRouteTransitionMixin<T> {
  10 + /// Creates a page route for use in an iOS designed app.
  11 + ///
  12 + /// The [builder], [maintainState], and [fullscreenDialog] arguments must not
  13 + /// be null.
14 GetPageRoute({ 14 GetPageRoute({
15 RouteSettings? settings, 15 RouteSettings? settings,
16 this.transitionDuration = const Duration(milliseconds: 300), 16 this.transitionDuration = const Duration(milliseconds: 300),
17 this.opaque = true, 17 this.opaque = true,
18 this.parameter, 18 this.parameter,
  19 + this.gestureWidth = 20.0,
19 this.curve, 20 this.curve,
20 this.alignment, 21 this.alignment,
21 this.transition, 22 this.transition,
@@ -27,6 +28,7 @@ class GetPageRoute<T> extends PageRoute<T> { @@ -27,6 +28,7 @@ class GetPageRoute<T> extends PageRoute<T> {
27 this.bindings, 28 this.bindings,
28 this.routeName, 29 this.routeName,
29 this.page, 30 this.page,
  31 + this.title,
30 this.barrierLabel, 32 this.barrierLabel,
31 this.maintainState = true, 33 this.maintainState = true,
32 bool fullscreenDialog = false, 34 bool fullscreenDialog = false,
@@ -36,35 +38,23 @@ class GetPageRoute<T> extends PageRoute<T> { @@ -36,35 +38,23 @@ class GetPageRoute<T> extends PageRoute<T> {
36 38
37 @override 39 @override
38 final Duration transitionDuration; 40 final Duration transitionDuration;
39 -  
40 final GetPageBuilder? page; 41 final GetPageBuilder? page;
41 -  
42 final String? routeName; 42 final String? routeName;
43 -  
44 final String reference; 43 final String reference;
45 -  
46 final CustomTransition? customTransition; 44 final CustomTransition? customTransition;
47 -  
48 final Bindings? binding; 45 final Bindings? binding;
49 -  
50 final Map<String, String>? parameter; 46 final Map<String, String>? parameter;
51 -  
52 final List<Bindings>? bindings; 47 final List<Bindings>? bindings;
53 48
54 @override 49 @override
55 final bool opaque; 50 final bool opaque;
56 -  
57 final bool? popGesture; 51 final bool? popGesture;
58 52
59 @override 53 @override
60 final bool barrierDismissible; 54 final bool barrierDismissible;
61 -  
62 final Transition? transition; 55 final Transition? transition;
63 -  
64 final Curve? curve; 56 final Curve? curve;
65 -  
66 final Alignment? alignment; 57 final Alignment? alignment;
67 -  
68 final List<GetMiddleware>? middlewares; 58 final List<GetMiddleware>? middlewares;
69 59
70 @override 60 @override
@@ -77,308 +67,6 @@ class GetPageRoute<T> extends PageRoute<T> { @@ -77,308 +67,6 @@ class GetPageRoute<T> extends PageRoute<T> {
77 final bool maintainState; 67 final bool maintainState;
78 68
79 @override 69 @override
80 - bool canTransitionTo(TransitionRoute<dynamic> nextRoute) {  
81 - // Don't perform outgoing animation if the next route is a  
82 - // fullscreen dialog.  
83 - return nextRoute is PageRoute && !nextRoute.fullscreenDialog;  
84 - }  
85 -  
86 - static bool _isPopGestureEnabled<T>(PageRoute<T> route) {  
87 - // ignore: lines_longer_than_80_chars  
88 - if (route.isFirst ||  
89 - route.willHandlePopInternally ||  
90 - route.hasScopedWillPopCallback ||  
91 - route.fullscreenDialog ||  
92 - route.animation!.status != AnimationStatus.completed ||  
93 - route.secondaryAnimation!.status != AnimationStatus.dismissed ||  
94 - isPopGestureInProgress(route)) return false;  
95 -  
96 - return true;  
97 - }  
98 -  
99 - static _CupertinoBackGestureController<T> _startPopGesture<T>(  
100 - PageRoute<T> route) {  
101 - assert(_isPopGestureEnabled(route));  
102 -  
103 - return _CupertinoBackGestureController<T>(  
104 - navigator: route.navigator!,  
105 - controller: route.controller!,  
106 - );  
107 - }  
108 -  
109 - @override  
110 - Widget buildPage(  
111 - BuildContext? context,  
112 - Animation<double>? animation,  
113 - Animation<double>? secondaryAnimation,  
114 - ) {  
115 - // Get.reference = settings.name ?? routeName;  
116 - Get.reference = reference;  
117 -  
118 - final middlewareRunner = MiddlewareRunner(middlewares);  
119 - final bindingsToBind = middlewareRunner.runOnBindingsStart(bindings);  
120 -  
121 - binding?.dependencies();  
122 - if (bindingsToBind != null) {  
123 - for (final binding in bindingsToBind) {  
124 - binding.dependencies();  
125 - }  
126 - }  
127 -  
128 - final pageToBuild = middlewareRunner.runOnPageBuildStart(page)!;  
129 - return middlewareRunner.runOnPageBuilt(pageToBuild());  
130 - }  
131 -  
132 - static bool isPopGestureInProgress(PageRoute<dynamic> route) {  
133 - return route.navigator!.userGestureInProgress;  
134 - }  
135 -  
136 - bool get popGestureInProgress => isPopGestureInProgress(this);  
137 -  
138 - @override  
139 - Widget buildTransitions(BuildContext context, Animation<double> animation,  
140 - Animation<double> secondaryAnimation, Widget child) {  
141 - final finalCurve = curve ?? Get.defaultTransitionCurve;  
142 - final hasCurve = curve != null;  
143 - if (fullscreenDialog && transition == null) {  
144 - /// by default, if no curve is defined, use Cupertino transition in the  
145 - /// default way (no linearTransition)... otherwise take the curve passed.  
146 - return CupertinoFullscreenDialogTransition(  
147 - primaryRouteAnimation: hasCurve  
148 - ? CurvedAnimation(parent: animation, curve: finalCurve)  
149 - : animation,  
150 - secondaryRouteAnimation: secondaryAnimation,  
151 - child: child,  
152 - linearTransition: hasCurve);  
153 - }  
154 - if (customTransition != null) {  
155 - return customTransition!.buildTransition(  
156 - context,  
157 - finalCurve,  
158 - alignment,  
159 - animation,  
160 - secondaryAnimation,  
161 - popGesture ?? Get.defaultPopGesture  
162 - ? _CupertinoBackGestureDetector<T>(  
163 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
164 - onStartPopGesture: () => _startPopGesture<T>(this),  
165 - child: child)  
166 - : child,  
167 - );  
168 - }  
169 -  
170 - /// Apply the curve by default...  
171 - final iosAnimation = animation;  
172 - animation = CurvedAnimation(parent: animation, curve: finalCurve);  
173 -  
174 - switch (transition ?? Get.defaultTransition) {  
175 - case Transition.leftToRight:  
176 - return SlideLeftTransition().buildTransitions(  
177 - context,  
178 - curve,  
179 - alignment,  
180 - animation,  
181 - secondaryAnimation,  
182 - popGesture ?? Get.defaultPopGesture  
183 - ? _CupertinoBackGestureDetector<T>(  
184 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
185 - onStartPopGesture: () => _startPopGesture<T>(this),  
186 - child: child)  
187 - : child);  
188 -  
189 - case Transition.downToUp:  
190 - return SlideDownTransition().buildTransitions(  
191 - context,  
192 - curve,  
193 - alignment,  
194 - animation,  
195 - secondaryAnimation,  
196 - popGesture ?? Get.defaultPopGesture  
197 - ? _CupertinoBackGestureDetector<T>(  
198 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
199 - onStartPopGesture: () => _startPopGesture<T>(this),  
200 - child: child)  
201 - : child);  
202 -  
203 - case Transition.upToDown:  
204 - return SlideTopTransition().buildTransitions(  
205 - context,  
206 - curve,  
207 - alignment,  
208 - animation,  
209 - secondaryAnimation,  
210 - popGesture ?? Get.defaultPopGesture  
211 - ? _CupertinoBackGestureDetector<T>(  
212 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
213 - onStartPopGesture: () => _startPopGesture<T>(this),  
214 - child: child)  
215 - : child);  
216 -  
217 - case Transition.noTransition:  
218 - return popGesture ?? Get.defaultPopGesture  
219 - ? _CupertinoBackGestureDetector<T>(  
220 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
221 - onStartPopGesture: () => _startPopGesture<T>(this),  
222 - child: child)  
223 - : child;  
224 -  
225 - case Transition.rightToLeft:  
226 - return SlideRightTransition().buildTransitions(  
227 - context,  
228 - curve,  
229 - alignment,  
230 - animation,  
231 - secondaryAnimation,  
232 - popGesture ?? Get.defaultPopGesture  
233 - ? _CupertinoBackGestureDetector<T>(  
234 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
235 - onStartPopGesture: () => _startPopGesture<T>(this),  
236 - child: child)  
237 - : child);  
238 -  
239 - case Transition.zoom:  
240 - return ZoomInTransition().buildTransitions(  
241 - context,  
242 - curve,  
243 - alignment,  
244 - animation,  
245 - secondaryAnimation,  
246 - popGesture ?? Get.defaultPopGesture  
247 - ? _CupertinoBackGestureDetector<T>(  
248 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
249 - onStartPopGesture: () => _startPopGesture<T>(this),  
250 - child: child)  
251 - : child);  
252 -  
253 - case Transition.fadeIn:  
254 - return FadeInTransition().buildTransitions(  
255 - context,  
256 - curve,  
257 - alignment,  
258 - animation,  
259 - secondaryAnimation,  
260 - popGesture ?? Get.defaultPopGesture  
261 - ? _CupertinoBackGestureDetector<T>(  
262 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
263 - onStartPopGesture: () => _startPopGesture<T>(this),  
264 - child: child)  
265 - : child);  
266 -  
267 - case Transition.rightToLeftWithFade:  
268 - return RightToLeftFadeTransition().buildTransitions(  
269 - context,  
270 - curve,  
271 - alignment,  
272 - animation,  
273 - secondaryAnimation,  
274 - popGesture ?? Get.defaultPopGesture  
275 - ? _CupertinoBackGestureDetector<T>(  
276 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
277 - onStartPopGesture: () => _startPopGesture<T>(this),  
278 - child: child)  
279 - : child);  
280 -  
281 - case Transition.leftToRightWithFade:  
282 - return LeftToRightFadeTransition().buildTransitions(  
283 - context,  
284 - curve,  
285 - alignment,  
286 - animation,  
287 - secondaryAnimation,  
288 - popGesture ?? Get.defaultPopGesture  
289 - ? _CupertinoBackGestureDetector<T>(  
290 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
291 - onStartPopGesture: () => _startPopGesture<T>(this),  
292 - child: child)  
293 - : child);  
294 -  
295 - case Transition.cupertino:  
296 - return CupertinoPageTransitionsBuilder().buildTransitions(  
297 - this,  
298 - context,  
299 - iosAnimation,  
300 - secondaryAnimation,  
301 - popGesture ?? Get.defaultPopGesture  
302 - ? _CupertinoBackGestureDetector<T>(  
303 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
304 - onStartPopGesture: () => _startPopGesture<T>(this),  
305 - child: child)  
306 - : child);  
307 -  
308 - case Transition.size:  
309 - return SizeTransitions().buildTransitions(  
310 - context,  
311 - curve!,  
312 - alignment,  
313 - animation,  
314 - secondaryAnimation,  
315 - popGesture ?? Get.defaultPopGesture  
316 - ? _CupertinoBackGestureDetector<T>(  
317 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
318 - onStartPopGesture: () => _startPopGesture<T>(this),  
319 - child: child)  
320 - : child);  
321 -  
322 - case Transition.fade:  
323 - return FadeUpwardsPageTransitionsBuilder().buildTransitions(  
324 - this,  
325 - context,  
326 - animation,  
327 - secondaryAnimation,  
328 - popGesture ?? Get.defaultPopGesture  
329 - ? _CupertinoBackGestureDetector<T>(  
330 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
331 - onStartPopGesture: () => _startPopGesture<T>(this),  
332 - child: child)  
333 - : child);  
334 -  
335 - case Transition.topLevel:  
336 - return ZoomPageTransitionsBuilder().buildTransitions(  
337 - this,  
338 - context,  
339 - animation,  
340 - secondaryAnimation,  
341 - popGesture ?? Get.defaultPopGesture  
342 - ? _CupertinoBackGestureDetector<T>(  
343 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
344 - onStartPopGesture: () => _startPopGesture<T>(this),  
345 - child: child)  
346 - : child);  
347 -  
348 - case Transition.native:  
349 - return PageTransitionsTheme().buildTransitions(  
350 - this,  
351 - context,  
352 - iosAnimation,  
353 - secondaryAnimation,  
354 - popGesture ?? Get.defaultPopGesture  
355 - ? _CupertinoBackGestureDetector<T>(  
356 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
357 - onStartPopGesture: () => _startPopGesture<T>(this),  
358 - child: child)  
359 - : child);  
360 -  
361 - default:  
362 - if (Get.customTransition != null) {  
363 - return Get.customTransition!.buildTransition(  
364 - context, curve, alignment, animation, secondaryAnimation, child);  
365 - }  
366 -  
367 - return PageTransitionsTheme().buildTransitions(  
368 - this,  
369 - context,  
370 - iosAnimation,  
371 - secondaryAnimation,  
372 - popGesture ?? Get.defaultPopGesture  
373 - ? _CupertinoBackGestureDetector<T>(  
374 - enabledCallback: () => _isPopGestureEnabled<T>(this),  
375 - onStartPopGesture: () => _startPopGesture<T>(this),  
376 - child: child)  
377 - : child);  
378 - }  
379 - }  
380 -  
381 - @override  
382 void dispose() { 70 void dispose() {
383 super.dispose(); 71 super.dispose();
384 if (Get.smartManagement != SmartManagement.onlyBuilder) { 72 if (Get.smartManagement != SmartManagement.onlyBuilder) {
@@ -396,220 +84,30 @@ class GetPageRoute<T> extends PageRoute<T> { @@ -396,220 +84,30 @@ class GetPageRoute<T> extends PageRoute<T> {
396 final middlewareRunner = MiddlewareRunner(middlewares); 84 final middlewareRunner = MiddlewareRunner(middlewares);
397 middlewareRunner.runOnPageDispose(); 85 middlewareRunner.runOnPageDispose();
398 } 86 }
399 -}  
400 -  
401 -const double _kBackGestureWidth = 20.0;  
402 -const double _kMinFlingVelocity = 1.0;  
403 -const int _kMaxDroppedSwipePageForwardAnimationTime = 800; // Milliseconds.  
404 -  
405 -// The maximum time for a page to get reset to it's original position if the  
406 -// user releases a page mid swipe.  
407 -const int _kMaxPageBackAnimationTime = 300;  
408 -  
409 -class _CupertinoBackGestureDetector<T> extends StatefulWidget {  
410 - const _CupertinoBackGestureDetector({  
411 - Key? key,  
412 - required this.enabledCallback,  
413 - required this.onStartPopGesture,  
414 - required this.child,  
415 - }) : super(key: key);  
416 -  
417 - final Widget child;  
418 -  
419 - final ValueGetter<bool> enabledCallback;  
420 -  
421 - final ValueGetter<_CupertinoBackGestureController<T>> onStartPopGesture;  
422 87
423 @override 88 @override
424 - _CupertinoBackGestureDetectorState<T> createState() =>  
425 - _CupertinoBackGestureDetectorState<T>();  
426 -}  
427 -  
428 -class _CupertinoBackGestureDetectorState<T>  
429 - extends State<_CupertinoBackGestureDetector<T>> {  
430 - _CupertinoBackGestureController<T>? _backGestureController; 89 + Widget buildContent(BuildContext context) {
  90 + Get.reference = reference;
  91 + final middlewareRunner = MiddlewareRunner(middlewares);
  92 + final bindingsToBind = middlewareRunner.runOnBindingsStart(bindings);
431 93
432 - late HorizontalDragGestureRecognizer _recognizer; 94 + binding?.dependencies();
  95 + if (bindingsToBind != null) {
  96 + for (final binding in bindingsToBind) {
  97 + binding.dependencies();
  98 + }
  99 + }
433 100
434 - @override  
435 - void initState() {  
436 - super.initState();  
437 - _recognizer = HorizontalDragGestureRecognizer(debugOwner: this)  
438 - ..onStart = _handleDragStart  
439 - ..onUpdate = _handleDragUpdate  
440 - ..onEnd = _handleDragEnd  
441 - ..onCancel = _handleDragCancel; 101 + final pageToBuild = middlewareRunner.runOnPageBuildStart(page)!;
  102 + return middlewareRunner.runOnPageBuilt(pageToBuild());
442 } 103 }
443 104
444 @override 105 @override
445 - void dispose() {  
446 - _recognizer.dispose();  
447 - super.dispose();  
448 - }  
449 -  
450 - void _handleDragStart(DragStartDetails details) {  
451 - assert(mounted);  
452 - assert(_backGestureController == null);  
453 - _backGestureController = widget.onStartPopGesture();  
454 - }  
455 -  
456 - void _handleDragUpdate(DragUpdateDetails details) {  
457 - assert(mounted);  
458 - assert(_backGestureController != null);  
459 - _backGestureController!.dragUpdate(  
460 - _convertToLogical(details.primaryDelta! / context.size!.width)!);  
461 - }  
462 -  
463 - void _handleDragEnd(DragEndDetails details) {  
464 - assert(mounted);  
465 - assert(_backGestureController != null);  
466 - _backGestureController!.dragEnd(_convertToLogical(  
467 - details.velocity.pixelsPerSecond.dx / context.size!.width)!);  
468 - _backGestureController = null;  
469 - }  
470 -  
471 - void _handleDragCancel() {  
472 - assert(mounted);  
473 - // This can be called even if start is not called, paired with  
474 - // the "down" event that we don't consider here.  
475 - _backGestureController?.dragEnd(0.0);  
476 - _backGestureController = null;  
477 - }  
478 -  
479 - void _handlePointerDown(PointerDownEvent event) {  
480 - if (widget.enabledCallback()) _recognizer.addPointer(event);  
481 - }  
482 -  
483 - double? _convertToLogical(double value) {  
484 - switch (Directionality.of(context)) {  
485 - case TextDirection.rtl:  
486 - return -value;  
487 - case TextDirection.ltr:  
488 - return value;  
489 - default:  
490 - return value;  
491 - }  
492 - } 106 + final String? title;
493 107
494 @override 108 @override
495 - Widget build(BuildContext context) {  
496 - assert(debugCheckHasDirectionality(context));  
497 - // For devices with notches, the drag area needs to be larger on the side  
498 - // that has the notch.  
499 - var dragAreaWidth = Directionality.of(context) == TextDirection.ltr  
500 - ? MediaQuery.of(context).padding.left  
501 - : MediaQuery.of(context).padding.right;  
502 - dragAreaWidth = max(dragAreaWidth, _kBackGestureWidth);  
503 - return Stack(  
504 - fit: StackFit.passthrough,  
505 - children: <Widget>[  
506 - widget.child,  
507 - PositionedDirectional(  
508 - start: 0.0,  
509 - width: dragAreaWidth,  
510 - top: 0.0,  
511 - bottom: 0.0,  
512 - child: Listener(  
513 - onPointerDown: _handlePointerDown,  
514 - behavior: HitTestBehavior.translucent,  
515 - ),  
516 - ),  
517 - ],  
518 - );  
519 - }  
520 -}  
521 -  
522 -class _CupertinoBackGestureController<T> {  
523 - /// Creates a controller for an iOS-style back gesture.  
524 - ///  
525 - /// The [navigator] and [controller] arguments must not be null.  
526 - _CupertinoBackGestureController({  
527 - required this.navigator,  
528 - required this.controller,  
529 - }) {  
530 - navigator.didStartUserGesture();  
531 - }  
532 -  
533 - final AnimationController controller;  
534 - final NavigatorState navigator;  
535 -  
536 - /// The drag gesture has changed by [fractionalDelta]. The total range of the  
537 - /// drag should be 0.0 to 1.0.  
538 - void dragUpdate(double delta) {  
539 - controller.value -= delta;  
540 - }  
541 -  
542 - /// The drag gesture has ended with a horizontal motion of  
543 - /// [fractionalVelocity] as a fraction of screen width per second.  
544 - void dragEnd(double velocity) {  
545 - // Fling in the appropriate direction.  
546 - // AnimationController.fling is guaranteed to  
547 - // take at least one frame.  
548 - //  
549 - // This curve has been determined through rigorously eyeballing native iOS  
550 - // animations.  
551 - const Curve animationCurve = Curves.fastLinearToSlowEaseIn;  
552 - bool animateForward;  
553 -  
554 - // If the user releases the page before mid screen with sufficient velocity,  
555 - // or after mid screen, we should animate the page out. Otherwise, the page  
556 - // should be animated back in.  
557 - if (velocity.abs() >= _kMinFlingVelocity) {  
558 - animateForward = velocity <= 0;  
559 - } else {  
560 - animateForward = controller.value > 0.5;  
561 - } 109 + String get debugLabel => '${super.debugLabel}(${settings.name})';
562 110
563 - if (animateForward) {  
564 - // The closer the panel is to dismissing, the shorter the animation is.  
565 - // We want to cap the animation time, but we want to use a linear curve  
566 - // to determine it.  
567 - final droppedPageForwardAnimationTime = min(  
568 - lerpDouble(  
569 - _kMaxDroppedSwipePageForwardAnimationTime,  
570 - 0,  
571 - controller.value,  
572 - )!  
573 - .floor(),  
574 - _kMaxPageBackAnimationTime,  
575 - );  
576 - controller.animateTo(1.0,  
577 - duration: Duration(milliseconds: droppedPageForwardAnimationTime),  
578 - curve: animationCurve);  
579 - } else {  
580 - // This route is destined to pop at this point. Reuse navigator's pop.  
581 - navigator.pop();  
582 -  
583 - // The popping may have finished inline if already at the target  
584 - // destination.  
585 - if (controller.isAnimating) {  
586 - // Otherwise, use a custom popping animation duration and curve.  
587 - final droppedPageBackAnimationTime = lerpDouble(  
588 - 0,  
589 - _kMaxDroppedSwipePageForwardAnimationTime,  
590 - controller.value,  
591 - )!  
592 - .floor();  
593 - controller.animateBack(  
594 - 0.0,  
595 - duration: Duration(milliseconds: droppedPageBackAnimationTime),  
596 - curve: animationCurve,  
597 - );  
598 - }  
599 - }  
600 -  
601 - if (controller.isAnimating) {  
602 - // Keep the userGestureInProgress in true state so we don't change the  
603 - // curve of the page transition mid-flight since CupertinoPageTransition  
604 - // depends on userGestureInProgress.  
605 - late AnimationStatusListener animationStatusCallback;  
606 - animationStatusCallback = (status) {  
607 - navigator.didStopUserGesture();  
608 - controller.removeStatusListener(animationStatusCallback);  
609 - };  
610 - controller.addStatusListener(animationStatusCallback);  
611 - } else {  
612 - navigator.didStopUserGesture();  
613 - }  
614 - } 111 + @override
  112 + final double gestureWidth;
615 } 113 }
  1 +// import 'package:flutter/material.dart';
  2 +
  3 +// import '../../../get.dart';
  4 +// import 'custom_transition.dart';
  5 +// import 'get_transition_mixin.dart';
  6 +// import 'route_middleware.dart';
  7 +// import 'transitions_type.dart';
  8 +
  9 +// class GetPageRoute<T> extends PageRoute<T>
  10 +// with GetPageRouteTransitionMixin<T> {
  11 +// /// Creates a page route for use in an iOS designed app.
  12 +// ///
  13 +// /// The [builder], [maintainState], and [fullscreenDialog] arguments must not
  14 +// /// be null.
  15 +// GetPageRoute({
  16 +// RouteSettings? settings,
  17 +// this.transitionDuration = const Duration(milliseconds: 300),
  18 +// this.opaque = true,
  19 +// this.parameter,
  20 +// this.curve,
  21 +// this.alignment,
  22 +// this.transition,
  23 +// this.popGesture,
  24 +// this.customTransition,
  25 +// this.barrierDismissible = false,
  26 +// this.barrierColor,
  27 +// this.binding,
  28 +// this.bindings,
  29 +// this.routeName,
  30 +// this.page,
  31 +// this.title,
  32 +// this.barrierLabel,
  33 +// this.maintainState = true,
  34 +// bool fullscreenDialog = false,
  35 +// this.middlewares,
  36 +// }) : reference = "$routeName: ${settings?.hashCode ?? page.hashCode}",
  37 +// super(settings: settings, fullscreenDialog: fullscreenDialog);
  38 +
  39 +// @override
  40 +// final Duration transitionDuration;
  41 +// final GetPageBuilder? page;
  42 +// final String? routeName;
  43 +// final String reference;
  44 +// final CustomTransition? customTransition;
  45 +// final Bindings? binding;
  46 +// final Map<String, String>? parameter;
  47 +// final List<Bindings>? bindings;
  48 +
  49 +// @override
  50 +// final bool opaque;
  51 +// final bool? popGesture;
  52 +
  53 +// @override
  54 +// final bool barrierDismissible;
  55 +// final Transition? transition;
  56 +// final Curve? curve;
  57 +// final Alignment? alignment;
  58 +// final List<GetMiddleware>? middlewares;
  59 +
  60 +// @override
  61 +// final Color? barrierColor;
  62 +
  63 +// @override
  64 +// final String? barrierLabel;
  65 +
  66 +// @override
  67 +// final bool maintainState;
  68 +
  69 +// @override
  70 +// void dispose() {
  71 +// super.dispose();
  72 +// if (Get.smartManagement != SmartManagement.onlyBuilder) {
  73 +// WidgetsBinding.instance!.addPostFrameCallback((_) {
  74 +// if (Get.reference != reference) {
  75 +// GetInstance().removeDependencyByRoute("$reference");
  76 +// }
  77 +// });
  78 +// }
  79 +
  80 +// // if (Get.smartManagement != SmartManagement.onlyBuilder) {
  81 +// // GetInstance().removeDependencyByRoute("$reference");
  82 +// // }
  83 +
  84 +// final middlewareRunner = MiddlewareRunner(middlewares);
  85 +// middlewareRunner.runOnPageDispose();
  86 +// }
  87 +
  88 +// @override
  89 +// Widget buildContent(BuildContext context) {
  90 +// Get.reference = reference;
  91 +// final middlewareRunner = MiddlewareRunner(middlewares);
  92 +// final bindingsToBind = middlewareRunner.runOnBindingsStart(bindings);
  93 +
  94 +// binding?.dependencies();
  95 +// if (bindingsToBind != null) {
  96 +// for (final binding in bindingsToBind) {
  97 +// binding.dependencies();
  98 +// }
  99 +// }
  100 +
  101 +// final pageToBuild = middlewareRunner.runOnPageBuildStart(page)!;
  102 +// return middlewareRunner.runOnPageBuilt(pageToBuild());
  103 +// }
  104 +
  105 +// @override
  106 +// final String? title;
  107 +
  108 +// @override
  109 +// String get debugLabel => '${super.debugLabel}(${settings.name})';
  110 +// }
  1 +import 'package:flutter/cupertino.dart';
1 import 'package:flutter/foundation.dart'; 2 import 'package:flutter/foundation.dart';
2 import 'package:flutter/material.dart'; 3 import 'package:flutter/material.dart';
3 import 'package:flutter/widgets.dart'; 4 import 'package:flutter/widgets.dart';
@@ -36,6 +37,7 @@ class GetPage<T> extends Page<T> { @@ -36,6 +37,7 @@ class GetPage<T> extends Page<T> {
36 final Alignment? alignment; 37 final Alignment? alignment;
37 final bool maintainState; 38 final bool maintainState;
38 final bool opaque; 39 final bool opaque;
  40 + final double gestureWidth;
39 final Bindings? binding; 41 final Bindings? binding;
40 final List<Bindings> bindings; 42 final List<Bindings> bindings;
41 final CustomTransition? customTransition; 43 final CustomTransition? customTransition;
@@ -63,6 +65,7 @@ class GetPage<T> extends Page<T> { @@ -63,6 +65,7 @@ class GetPage<T> extends Page<T> {
63 required this.name, 65 required this.name,
64 required this.page, 66 required this.page,
65 this.title, 67 this.title,
  68 + this.gestureWidth = 20,
66 // RouteSettings settings, 69 // RouteSettings settings,
67 this.maintainState = true, 70 this.maintainState = true,
68 this.curve = Curves.linear, 71 this.curve = Curves.linear,
@@ -109,7 +112,7 @@ class GetPage<T> extends Page<T> { @@ -109,7 +112,7 @@ class GetPage<T> extends Page<T> {
109 return PathDecoded(RegExp('^$stringPath\$'), keys); 112 return PathDecoded(RegExp('^$stringPath\$'), keys);
110 } 113 }
111 114
112 - GetPage copy({ 115 + GetPage<T> copy({
113 String? name, 116 String? name,
114 GetPageBuilder? page, 117 GetPageBuilder? page,
115 bool? popGesture, 118 bool? popGesture,
@@ -130,6 +133,7 @@ class GetPage<T> extends Page<T> { @@ -130,6 +133,7 @@ class GetPage<T> extends Page<T> {
130 GetPage? unknownRoute, 133 GetPage? unknownRoute,
131 List<GetMiddleware>? middlewares, 134 List<GetMiddleware>? middlewares,
132 bool? preventDuplicates, 135 bool? preventDuplicates,
  136 + double? gestureWidth,
133 }) { 137 }) {
134 return GetPage( 138 return GetPage(
135 preventDuplicates: preventDuplicates ?? this.preventDuplicates, 139 preventDuplicates: preventDuplicates ?? this.preventDuplicates,
@@ -151,14 +155,17 @@ class GetPage<T> extends Page<T> { @@ -151,14 +155,17 @@ class GetPage<T> extends Page<T> {
151 children: children ?? this.children, 155 children: children ?? this.children,
152 unknownRoute: unknownRoute ?? this.unknownRoute, 156 unknownRoute: unknownRoute ?? this.unknownRoute,
153 middlewares: middlewares ?? this.middlewares, 157 middlewares: middlewares ?? this.middlewares,
  158 + gestureWidth: gestureWidth ?? this.gestureWidth,
154 ); 159 );
155 } 160 }
156 161
157 @override 162 @override
158 Route<T> createRoute(BuildContext context) { 163 Route<T> createRoute(BuildContext context) {
  164 + // return GetPageRoute<T>(settings: this, page: page);
159 return PageRedirect( 165 return PageRedirect(
160 - this,  
161 - unknownRoute,  
162 - ).page<T>(); 166 + route: this,
  167 + settings: this,
  168 + unknownRoute: unknownRoute,
  169 + ).getPageToRoute<T>(this, unknownRoute);
163 } 170 }
164 } 171 }
  1 +import 'dart:math';
  2 +import 'dart:ui';
  3 +
  4 +import 'package:flutter/cupertino.dart';
  5 +import 'package:flutter/foundation.dart';
  6 +import 'package:flutter/gestures.dart';
  7 +import 'package:flutter/material.dart';
  8 +import '../../../get.dart';
  9 +
  10 +import 'default_transitions.dart';
  11 +import 'transitions_type.dart';
  12 +
  13 +//const double _kBackGestureWidth = 20.0;
  14 +const double _kMinFlingVelocity = 1.0; // Screen widths per second.
  15 +
  16 +// An eyeballed value for the maximum time it takes
  17 +//for a page to animate forward
  18 +// if the user releases a page mid swipe.
  19 +const int _kMaxDroppedSwipePageForwardAnimationTime = 800; // Milliseconds.
  20 +
  21 +// The maximum time for a page to get reset to it's original position if the
  22 +// user releases a page mid swipe.
  23 +const int _kMaxPageBackAnimationTime = 300; // Milliseconds.
  24 +
  25 +mixin GetPageRouteTransitionMixin<T> on PageRoute<T> {
  26 + /// Builds the primary contents of the route.
  27 + @protected
  28 + Widget buildContent(BuildContext context);
  29 +
  30 + /// {@template flutter.cupertino.CupertinoRouteTransitionMixin.title}
  31 + /// A title string for this route.
  32 + ///
  33 + /// Used to auto-populate [CupertinoNavigationBar] and
  34 + /// [CupertinoSliverNavigationBar]'s `middle`/`largeTitle` widgets when
  35 + /// one is not manually supplied.
  36 + /// {@endtemplate}
  37 + String? get title;
  38 +
  39 + double get gestureWidth;
  40 +
  41 + ValueNotifier<String?>? _previousTitle;
  42 +
  43 + /// The title string of the previous [CupertinoPageRoute].
  44 + ///
  45 + /// The [ValueListenable]'s value is readable after the route is installed
  46 + /// onto a [Navigator]. The [ValueListenable] will also notify its listeners
  47 + /// if the value changes (such as by replacing the previous route).
  48 + ///
  49 + /// The [ValueListenable] itself will be null before the route is installed.
  50 + /// Its content value will be null if the previous route has no title or
  51 + /// is not a [CupertinoPageRoute].
  52 + ///
  53 + /// See also:
  54 + ///
  55 + /// * [ValueListenableBuilder], which can be used to listen and rebuild
  56 + /// widgets based on a ValueListenable.
  57 + ValueListenable<String?> get previousTitle {
  58 + assert(
  59 + _previousTitle != null,
  60 + '''
  61 +Cannot read the previousTitle for a route that has not yet been installed''',
  62 + );
  63 + return _previousTitle!;
  64 + }
  65 +
  66 + @override
  67 + void didChangePrevious(Route<dynamic>? previousRoute) {
  68 + final previousTitleString = previousRoute is CupertinoRouteTransitionMixin
  69 + ? previousRoute.title
  70 + : null;
  71 + if (_previousTitle == null) {
  72 + _previousTitle = ValueNotifier<String?>(previousTitleString);
  73 + } else {
  74 + _previousTitle!.value = previousTitleString;
  75 + }
  76 + super.didChangePrevious(previousRoute);
  77 + }
  78 +
  79 + @override
  80 + // A relatively rigorous eyeball estimation.
  81 + Duration get transitionDuration => const Duration(milliseconds: 400);
  82 +
  83 + @override
  84 + Color? get barrierColor => null;
  85 +
  86 + @override
  87 + String? get barrierLabel => null;
  88 +
  89 + @override
  90 + bool canTransitionTo(TransitionRoute<dynamic> nextRoute) {
  91 + // Don't perform outgoing animation if the next route is a
  92 + // fullscreen dialog.
  93 + return nextRoute is CupertinoRouteTransitionMixin &&
  94 + !nextRoute.fullscreenDialog;
  95 + }
  96 +
  97 + /// True if an iOS-style back swipe pop gesture is currently
  98 + /// underway for [route].
  99 + ///
  100 + /// This just check the route's [NavigatorState.userGestureInProgress].
  101 + ///
  102 + /// See also:
  103 + ///
  104 + /// * [popGestureEnabled], which returns true if a user-triggered pop gesture
  105 + /// would be allowed.
  106 + static bool isPopGestureInProgress(PageRoute<dynamic> route) {
  107 + return route.navigator!.userGestureInProgress;
  108 + }
  109 +
  110 + /// True if an iOS-style back swipe pop gesture is currently
  111 + /// underway for this route.
  112 + ///
  113 + /// See also:
  114 + ///
  115 + /// * [isPopGestureInProgress], which returns true if a Cupertino pop gesture
  116 + /// is currently underway for specific route.
  117 + /// * [popGestureEnabled], which returns true if a user-triggered pop gesture
  118 + /// would be allowed.
  119 + bool get popGestureInProgress => isPopGestureInProgress(this);
  120 +
  121 + /// Whether a pop gesture can be started by the user.
  122 + ///
  123 + /// Returns true if the user can edge-swipe to a previous route.
  124 + ///
  125 + /// Returns false once [isPopGestureInProgress] is true, but
  126 + /// [isPopGestureInProgress] can only become true if [popGestureEnabled] was
  127 + /// true first.
  128 + ///
  129 + /// This should only be used between frames, not during build.
  130 + bool get popGestureEnabled => _isPopGestureEnabled(this);
  131 +
  132 + static bool _isPopGestureEnabled<T>(PageRoute<T> route) {
  133 + // If there's nothing to go back to, then obviously we don't support
  134 + // the back gesture.
  135 + if (route.isFirst) return false;
  136 + // If the route wouldn't actually pop if we popped it, then the gesture
  137 + // would be really confusing (or would skip internal routes),
  138 + //so disallow it.
  139 + if (route.willHandlePopInternally) return false;
  140 + // If attempts to dismiss this route might be vetoed such as in a page
  141 + // with forms, then do not allow the user to dismiss the route with a swipe.
  142 + if (route.hasScopedWillPopCallback) return false;
  143 + // Fullscreen dialogs aren't dismissible by back swipe.
  144 + if (route.fullscreenDialog) return false;
  145 + // If we're in an animation already, we cannot be manually swiped.
  146 + if (route.animation!.status != AnimationStatus.completed) return false;
  147 + // If we're being popped into, we also cannot be swiped until the pop above
  148 + // it completes. This translates to our secondary animation being
  149 + // dismissed.
  150 + if (route.secondaryAnimation!.status != AnimationStatus.dismissed) {
  151 + return false;
  152 + }
  153 + // If we're in a gesture already, we cannot start another.
  154 + if (isPopGestureInProgress(route)) return false;
  155 +
  156 + // Looks like a back gesture would be welcome!
  157 + return true;
  158 + }
  159 +
  160 + @override
  161 + Widget buildPage(BuildContext context, Animation<double> animation,
  162 + Animation<double> secondaryAnimation) {
  163 + final child = buildContent(context);
  164 + final Widget result = Semantics(
  165 + scopesRoute: true,
  166 + explicitChildNodes: true,
  167 + child: child,
  168 + );
  169 + return result;
  170 + }
  171 +
  172 + // Called by CupertinoBackGestureDetector when a pop ("back") drag start
  173 + // gesture is detected. The returned controller handles all of the subsequent
  174 + // drag events.
  175 + static CupertinoBackGestureController<T> _startPopGesture<T>(
  176 + PageRoute<T> route) {
  177 + assert(_isPopGestureEnabled(route));
  178 +
  179 + return CupertinoBackGestureController<T>(
  180 + navigator: route.navigator!,
  181 + controller: route.controller!, // protected access
  182 + );
  183 + }
  184 +
  185 + /// Returns a [CupertinoFullscreenDialogTransition] if [route] is a full
  186 + /// screen dialog, otherwise a [CupertinoPageTransition] is returned.
  187 + ///
  188 + /// Used by [CupertinoPageRoute.buildTransitions].
  189 + ///
  190 + /// This method can be applied to any [PageRoute], not just
  191 + /// [CupertinoPageRoute]. It's typically used to provide a Cupertino style
  192 + /// horizontal transition for material widgets when the target platform
  193 + /// is [TargetPlatform.iOS].
  194 + ///
  195 + /// See also:
  196 + ///
  197 + /// * [CupertinoPageTransitionsBuilder], which uses this method to define a
  198 + /// [PageTransitionsBuilder] for the [PageTransitionsTheme].
  199 + static Widget buildPageTransitions<T>(
  200 + PageRoute<T> rawRoute,
  201 + BuildContext context,
  202 + Animation<double> animation,
  203 + Animation<double> secondaryAnimation,
  204 + Widget child,
  205 + ) {
  206 + // Check if the route has an animation that's currently participating
  207 + // in a back swipe gesture.
  208 + //
  209 + // In the middle of a back gesture drag, let the transition be linear to
  210 + // match finger motions.
  211 + final route = rawRoute as GetPageRoute<T>;
  212 + final linearTransition = isPopGestureInProgress(route);
  213 + final finalCurve = route.curve ?? Get.defaultTransitionCurve;
  214 + final hasCurve = route.curve != null;
  215 + if (route.fullscreenDialog && route.transition == null) {
  216 + return CupertinoFullscreenDialogTransition(
  217 + primaryRouteAnimation: hasCurve
  218 + ? CurvedAnimation(parent: animation, curve: finalCurve)
  219 + : animation,
  220 + secondaryRouteAnimation: secondaryAnimation,
  221 + child: child,
  222 + linearTransition: linearTransition,
  223 + );
  224 + } else {
  225 + if (route.customTransition != null) {
  226 + return route.customTransition!.buildTransition(
  227 + context,
  228 + finalCurve,
  229 + route.alignment,
  230 + animation,
  231 + secondaryAnimation,
  232 + route.popGesture ?? Get.defaultPopGesture
  233 + ? CupertinoBackGestureDetector<T>(
  234 + gestureWidth: route.gestureWidth,
  235 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  236 + onStartPopGesture: () => _startPopGesture<T>(route),
  237 + child: child)
  238 + : child,
  239 + );
  240 + }
  241 +
  242 + /// Apply the curve by default...
  243 + final iosAnimation = animation;
  244 + animation = CurvedAnimation(parent: animation, curve: finalCurve);
  245 +
  246 + switch (route.transition ?? Get.defaultTransition) {
  247 + case Transition.leftToRight:
  248 + return SlideLeftTransition().buildTransitions(
  249 + context,
  250 + route.curve,
  251 + route.alignment,
  252 + animation,
  253 + secondaryAnimation,
  254 + route.popGesture ?? Get.defaultPopGesture
  255 + ? CupertinoBackGestureDetector<T>(
  256 + gestureWidth: route.gestureWidth,
  257 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  258 + onStartPopGesture: () => _startPopGesture<T>(route),
  259 + child: child)
  260 + : child);
  261 +
  262 + case Transition.downToUp:
  263 + return SlideDownTransition().buildTransitions(
  264 + context,
  265 + route.curve,
  266 + route.alignment,
  267 + animation,
  268 + secondaryAnimation,
  269 + route.popGesture ?? Get.defaultPopGesture
  270 + ? CupertinoBackGestureDetector<T>(
  271 + gestureWidth: route.gestureWidth,
  272 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  273 + onStartPopGesture: () => _startPopGesture<T>(route),
  274 + child: child)
  275 + : child);
  276 +
  277 + case Transition.upToDown:
  278 + return SlideTopTransition().buildTransitions(
  279 + context,
  280 + route.curve,
  281 + route.alignment,
  282 + animation,
  283 + secondaryAnimation,
  284 + route.popGesture ?? Get.defaultPopGesture
  285 + ? CupertinoBackGestureDetector<T>(
  286 + gestureWidth: route.gestureWidth,
  287 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  288 + onStartPopGesture: () => _startPopGesture<T>(route),
  289 + child: child)
  290 + : child);
  291 +
  292 + case Transition.noTransition:
  293 + return route.popGesture ?? Get.defaultPopGesture
  294 + ? CupertinoBackGestureDetector<T>(
  295 + gestureWidth: route.gestureWidth,
  296 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  297 + onStartPopGesture: () => _startPopGesture<T>(route),
  298 + child: child)
  299 + : child;
  300 +
  301 + case Transition.rightToLeft:
  302 + return SlideRightTransition().buildTransitions(
  303 + context,
  304 + route.curve,
  305 + route.alignment,
  306 + animation,
  307 + secondaryAnimation,
  308 + route.popGesture ?? Get.defaultPopGesture
  309 + ? CupertinoBackGestureDetector<T>(
  310 + gestureWidth: route.gestureWidth,
  311 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  312 + onStartPopGesture: () => _startPopGesture<T>(route),
  313 + child: child)
  314 + : child);
  315 +
  316 + case Transition.zoom:
  317 + return ZoomInTransition().buildTransitions(
  318 + context,
  319 + route.curve,
  320 + route.alignment,
  321 + animation,
  322 + secondaryAnimation,
  323 + route.popGesture ?? Get.defaultPopGesture
  324 + ? CupertinoBackGestureDetector<T>(
  325 + gestureWidth: route.gestureWidth,
  326 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  327 + onStartPopGesture: () => _startPopGesture<T>(route),
  328 + child: child)
  329 + : child);
  330 +
  331 + case Transition.fadeIn:
  332 + return FadeInTransition().buildTransitions(
  333 + context,
  334 + route.curve,
  335 + route.alignment,
  336 + animation,
  337 + secondaryAnimation,
  338 + route.popGesture ?? Get.defaultPopGesture
  339 + ? CupertinoBackGestureDetector<T>(
  340 + gestureWidth: route.gestureWidth,
  341 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  342 + onStartPopGesture: () => _startPopGesture<T>(route),
  343 + child: child)
  344 + : child);
  345 +
  346 + case Transition.rightToLeftWithFade:
  347 + return RightToLeftFadeTransition().buildTransitions(
  348 + context,
  349 + route.curve,
  350 + route.alignment,
  351 + animation,
  352 + secondaryAnimation,
  353 + route.popGesture ?? Get.defaultPopGesture
  354 + ? CupertinoBackGestureDetector<T>(
  355 + gestureWidth: route.gestureWidth,
  356 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  357 + onStartPopGesture: () => _startPopGesture<T>(route),
  358 + child: child)
  359 + : child);
  360 +
  361 + case Transition.leftToRightWithFade:
  362 + return LeftToRightFadeTransition().buildTransitions(
  363 + context,
  364 + route.curve,
  365 + route.alignment,
  366 + animation,
  367 + secondaryAnimation,
  368 + route.popGesture ?? Get.defaultPopGesture
  369 + ? CupertinoBackGestureDetector<T>(
  370 + gestureWidth: route.gestureWidth,
  371 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  372 + onStartPopGesture: () => _startPopGesture<T>(route),
  373 + child: child)
  374 + : child);
  375 +
  376 + case Transition.cupertino:
  377 + return CupertinoPageTransition(
  378 + primaryRouteAnimation: animation,
  379 + secondaryRouteAnimation: secondaryAnimation,
  380 + linearTransition: linearTransition,
  381 + child: CupertinoBackGestureDetector<T>(
  382 + gestureWidth: route.gestureWidth,
  383 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  384 + onStartPopGesture: () => _startPopGesture<T>(route),
  385 + child: child,
  386 + ),
  387 + );
  388 +
  389 + case Transition.size:
  390 + return SizeTransitions().buildTransitions(
  391 + context,
  392 + route.curve!,
  393 + route.alignment,
  394 + animation,
  395 + secondaryAnimation,
  396 + route.popGesture ?? Get.defaultPopGesture
  397 + ? CupertinoBackGestureDetector<T>(
  398 + gestureWidth: route.gestureWidth,
  399 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  400 + onStartPopGesture: () => _startPopGesture<T>(route),
  401 + child: child)
  402 + : child);
  403 +
  404 + case Transition.fade:
  405 + return FadeUpwardsPageTransitionsBuilder().buildTransitions(
  406 + route,
  407 + context,
  408 + animation,
  409 + secondaryAnimation,
  410 + route.popGesture ?? Get.defaultPopGesture
  411 + ? CupertinoBackGestureDetector<T>(
  412 + gestureWidth: route.gestureWidth,
  413 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  414 + onStartPopGesture: () => _startPopGesture<T>(route),
  415 + child: child)
  416 + : child);
  417 +
  418 + case Transition.topLevel:
  419 + return ZoomPageTransitionsBuilder().buildTransitions(
  420 + route,
  421 + context,
  422 + animation,
  423 + secondaryAnimation,
  424 + route.popGesture ?? Get.defaultPopGesture
  425 + ? CupertinoBackGestureDetector<T>(
  426 + gestureWidth: route.gestureWidth,
  427 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  428 + onStartPopGesture: () => _startPopGesture<T>(route),
  429 + child: child)
  430 + : child);
  431 +
  432 + case Transition.native:
  433 + return PageTransitionsTheme().buildTransitions(
  434 + route,
  435 + context,
  436 + iosAnimation,
  437 + secondaryAnimation,
  438 + route.popGesture ?? Get.defaultPopGesture
  439 + ? CupertinoBackGestureDetector<T>(
  440 + gestureWidth: route.gestureWidth,
  441 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  442 + onStartPopGesture: () => _startPopGesture<T>(route),
  443 + child: child)
  444 + : child);
  445 +
  446 + default:
  447 + if (Get.customTransition != null) {
  448 + return Get.customTransition!.buildTransition(context, route.curve,
  449 + route.alignment, animation, secondaryAnimation, child);
  450 + }
  451 +
  452 + return PageTransitionsTheme().buildTransitions(
  453 + route,
  454 + context,
  455 + iosAnimation,
  456 + secondaryAnimation,
  457 + route.popGesture ?? Get.defaultPopGesture
  458 + ? CupertinoBackGestureDetector<T>(
  459 + gestureWidth: route.gestureWidth,
  460 + enabledCallback: () => _isPopGestureEnabled<T>(route),
  461 + onStartPopGesture: () => _startPopGesture<T>(route),
  462 + child: child)
  463 + : child);
  464 + }
  465 + }
  466 + }
  467 +
  468 + @override
  469 + Widget buildTransitions(BuildContext context, Animation<double> animation,
  470 + Animation<double> secondaryAnimation, Widget child) {
  471 + return buildPageTransitions<T>(
  472 + this, context, animation, secondaryAnimation, child);
  473 + }
  474 +}
  475 +
  476 +class CupertinoBackGestureDetector<T> extends StatefulWidget {
  477 + const CupertinoBackGestureDetector({
  478 + Key? key,
  479 + required this.enabledCallback,
  480 + required this.onStartPopGesture,
  481 + required this.child,
  482 + required this.gestureWidth,
  483 + }) : super(key: key);
  484 +
  485 + final Widget child;
  486 + final double gestureWidth;
  487 +
  488 + final ValueGetter<bool> enabledCallback;
  489 +
  490 + final ValueGetter<CupertinoBackGestureController<T>> onStartPopGesture;
  491 +
  492 + @override
  493 + CupertinoBackGestureDetectorState<T> createState() =>
  494 + CupertinoBackGestureDetectorState<T>();
  495 +}
  496 +
  497 +class CupertinoBackGestureDetectorState<T>
  498 + extends State<CupertinoBackGestureDetector<T>> {
  499 + CupertinoBackGestureController<T>? _backGestureController;
  500 +
  501 + late HorizontalDragGestureRecognizer _recognizer;
  502 +
  503 + @override
  504 + void initState() {
  505 + super.initState();
  506 + _recognizer = HorizontalDragGestureRecognizer(debugOwner: this)
  507 + ..onStart = _handleDragStart
  508 + ..onUpdate = _handleDragUpdate
  509 + ..onEnd = _handleDragEnd
  510 + ..onCancel = _handleDragCancel;
  511 + }
  512 +
  513 + @override
  514 + void dispose() {
  515 + _recognizer.dispose();
  516 + super.dispose();
  517 + }
  518 +
  519 + void _handleDragStart(DragStartDetails details) {
  520 + assert(mounted);
  521 + assert(_backGestureController == null);
  522 + _backGestureController = widget.onStartPopGesture();
  523 + }
  524 +
  525 + void _handleDragUpdate(DragUpdateDetails details) {
  526 + assert(mounted);
  527 + assert(_backGestureController != null);
  528 + _backGestureController!.dragUpdate(
  529 + _convertToLogical(details.primaryDelta! / context.size!.width));
  530 + }
  531 +
  532 + void _handleDragEnd(DragEndDetails details) {
  533 + assert(mounted);
  534 + assert(_backGestureController != null);
  535 + _backGestureController!.dragEnd(_convertToLogical(
  536 + details.velocity.pixelsPerSecond.dx / context.size!.width));
  537 + _backGestureController = null;
  538 + }
  539 +
  540 + void _handleDragCancel() {
  541 + assert(mounted);
  542 + // This can be called even if start is not called, paired with
  543 + // the "down" event
  544 + // that we don't consider here.
  545 + _backGestureController?.dragEnd(0.0);
  546 + _backGestureController = null;
  547 + }
  548 +
  549 + void _handlePointerDown(PointerDownEvent event) {
  550 + if (widget.enabledCallback()) _recognizer.addPointer(event);
  551 + }
  552 +
  553 + double _convertToLogical(double value) {
  554 + switch (Directionality.of(context)) {
  555 + case TextDirection.rtl:
  556 + return -value;
  557 + case TextDirection.ltr:
  558 + return value;
  559 + }
  560 + }
  561 +
  562 + @override
  563 + Widget build(BuildContext context) {
  564 + assert(debugCheckHasDirectionality(context));
  565 + // For devices with notches, the drag area needs to be larger on the side
  566 + // that has the notch.
  567 + var dragAreaWidth = Directionality.of(context) == TextDirection.ltr
  568 + ? MediaQuery.of(context).padding.left
  569 + : MediaQuery.of(context).padding.right;
  570 + dragAreaWidth = max(dragAreaWidth, widget.gestureWidth);
  571 + return Stack(
  572 + fit: StackFit.passthrough,
  573 + children: <Widget>[
  574 + widget.child,
  575 + PositionedDirectional(
  576 + start: 0.0,
  577 + width: dragAreaWidth,
  578 + top: 0.0,
  579 + bottom: 0.0,
  580 + child: Listener(
  581 + onPointerDown: _handlePointerDown,
  582 + behavior: HitTestBehavior.translucent,
  583 + ),
  584 + ),
  585 + ],
  586 + );
  587 + }
  588 +}
  589 +
  590 +class CupertinoBackGestureController<T> {
  591 + /// Creates a controller for an iOS-style back gesture.
  592 + ///
  593 + /// The [navigator] and [controller] arguments must not be null.
  594 + CupertinoBackGestureController({
  595 + required this.navigator,
  596 + required this.controller,
  597 + }) {
  598 + navigator.didStartUserGesture();
  599 + }
  600 +
  601 + final AnimationController controller;
  602 + final NavigatorState navigator;
  603 +
  604 + /// The drag gesture has changed by [fractionalDelta]. The total range of the
  605 + /// drag should be 0.0 to 1.0.
  606 + void dragUpdate(double delta) {
  607 + controller.value -= delta;
  608 + }
  609 +
  610 + /// The drag gesture has ended with a horizontal motion of
  611 + /// [fractionalVelocity] as a fraction of screen width per second.
  612 + void dragEnd(double velocity) {
  613 + // Fling in the appropriate direction.
  614 + // AnimationController.fling is guaranteed to
  615 + // take at least one frame.
  616 + //
  617 + // This curve has been determined through rigorously eyeballing native iOS
  618 + // animations.
  619 + const Curve animationCurve = Curves.fastLinearToSlowEaseIn;
  620 + final bool animateForward;
  621 +
  622 + // If the user releases the page before mid screen with sufficient velocity,
  623 + // or after mid screen, we should animate the page out. Otherwise, the page
  624 + // should be animated back in.
  625 + if (velocity.abs() >= _kMinFlingVelocity) {
  626 + animateForward = velocity <= 0;
  627 + } else {
  628 + animateForward = controller.value > 0.5;
  629 + }
  630 +
  631 + if (animateForward) {
  632 + // The closer the panel is to dismissing, the shorter the animation is.
  633 + // We want to cap the animation time, but we want to use a linear curve
  634 + // to determine it.
  635 + final droppedPageForwardAnimationTime = min(
  636 + lerpDouble(
  637 + _kMaxDroppedSwipePageForwardAnimationTime, 0, controller.value)!
  638 + .floor(),
  639 + _kMaxPageBackAnimationTime,
  640 + );
  641 + controller.animateTo(1.0,
  642 + duration: Duration(milliseconds: droppedPageForwardAnimationTime),
  643 + curve: animationCurve);
  644 + } else {
  645 + // This route is destined to pop at this point. Reuse navigator's pop.
  646 + navigator.pop();
  647 +
  648 + // The popping may have finished inline if already at the
  649 + // target destination.
  650 + if (controller.isAnimating) {
  651 + // Otherwise, use a custom popping animation duration and curve.
  652 + final droppedPageBackAnimationTime = lerpDouble(
  653 + 0, _kMaxDroppedSwipePageForwardAnimationTime, controller.value)!
  654 + .floor();
  655 + controller.animateBack(0.0,
  656 + duration: Duration(milliseconds: droppedPageBackAnimationTime),
  657 + curve: animationCurve);
  658 + }
  659 + }
  660 +
  661 + if (controller.isAnimating) {
  662 + // Keep the userGestureInProgress in true state so we don't change the
  663 + // curve of the page transition mid-flight since CupertinoPageTransition
  664 + // depends on userGestureInProgress.
  665 + late AnimationStatusListener animationStatusCallback;
  666 + animationStatusCallback = (status) {
  667 + navigator.didStopUserGesture();
  668 + controller.removeStatusListener(animationStatusCallback);
  669 + };
  670 + controller.addStatusListener(animationStatusCallback);
  671 + } else {
  672 + navigator.didStopUserGesture();
  673 + }
  674 + }
  675 +}
@@ -158,14 +158,14 @@ class MiddlewareRunner { @@ -158,14 +158,14 @@ class MiddlewareRunner {
158 class PageRedirect { 158 class PageRedirect {
159 GetPage? route; 159 GetPage? route;
160 GetPage? unknownRoute; 160 GetPage? unknownRoute;
161 - RouteSettings settings; 161 + RouteSettings? settings;
162 bool isUnknown; 162 bool isUnknown;
163 163
164 - PageRedirect(  
165 - this.settings,  
166 - this.unknownRoute, {  
167 - this.isUnknown = false, 164 + PageRedirect({
168 this.route, 165 this.route,
  166 + this.unknownRoute,
  167 + this.isUnknown = false,
  168 + this.settings,
169 }); 169 });
170 170
171 // redirect all pages that needes redirecting 171 // redirect all pages that needes redirecting
@@ -178,11 +178,36 @@ class PageRedirect { @@ -178,11 +178,36 @@ class PageRedirect {
178 settings: isUnknown 178 settings: isUnknown
179 ? RouteSettings( 179 ? RouteSettings(
180 name: _r.name, 180 name: _r.name,
181 - arguments: settings.arguments, 181 + arguments: settings!.arguments,
182 ) 182 )
183 : settings, 183 : settings,
184 curve: _r.curve, 184 curve: _r.curve,
185 opaque: _r.opaque, 185 opaque: _r.opaque,
  186 + gestureWidth: _r.gestureWidth,
  187 + customTransition: _r.customTransition,
  188 + binding: _r.binding,
  189 + bindings: _r.bindings,
  190 + transitionDuration:
  191 + _r.transitionDuration ?? Get.defaultTransitionDuration,
  192 + transition: _r.transition,
  193 + popGesture: _r.popGesture,
  194 + fullscreenDialog: _r.fullscreenDialog,
  195 + middlewares: _r.middlewares,
  196 + );
  197 + }
  198 +
  199 + // redirect all pages that needes redirecting
  200 + GetPageRoute<T> getPageToRoute<T>(GetPage rou, GetPage? unk) {
  201 + while (needRecheck()) {}
  202 + final _r = (isUnknown ? unk : rou)!;
  203 +
  204 + return GetPageRoute<T>(
  205 + page: _r.page,
  206 + parameter: _r.parameter,
  207 + settings: _r,
  208 + curve: _r.curve,
  209 + gestureWidth: _r.gestureWidth,
  210 + opaque: _r.opaque,
186 customTransition: _r.customTransition, 211 customTransition: _r.customTransition,
187 binding: _r.binding, 212 binding: _r.binding,
188 bindings: _r.bindings, 213 bindings: _r.bindings,
@@ -197,7 +222,10 @@ class PageRedirect { @@ -197,7 +222,10 @@ class PageRedirect {
197 222
198 /// check if redirect is needed 223 /// check if redirect is needed
199 bool needRecheck() { 224 bool needRecheck() {
200 - final match = Get.routeTree.matchRoute(settings.name!); 225 + if (settings == null && route != null) {
  226 + settings = route;
  227 + }
  228 + final match = Get.routeTree.matchRoute(settings!.name!);
201 Get.parameters = match.parameters; 229 Get.parameters = match.parameters;
202 230
203 // No Match found 231 // No Match found
@@ -214,7 +242,7 @@ class PageRedirect { @@ -214,7 +242,7 @@ class PageRedirect {
214 if (match.route!.middlewares == null || match.route!.middlewares!.isEmpty) { 242 if (match.route!.middlewares == null || match.route!.middlewares!.isEmpty) {
215 return false; 243 return false;
216 } 244 }
217 - final newSettings = runner.runRedirect(settings.name); 245 + final newSettings = runner.runRedirect(settings!.name);
218 if (newSettings == null) { 246 if (newSettings == null) {
219 return false; 247 return false;
220 } 248 }