Schaban

Add Page Middleware

... ... @@ -9,6 +9,7 @@ export 'src/routes/custom_transition.dart';
export 'src/routes/default_route.dart';
export 'src/routes/get_route.dart';
export 'src/routes/observers/route_observer.dart';
export 'src/routes/route_middleware.dart';
export 'src/routes/transitions_type.dart';
export 'src/snackbar/snack.dart';
export 'src/snackbar/snack_route.dart';
... ...
... ... @@ -188,7 +188,14 @@ class GetCupertinoApp extends StatelessWidget {
super(key: key);
Route<dynamic> generator(RouteSettings settings) {
final match = Get.routeTree.matchRoute(settings.name);
var match = Get.routeTree.matchRoute(settings.name);
final redirect =
MiddlewareRunner(match.route.middlewares).runOnPageCalled();
if (!redirect.isNullOrBlank) {
match = Get.routeTree.matchRoute(redirect);
}
Get.parameters = match?.parameters;
if (match?.route == null) {
... ... @@ -207,6 +214,7 @@ class GetCupertinoApp extends StatelessWidget {
transition: unknownRoute.transition,
popGesture: unknownRoute.popGesture,
fullscreenDialog: unknownRoute.fullscreenDialog,
middlewares: unknownRoute.middlewares,
);
}
... ... @@ -225,6 +233,7 @@ class GetCupertinoApp extends StatelessWidget {
transition: match.route.transition,
popGesture: match.route.popGesture,
fullscreenDialog: match.route.fullscreenDialog,
middlewares: match.route.middlewares,
);
}
... ...
... ... @@ -199,7 +199,14 @@ class GetMaterialApp extends StatelessWidget {
super(key: key);
Route<dynamic> generator(RouteSettings settings) {
final match = Get.routeTree.matchRoute(settings.name);
var match = Get.routeTree.matchRoute(settings.name);
final redirect =
MiddlewareRunner(match.route.middlewares).runOnPageCalled();
if (!redirect.isNullOrBlank) {
match = Get.routeTree.matchRoute(redirect);
}
Get.parameters = match?.parameters;
if (match?.route == null) {
... ... @@ -218,6 +225,7 @@ class GetMaterialApp extends StatelessWidget {
transition: unknownRoute.transition,
popGesture: unknownRoute.popGesture,
fullscreenDialog: unknownRoute.fullscreenDialog,
middlewares: unknownRoute.middlewares,
);
}
... ... @@ -236,6 +244,7 @@ class GetMaterialApp extends StatelessWidget {
transition: match.route.transition,
popGesture: match.route.popGesture,
fullscreenDialog: match.route.fullscreenDialog,
middlewares: match.route.middlewares
);
}
... ...
... ... @@ -70,23 +70,24 @@ class ParseRouteTree {
}
/// Change the Path for a [GetPage]
GetPage _changePath(GetPage orgin, String routePath) => GetPage(
name: routePath + orgin.name,
page: orgin.page,
title: orgin.title,
alignment: orgin.alignment,
transition: orgin.transition,
binding: orgin.binding,
bindings: orgin.bindings,
curve: orgin.curve,
customTransition: orgin.customTransition,
fullscreenDialog: orgin.fullscreenDialog,
maintainState: orgin.maintainState,
opaque: orgin.opaque,
parameter: orgin.parameter,
popGesture: orgin.popGesture,
settings: orgin.settings,
transitionDuration: orgin.transitionDuration,
GetPage _changePath(GetPage origin, String routePath) => GetPage(
name: routePath + origin.name,
page: origin.page,
title: origin.title,
alignment: origin.alignment,
transition: origin.transition,
binding: origin.binding,
bindings: origin.bindings,
curve: origin.curve,
customTransition: origin.customTransition,
fullscreenDialog: origin.fullscreenDialog,
maintainState: origin.maintainState,
opaque: origin.opaque,
parameter: origin.parameter,
popGesture: origin.popGesture,
settings: origin.settings,
transitionDuration: origin.transitionDuration,
middlewares: origin.middlewares,
);
_GetPageMatch matchRoute(String path) {
... ...
... ... @@ -30,6 +30,7 @@ class GetPageRoute<T> extends PageRoute<T> {
this.barrierLabel,
this.maintainState = true,
bool fullscreenDialog = false,
this.middlewares
}) : assert(opaque != null),
assert(barrierDismissible != null),
assert(maintainState != null),
... ... @@ -64,6 +65,8 @@ class GetPageRoute<T> extends PageRoute<T> {
final Curve curve;
final Alignment alignment;
final List<GetPageMiddleware> middlewares;
@override
final Color barrierColor;
... ... @@ -111,14 +114,18 @@ class GetPageRoute<T> extends PageRoute<T> {
Animation<double> secondaryAnimation,
) {
Get.reference = settings.name ?? routeName;
final middlewareRunner = MiddlewareRunner(middlewares);
final bindingsToBind = middlewareRunner.runOnBindingsStart(bindings);
binding?.dependencies();
if (bindings != null) {
for (final binding in bindings) {
if (bindingsToBind != null) {
for (final binding in bindingsToBind) {
binding.dependencies();
}
}
// final pageWidget = page();
return page();
final pageToBuild = middlewareRunner.runOnPageBuildStart(page);
return middlewareRunner.runOnPageBuilt(pageToBuild());
}
static bool isPopGestureInProgress(PageRoute<dynamic> route) {
... ...
import 'package:flutter/widgets.dart';
import '../../../get_instance/get_instance.dart';
import '../../get_navigation.dart';
import 'custom_transition.dart';
import 'transitions_type.dart';
... ... @@ -21,6 +23,7 @@ class GetPage {
final bool fullscreenDialog;
final RouteSettings settings;
final List<GetPage> children;
final List<GetPageMiddleware> middlewares;
const GetPage({
@required this.name,
... ... @@ -40,6 +43,7 @@ class GetPage {
this.customTransition,
this.fullscreenDialog = false,
this.children,
this.middlewares,
}) : assert(page != null),
assert(name != null),
assert(maintainState != null),
... ...
import 'package:flutter/cupertino.dart';
import '../../../get.dart';
/// The Page Middlewares
/// The Functions will be called in this order
/// (( [onPageCalled] -> [onBindingsStart] -> [onPageBuildStart] ->
/// [onPageBuilt] -> [onPageDispose] ))
abstract class GetPageMiddleware {
/// The Order of the Middlewares to run.
int priority;
/// This function will be the first thing to call when this Page is called
/// you can use it to redirect befor anything in this page happend.
/// {@tool snippet}
/// ```dart
/// GetPage onPageCalled( ) {
/// final authService = Get.find<AuthService>();
/// return authService.isAuthed ? null : '/login';
/// }
/// ```
/// {@end-tool}
String redirect();
///This function will be called right before the [Bindings] are initialize.
/// Here you can change [Bindings] for this page
List<Bindings> onBindingsStart(List<Bindings> bindings);
/// This function will be called right after the [Bindings] are initialize.
GetPageBuilder onPageBuildStart(GetPageBuilder page);
// Get the built page
Widget onPageBuilt(Widget page);
void onPageDispose();
}
class MiddlewareRunner {
MiddlewareRunner(this._middlewares);
final List<GetPageMiddleware> _middlewares;
List<GetPageMiddleware> _getMiddlewares() {
if (_middlewares != null) {
_middlewares.sort((a, b) => a.priority.compareTo(b.priority));
return _middlewares;
}
return <GetPageMiddleware>[];
}
String runOnPageCalled() {
var to = '';
_getMiddlewares().forEach((element) {
to = element.redirect();
});
if (!to.isNullOrBlank) {
Get.log('Redirect to $to');
}
return to;
}
List<Bindings> runOnBindingsStart(List<Bindings> bindings) {
_getMiddlewares().forEach((element) {
bindings = element.onBindingsStart(bindings);
});
return bindings;
}
GetPageBuilder runOnPageBuildStart(GetPageBuilder page) {
_getMiddlewares().forEach((element) {
page = element.onPageBuildStart(page);
});
return page;
}
Widget runOnPageBuilt(Widget page) {
_getMiddlewares().forEach((element) {
page = element.onPageBuilt(page);
});
return page;
}
void runOnPageDispose() =>
_getMiddlewares().forEach((element) => element.onPageDispose());
}
... ...