Compare commits

..

11 Commits

Author SHA1 Message Date
Michael Pfaff 9956b24eb2 Take GlobalKey<NavigatorState> instead of BuildContext 2020-04-24 14:16:22 -04:00
Michael Pfaff 45949890cc Make route handler constant 2020-04-20 16:59:39 -04:00
Michael Pfaff 8e99c535bd Remove file that should not be checked into version control 2020-04-20 16:59:23 -04:00
Luke 30ae4378df
Remove upper bounds on pubspec (#163)
* remove upper constraint for flutter environment
* update docs
Co-authored-by: Luke Pighetti <lukepighetti@gmail.com>
2020-04-07 10:46:20 -07:00
Luke Freeman 937afe9757 update docs 2020-03-28 14:37:43 -07:00
Luke Pighetti aca29a1e34
Allow Flutter <1.17.0 (#153)
- Support dev version
2020-03-22 14:56:55 -07:00
Luke Freeman 337d864b62 bump version 2020-03-08 19:54:50 -07:00
Luke Freeman 3a1a20e03b update CHANGLOG and README 2020-03-08 19:54:38 -07:00
Luke Freeman 53e1c97960 downgrade Flutter required version 2020-03-08 19:53:28 -07:00
Luke Freeman 16b09f760c bump version 2020-03-08 19:42:31 -07:00
Luke Freeman 624626c85d update README and CHANGELOG 2020-03-08 19:39:52 -07:00
11 changed files with 246 additions and 25 deletions

3
.gitignore vendored
View File

@ -11,3 +11,6 @@ coverage
__temp_coverage*
.dart_tool/
build/
# iOS
**/flutter_export_environment.sh

View File

@ -1,5 +1,15 @@
# 1.6.3
- Remove upper bounds on Flutter SDK checks because Flutter releases are a ridiculous mess
# 1.6.2
- Support for Flutter `>=1.12 <=1.17`
# 1.6.1
- Support for Flutter `1.12+`
# 1.6.0
- Flutter `>= 1.13.0` is required due to Flutter compatibility issues
- No changes other than fixes for non-backwards compatible Flutter changes
- Flutter `>= 1.12.0` is required due to Flutter compatibility issues
- Dart `>= 2.6.0` is required
# 1.5.2

View File

@ -3,10 +3,12 @@
The brightest, hippest, coolest router for Flutter.
[![Version](https://img.shields.io/badge/version-1.6.0-blue.svg)](https://pub.dartlang.org/packages/fluro)
[![Version](https://img.shields.io/badge/version-1.6.3-blue.svg)](https://pub.dartlang.org/packages/fluro)
[![Build Status](https://travis-ci.org/theyakka/fluro.svg?branch=master)](https://travis-ci.org/theyakka/fluro)
[![Coverage](https://codecov.io/gh/theyakka/fluro/branch/master/graph/badge.svg)](https://codecov.io/gh/theyakka/fluro)
Version `1.6.0` (and higher) requires Flutter `>= 1.12.0` and Dart `>= 2.6.0`. If you're running an older version of Flutter, use a version `< 1.6.0`.
## Features
- Simple route navigation
@ -25,7 +27,7 @@ See CHANGELOG for all breaking (and non-breaking) changes.
You should ensure that you add the router as a dependency in your flutter project.
```yaml
dependencies:
fluro: "^1.6.0"
fluro: "^1.6.3"
```
You can also reference the git repo directly if you want:

View File

@ -1,10 +0,0 @@
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=/home/luke/Development/.sdks/flutter"
export "FLUTTER_APPLICATION_PATH=/home/luke/Development/yakka/fluro/fluro-flutter/example"
export "FLUTTER_TARGET=lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "SYMROOT=${SOURCE_ROOT}/../build/ios"
export "FLUTTER_FRAMEWORK_DIR=/home/luke/Development/.sdks/flutter/bin/cache/artifacts/engine/ios"
export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1"

View File

@ -35,6 +35,7 @@ class AppComponentState extends State<AppComponent> {
primarySwatch: Colors.blue,
),
onGenerateRoute: Application.router.generator,
navigatorKey: Application.routerKey,
);
// print("initial route = ${app.initialRoute}");
return app;

View File

@ -232,10 +232,10 @@ class HomeComponentState extends State<HomeComponent> {
}
Application.router
.navigateTo(context, route, transition: transitionType)
.navigateTo(Application.routerKey, route, transition: transitionType)
.then((result) {
if (key == "pop-result") {
Application.router.navigateTo(context, "/demo/func?message=$result");
Application.router.navigateTo(Application.routerKey, "/demo/func?message=$result");
}
});
} else if (key == "custom") {
@ -253,7 +253,7 @@ class HomeComponentState extends State<HomeComponent> {
);
};
Application.router.navigateTo(
context,
Application.routerKey,
"/demo?message=$message&color_hex=$hexCode",
transition: TransitionType.custom,
transitionBuilder: transition,
@ -261,10 +261,10 @@ class HomeComponentState extends State<HomeComponent> {
);
} else if (key == "fixed-trans") {
Application.router.navigateTo(
context, "/demo/fixedtrans?message=Hello!&color_hex=#f4424b");
Application.routerKey, "/demo/fixedtrans?message=Hello!&color_hex=#f4424b");
} else {
message = "You tapped the function button!";
Application.router.navigateTo(context, "/demo/func?message=$message");
Application.router.navigateTo(Application.routerKey, "/demo/func?message=$message");
}
}
}

View File

@ -7,7 +7,10 @@
* See LICENSE for distribution and usage details.
*/
import 'package:fluro/fluro.dart';
import 'package:flutter/material.dart';
class Application {
static Router router;
static GlobalKey<NavigatorState> routerKey = GlobalKey<NavigatorState>();
}

View File

@ -8,7 +8,6 @@
*/
library fluro;
export 'package:dazza/dazza.dart';
export 'src/common.dart';
export 'src/router.dart';
export 'src/tree.dart';

View File

@ -17,7 +17,7 @@ enum HandlerType {
///
class Handler {
Handler({this.type = HandlerType.route, this.handlerFunc});
const Handler({this.type = HandlerType.route, this.handlerFunc});
final HandlerType type;
final HandlerFunc handlerFunc;
}

View File

@ -3,7 +3,7 @@
* Created by Yakka
* https://theyakka.com
*
* Copyright (c) 2020 Yakka, LLC. All rights reserved.
* Copyright (c) 2019 Yakka, LLC. All rights reserved.
* See LICENSE for distribution and usage details.
*/
@ -14,3 +14,218 @@ import 'package:fluro/src/common.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class Router {
static final appRouter = Router();
/// The tree structure that stores the defined routes
final RouteTree _routeTree = RouteTree();
/// Generic handler for when a route has not been defined
Handler notFoundHandler;
/// Creates a [PageRoute] definition for the passed [RouteHandler]. You can optionally provide a default transition type.
void define(String routePath,
{@required Handler handler, TransitionType transitionType}) {
_routeTree.addRoute(
AppRoute(routePath, handler, transitionType: transitionType),
);
}
/// Finds a defined [AppRoute] for the path value. If no [AppRoute] definition was found
/// then function will return null.
AppRouteMatch match(String path) {
return _routeTree.matchRoute(path);
}
void pop(GlobalKey<NavigatorState> key) => key.currentState.pop();
///
Future navigateTo(GlobalKey<NavigatorState> key, String path,
{bool replace = false,
bool clearStack = false,
TransitionType transition,
Duration transitionDuration = const Duration(milliseconds: 250),
RouteTransitionsBuilder transitionBuilder}) {
RouteMatch routeMatch = matchRoute(key.currentContext, path,
transitionType: transition,
transitionsBuilder: transitionBuilder,
transitionDuration: transitionDuration);
Route<dynamic> route = routeMatch.route;
Completer completer = Completer();
Future future = completer.future;
if (routeMatch.matchType == RouteMatchType.nonVisual) {
completer.complete("Non visual route type.");
} else {
if (route == null && notFoundHandler != null) {
route = _notFoundRoute(path);
}
if (route != null) {
if (clearStack) {
future =
key.currentState.pushAndRemoveUntil(route, (check) => false);
} else {
future = replace
? key.currentState.pushReplacement(route)
: key.currentState.push(route);
}
completer.complete();
} else {
String error = "No registered route was found to handle '$path'.";
print(error);
completer.completeError(RouteNotFoundException(error, path));
}
}
return future;
}
///
Route<Null> _notFoundRoute(String path) {
RouteCreator<Null> creator =
(RouteSettings routeSettings, Map<String, List<String>> parameters) {
return MaterialPageRoute<Null>(
settings: routeSettings,
builder: (BuildContext context) {
return notFoundHandler.handlerFunc(context, parameters);
});
};
return creator(RouteSettings(name: path), null);
}
///
RouteMatch matchRoute(BuildContext buildContext, String path,
{RouteSettings routeSettings,
TransitionType transitionType,
Duration transitionDuration = const Duration(milliseconds: 250),
RouteTransitionsBuilder transitionsBuilder}) {
RouteSettings settingsToUse = routeSettings;
if (routeSettings == null) {
settingsToUse = RouteSettings(name: path);
}
AppRouteMatch match = _routeTree.matchRoute(path);
AppRoute route = match?.route;
Handler handler = (route != null ? route.handler : notFoundHandler);
var transition = transitionType;
if (transitionType == null) {
transition = route != null ? route.transitionType : TransitionType.native;
}
if (route == null && notFoundHandler == null) {
return RouteMatch(
matchType: RouteMatchType.noMatch,
errorMessage: "No matching route was found");
}
Map<String, List<String>> parameters =
match?.parameters ?? <String, List<String>>{};
if (handler.type == HandlerType.function) {
handler.handlerFunc(buildContext, parameters);
return RouteMatch(matchType: RouteMatchType.nonVisual);
}
RouteCreator creator =
(RouteSettings routeSettings, Map<String, List<String>> parameters) {
bool isNativeTransition = (transition == TransitionType.native ||
transition == TransitionType.nativeModal);
if (isNativeTransition) {
if (Theme.of(buildContext).platform == TargetPlatform.iOS) {
return CupertinoPageRoute<dynamic>(
settings: routeSettings,
fullscreenDialog: transition == TransitionType.nativeModal,
builder: (BuildContext context) {
return handler.handlerFunc(context, parameters);
});
} else {
return MaterialPageRoute<dynamic>(
settings: routeSettings,
fullscreenDialog: transition == TransitionType.nativeModal,
builder: (BuildContext context) {
return handler.handlerFunc(context, parameters);
});
}
} else if (transition == TransitionType.material ||
transition == TransitionType.materialFullScreenDialog) {
return MaterialPageRoute<dynamic>(
settings: routeSettings,
fullscreenDialog:
transition == TransitionType.materialFullScreenDialog,
builder: (BuildContext context) {
return handler.handlerFunc(context, parameters);
});
} else if (transition == TransitionType.cupertino ||
transition == TransitionType.cupertinoFullScreenDialog) {
return CupertinoPageRoute<dynamic>(
settings: routeSettings,
fullscreenDialog:
transition == TransitionType.cupertinoFullScreenDialog,
builder: (BuildContext context) {
return handler.handlerFunc(context, parameters);
});
} else {
var routeTransitionsBuilder;
if (transition == TransitionType.custom) {
routeTransitionsBuilder = transitionsBuilder;
} else {
routeTransitionsBuilder = _standardTransitionsBuilder(transition);
}
return PageRouteBuilder<dynamic>(
settings: routeSettings,
pageBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
return handler.handlerFunc(context, parameters);
},
transitionDuration: transitionDuration,
transitionsBuilder: routeTransitionsBuilder,
);
}
};
return RouteMatch(
matchType: RouteMatchType.visual,
route: creator(settingsToUse, parameters),
);
}
RouteTransitionsBuilder _standardTransitionsBuilder(
TransitionType transitionType) {
return (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation, Widget child) {
if (transitionType == TransitionType.fadeIn) {
return FadeTransition(opacity: animation, child: child);
} else {
const Offset topLeft = const Offset(0.0, 0.0);
const Offset topRight = const Offset(1.0, 0.0);
const Offset bottomLeft = const Offset(0.0, 1.0);
Offset startOffset = bottomLeft;
Offset endOffset = topLeft;
if (transitionType == TransitionType.inFromLeft) {
startOffset = const Offset(-1.0, 0.0);
endOffset = topLeft;
} else if (transitionType == TransitionType.inFromRight) {
startOffset = topRight;
endOffset = topLeft;
}
return SlideTransition(
position: Tween<Offset>(
begin: startOffset,
end: endOffset,
).animate(animation),
child: child,
);
}
};
}
/// Route generation method. This function can be used as a way to create routes on-the-fly
/// if any defined handler is found. It can also be used with the [MaterialApp.onGenerateRoute]
/// property as callback to create routes that can be used with the [Navigator] class.
Route<dynamic> generator(RouteSettings routeSettings) {
RouteMatch match =
matchRoute(null, routeSettings.name, routeSettings: routeSettings);
return match.route;
}
/// Prints the route tree so you can analyze it.
void printTree() {
_routeTree.printTree();
}
}

View File

@ -2,12 +2,12 @@ name: fluro
description: >
Fluro is a Flutter routing library that adds flexible routing options like wildcards, named
parameters and clear route definitions.
version: 1.6.0-dev
version: 1.6.3
homepage: https://github.com/theyakka/fluro
environment:
sdk: ">=2.6.0 <3.0.0"
flutter: ">=1.13.0 <1.16.0"
flutter: ">=1.12.0"
dependencies:
flutter:
@ -17,8 +17,6 @@ dev_dependencies:
flutter_test:
sdk: flutter
test: ^1.6.0
dazza:
path: ../../dazza
flutter:
uses-material-design: false