Compare commits
1 Commits
Author | SHA1 | Date |
---|---|---|
Luke Freeman | 4f472e556c |
|
@ -11,6 +11,3 @@ coverage
|
||||||
__temp_coverage*
|
__temp_coverage*
|
||||||
.dart_tool/
|
.dart_tool/
|
||||||
build/
|
build/
|
||||||
|
|
||||||
# iOS
|
|
||||||
**/flutter_export_environment.sh
|
|
||||||
|
|
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,15 +1,5 @@
|
||||||
# 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
|
# 1.6.0
|
||||||
- No changes other than fixes for non-backwards compatible Flutter changes
|
- Flutter `>= 1.13.0` is required due to Flutter compatibility issues
|
||||||
- Flutter `>= 1.12.0` is required due to Flutter compatibility issues
|
|
||||||
- Dart `>= 2.6.0` is required
|
- Dart `>= 2.6.0` is required
|
||||||
|
|
||||||
# 1.5.2
|
# 1.5.2
|
||||||
|
|
|
@ -3,12 +3,10 @@
|
||||||
|
|
||||||
The brightest, hippest, coolest router for Flutter.
|
The brightest, hippest, coolest router for Flutter.
|
||||||
|
|
||||||
[![Version](https://img.shields.io/badge/version-1.6.3-blue.svg)](https://pub.dartlang.org/packages/fluro)
|
[![Version](https://img.shields.io/badge/version-1.6.0-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)
|
[![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)
|
[![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
|
## Features
|
||||||
|
|
||||||
- Simple route navigation
|
- Simple route navigation
|
||||||
|
@ -27,7 +25,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.
|
You should ensure that you add the router as a dependency in your flutter project.
|
||||||
```yaml
|
```yaml
|
||||||
dependencies:
|
dependencies:
|
||||||
fluro: "^1.6.3"
|
fluro: "^1.6.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also reference the git repo directly if you want:
|
You can also reference the git repo directly if you want:
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/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"
|
|
@ -35,7 +35,6 @@ class AppComponentState extends State<AppComponent> {
|
||||||
primarySwatch: Colors.blue,
|
primarySwatch: Colors.blue,
|
||||||
),
|
),
|
||||||
onGenerateRoute: Application.router.generator,
|
onGenerateRoute: Application.router.generator,
|
||||||
navigatorKey: Application.routerKey,
|
|
||||||
);
|
);
|
||||||
// print("initial route = ${app.initialRoute}");
|
// print("initial route = ${app.initialRoute}");
|
||||||
return app;
|
return app;
|
||||||
|
|
|
@ -232,10 +232,10 @@ class HomeComponentState extends State<HomeComponent> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Application.router
|
Application.router
|
||||||
.navigateTo(Application.routerKey, route, transition: transitionType)
|
.navigateTo(context, route, transition: transitionType)
|
||||||
.then((result) {
|
.then((result) {
|
||||||
if (key == "pop-result") {
|
if (key == "pop-result") {
|
||||||
Application.router.navigateTo(Application.routerKey, "/demo/func?message=$result");
|
Application.router.navigateTo(context, "/demo/func?message=$result");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (key == "custom") {
|
} else if (key == "custom") {
|
||||||
|
@ -253,7 +253,7 @@ class HomeComponentState extends State<HomeComponent> {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
Application.router.navigateTo(
|
Application.router.navigateTo(
|
||||||
Application.routerKey,
|
context,
|
||||||
"/demo?message=$message&color_hex=$hexCode",
|
"/demo?message=$message&color_hex=$hexCode",
|
||||||
transition: TransitionType.custom,
|
transition: TransitionType.custom,
|
||||||
transitionBuilder: transition,
|
transitionBuilder: transition,
|
||||||
|
@ -261,10 +261,10 @@ class HomeComponentState extends State<HomeComponent> {
|
||||||
);
|
);
|
||||||
} else if (key == "fixed-trans") {
|
} else if (key == "fixed-trans") {
|
||||||
Application.router.navigateTo(
|
Application.router.navigateTo(
|
||||||
Application.routerKey, "/demo/fixedtrans?message=Hello!&color_hex=#f4424b");
|
context, "/demo/fixedtrans?message=Hello!&color_hex=#f4424b");
|
||||||
} else {
|
} else {
|
||||||
message = "You tapped the function button!";
|
message = "You tapped the function button!";
|
||||||
Application.router.navigateTo(Application.routerKey, "/demo/func?message=$message");
|
Application.router.navigateTo(context, "/demo/func?message=$message");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,7 @@
|
||||||
* See LICENSE for distribution and usage details.
|
* See LICENSE for distribution and usage details.
|
||||||
*/
|
*/
|
||||||
import 'package:fluro/fluro.dart';
|
import 'package:fluro/fluro.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class Application {
|
class Application {
|
||||||
static Router router;
|
static Router router;
|
||||||
|
|
||||||
static GlobalKey<NavigatorState> routerKey = GlobalKey<NavigatorState>();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
*/
|
*/
|
||||||
library fluro;
|
library fluro;
|
||||||
|
|
||||||
|
export 'package:dazza/dazza.dart';
|
||||||
export 'src/common.dart';
|
export 'src/common.dart';
|
||||||
export 'src/router.dart';
|
export 'src/router.dart';
|
||||||
export 'src/tree.dart';
|
export 'src/tree.dart';
|
||||||
|
|
|
@ -17,7 +17,7 @@ enum HandlerType {
|
||||||
|
|
||||||
///
|
///
|
||||||
class Handler {
|
class Handler {
|
||||||
const Handler({this.type = HandlerType.route, this.handlerFunc});
|
Handler({this.type = HandlerType.route, this.handlerFunc});
|
||||||
final HandlerType type;
|
final HandlerType type;
|
||||||
final HandlerFunc handlerFunc;
|
final HandlerFunc handlerFunc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* Created by Yakka
|
* Created by Yakka
|
||||||
* https://theyakka.com
|
* https://theyakka.com
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Yakka, LLC. All rights reserved.
|
* Copyright (c) 2020 Yakka, LLC. All rights reserved.
|
||||||
* See LICENSE for distribution and usage details.
|
* See LICENSE for distribution and usage details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -14,218 +14,3 @@ import 'package:fluro/src/common.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,12 +2,12 @@ name: fluro
|
||||||
description: >
|
description: >
|
||||||
Fluro is a Flutter routing library that adds flexible routing options like wildcards, named
|
Fluro is a Flutter routing library that adds flexible routing options like wildcards, named
|
||||||
parameters and clear route definitions.
|
parameters and clear route definitions.
|
||||||
version: 1.6.3
|
version: 1.6.0-dev
|
||||||
homepage: https://github.com/theyakka/fluro
|
homepage: https://github.com/theyakka/fluro
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.6.0 <3.0.0"
|
sdk: ">=2.6.0 <3.0.0"
|
||||||
flutter: ">=1.12.0"
|
flutter: ">=1.13.0 <1.16.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
|
@ -17,6 +17,8 @@ dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
test: ^1.6.0
|
test: ^1.6.0
|
||||||
|
dazza:
|
||||||
|
path: ../../dazza
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: false
|
uses-material-design: false
|
||||||
|
|
Loading…
Reference in New Issue