fix transition bug. add explicit material transition type. tidy example. add font license. remove 'new', 'const', etc where not needed.
|
@ -1,3 +1,10 @@
|
|||
# 1.5.1
|
||||
- Add explicit material and full screen material transition types
|
||||
- Fix issue in transition logic
|
||||
- Remove redundant `new`, `const`, etc qualifiers
|
||||
- Tidy example
|
||||
- Add font license info
|
||||
|
||||
# 1.5.0
|
||||
- Native transitions will now use the Cupertino page route on iOS and Material page route on android. This will enable swipe gestures on iOS.
|
||||
- Added cupertino specific transition types.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
The brightest, hippest, coolest router for Flutter.
|
||||
|
||||
[![Version](https://img.shields.io/badge/version-1.5.0-blue.svg)](https://pub.dartlang.org/packages/fluro)
|
||||
[![Version](https://img.shields.io/badge/version-1.5.1-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)
|
||||
|
||||
|
@ -25,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.
|
||||
```yaml
|
||||
dependencies:
|
||||
fluro: "^1.5.0"
|
||||
fluro: "^1.5.1"
|
||||
```
|
||||
|
||||
You can also reference the git repo directly if you want:
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
Copyright 2015 SUNRISE DIGITAL, Juan Hodgson Authors (srdigital@msn.com)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
After Width: | Height: | Size: 731 B |
After Width: | Height: | Size: 978 B |
After Width: | Height: | Size: 882 B |
After Width: | Height: | Size: 587 B |
After Width: | Height: | Size: 645 B |
After Width: | Height: | Size: 978 B |
After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 11 KiB |
|
@ -6,36 +6,37 @@
|
|||
* Copyright (c) 2019 Yakka, LLC. All rights reserved.
|
||||
* See LICENSE for distribution and usage details.
|
||||
*/
|
||||
import '../../config/application.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluro/fluro.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../config/application.dart';
|
||||
import '../../config/routes.dart';
|
||||
|
||||
class AppComponent extends StatefulWidget {
|
||||
@override
|
||||
State createState() {
|
||||
return new AppComponentState();
|
||||
return AppComponentState();
|
||||
}
|
||||
}
|
||||
|
||||
class AppComponentState extends State<AppComponent> {
|
||||
AppComponentState() {
|
||||
final router = new Router();
|
||||
final router = Router();
|
||||
Routes.configureRoutes(router);
|
||||
Application.router = router;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final app = new MaterialApp(
|
||||
final app = MaterialApp(
|
||||
title: 'Fluro',
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: new ThemeData(
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
),
|
||||
onGenerateRoute: Application.router.generator,
|
||||
);
|
||||
print("initial route = ${app.initialRoute}");
|
||||
// print("initial route = ${app.initialRoute}");
|
||||
return app;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,15 +17,16 @@ class DemoMessageComponent extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Material(
|
||||
return Material(
|
||||
color: this.color,
|
||||
child: new Center(
|
||||
child: new Text(
|
||||
message,
|
||||
style: new TextStyle(
|
||||
fontFamily: "Lazer84",
|
||||
child: Center(
|
||||
child: Text(
|
||||
message,
|
||||
style: TextStyle(
|
||||
fontFamily: "Lazer84",
|
||||
),
|
||||
),
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,12 @@ import 'package:flutter/material.dart';
|
|||
|
||||
class DemoResultComponent extends StatefulWidget {
|
||||
@override
|
||||
_DemoResultComponentState createState() => new _DemoResultComponentState();
|
||||
_DemoResultComponentState createState() => _DemoResultComponentState();
|
||||
}
|
||||
|
||||
class _DemoResultComponentState extends State<DemoResultComponent> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Container();
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,32 +24,32 @@ class DemoSimpleComponent extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new Material(
|
||||
return Material(
|
||||
color: color,
|
||||
child: new Column(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
new Image(
|
||||
image: new AssetImage("assets/images/acc_boom.png"),
|
||||
Image(
|
||||
image: AssetImage("assets/images/acc_boom.png"),
|
||||
color: ColorHelpers.blackOrWhiteContrastColor(color),
|
||||
width: 260.0,
|
||||
),
|
||||
new Padding(
|
||||
padding: new EdgeInsets.only(left: 50.0, right: 50.0, top: 15.0),
|
||||
child: new Text(
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 50.0, right: 50.0, top: 15.0),
|
||||
child: Text(
|
||||
message,
|
||||
textAlign: TextAlign.center,
|
||||
style: new TextStyle(
|
||||
style: TextStyle(
|
||||
color: ColorHelpers.blackOrWhiteContrastColor(color),
|
||||
height: 2.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
new Padding(
|
||||
padding: new EdgeInsets.only(top: 15.0),
|
||||
child: new ConstrainedBox(
|
||||
constraints: new BoxConstraints(minHeight: 42.0),
|
||||
child: new FlatButton(
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 15.0),
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(minHeight: 42.0),
|
||||
child: FlatButton(
|
||||
highlightColor:
|
||||
ColorHelpers.blackOrWhiteContrastColor(color).withAlpha(17),
|
||||
splashColor:
|
||||
|
@ -61,9 +61,9 @@ class DemoSimpleComponent extends StatelessWidget {
|
|||
Navigator.pop(context, result);
|
||||
}
|
||||
},
|
||||
child: new Text(
|
||||
child: Text(
|
||||
"OK",
|
||||
style: new TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 18.0,
|
||||
color: ColorHelpers.blackOrWhiteContrastColor(color),
|
||||
),
|
||||
|
|
|
@ -8,14 +8,16 @@
|
|||
*/
|
||||
import 'dart:async';
|
||||
|
||||
import '../../config/application.dart';
|
||||
import 'package:fluro/fluro.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import '../../config/application.dart';
|
||||
|
||||
class HomeComponent extends StatefulWidget {
|
||||
@override
|
||||
State createState() => new HomeComponentState();
|
||||
State createState() => HomeComponentState();
|
||||
}
|
||||
|
||||
class HomeComponentState extends State<HomeComponent> {
|
||||
|
@ -33,16 +35,16 @@ class HomeComponentState extends State<HomeComponent> {
|
|||
];
|
||||
|
||||
Widget deepLinkWidget(BuildContext context) {
|
||||
return new Stack(
|
||||
return Stack(
|
||||
children: <Widget>[
|
||||
// copied widget
|
||||
new AnimatedOpacity(
|
||||
AnimatedOpacity(
|
||||
opacity: (_deepLinkOpacity - 1.0).abs(),
|
||||
duration: new Duration(milliseconds: 400),
|
||||
child: new Center(
|
||||
child: new Text(
|
||||
duration: Duration(milliseconds: 400),
|
||||
child: Center(
|
||||
child: Text(
|
||||
"Copied to clipboard!",
|
||||
style: new TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14.0,
|
||||
color: const Color(0xFFFFFFFF),
|
||||
fontWeight: FontWeight.w500,
|
||||
|
@ -51,16 +53,16 @@ class HomeComponentState extends State<HomeComponent> {
|
|||
),
|
||||
),
|
||||
// button widget
|
||||
new AnimatedOpacity(
|
||||
AnimatedOpacity(
|
||||
opacity: _deepLinkOpacity,
|
||||
duration: new Duration(milliseconds: 250),
|
||||
child: new Center(
|
||||
child: new FlatButton(
|
||||
duration: Duration(milliseconds: 250),
|
||||
child: Center(
|
||||
child: FlatButton(
|
||||
highlightColor: const Color(0x11FFFFFF),
|
||||
splashColor: const Color(0x22FFFFFF),
|
||||
onPressed: () {
|
||||
if (_deepLinkOpacity == 1.0) {
|
||||
new Timer(new Duration(milliseconds: 2000), () {
|
||||
Timer(Duration(milliseconds: 2000), () {
|
||||
setState(() {
|
||||
_deepLinkOpacity = 1.0;
|
||||
});
|
||||
|
@ -68,16 +70,16 @@ class HomeComponentState extends State<HomeComponent> {
|
|||
setState(() {
|
||||
_deepLinkOpacity = 0.0;
|
||||
});
|
||||
final clipboardData = new ClipboardData(text: _deepLinkURL);
|
||||
final clipboardData = ClipboardData(text: _deepLinkURL);
|
||||
Clipboard.setData(clipboardData);
|
||||
}
|
||||
},
|
||||
child: new Padding(
|
||||
padding: new EdgeInsets.all(8.0),
|
||||
child: new Text(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
"Click here to copy a deep link url to the clipboard",
|
||||
textAlign: TextAlign.center,
|
||||
style: new TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12.0,
|
||||
color: const Color(0xCCFFFFFF),
|
||||
),
|
||||
|
@ -93,52 +95,99 @@ class HomeComponentState extends State<HomeComponent> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var menuWidgets = <Widget>[
|
||||
new Padding(
|
||||
padding: new EdgeInsets.only(bottom: 35.0),
|
||||
child: new Image(
|
||||
image: new AssetImage("assets/images/logo_fluro.png"),
|
||||
width: 200.0),
|
||||
),
|
||||
menuButton(context, "Native Animation", "native"),
|
||||
menuButton(context, "Preset (Fade In)", "preset-fade"),
|
||||
menuButton(context, "Preset (Global transition)", "fixed-trans"),
|
||||
menuButton(context, "Custom Transition", "custom"),
|
||||
menuButton(context, "Navigator Result", "pop-result"),
|
||||
menuButton(context, "Function Call", "function-call"),
|
||||
new Padding(
|
||||
padding: new EdgeInsets.only(top: 65.0, left: 60.0, right: 60.0),
|
||||
child: new Center(
|
||||
child: new ConstrainedBox(
|
||||
constraints: new BoxConstraints.tightFor(height: 60.0),
|
||||
child: deepLinkWidget(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
menuButton(context, 'assets/images/ic_transform_native_hz.png',
|
||||
"Native Animation", "native"),
|
||||
menuButton(context, 'assets/images/ic_transform_fade_in_hz.png',
|
||||
"Preset (Fade In)", "preset-fade"),
|
||||
menuButton(context, 'assets/images/ic_transform_global_hz.png',
|
||||
"Preset (Global transition)", "fixed-trans"),
|
||||
menuButton(context, 'assets/images/ic_transform_custom_hz.png',
|
||||
"Custom Transition", "custom"),
|
||||
menuButton(context, 'assets/images/ic_result_hz.png', "Navigator Result",
|
||||
"pop-result"),
|
||||
menuButton(context, 'assets/images/ic_function_hz.png', "Function Call",
|
||||
"function-call"),
|
||||
];
|
||||
|
||||
return new Material(
|
||||
final size = MediaQuery.of(context).size;
|
||||
final childRatio = (size.width / size.height) * 2.5;
|
||||
|
||||
return Material(
|
||||
color: const Color(0xFF00D6F7),
|
||||
child: new Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: menuWidgets,
|
||||
child: SafeArea(
|
||||
top: true,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 25, bottom: 35, left: 25),
|
||||
child: Image(
|
||||
image: AssetImage("assets/images/logo_fluro.png"),
|
||||
width: 100.0,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 25),
|
||||
child: GridView.count(
|
||||
childAspectRatio: childRatio,
|
||||
crossAxisCount: 2,
|
||||
mainAxisSpacing: 5,
|
||||
children: menuWidgets,
|
||||
),
|
||||
),
|
||||
),
|
||||
// Padding(
|
||||
// padding: EdgeInsets.only(top: 35.0, bottom: 25),
|
||||
// child: Center(
|
||||
// child: ConstrainedBox(
|
||||
// constraints: BoxConstraints.tightFor(height: 60.0),
|
||||
// child: deepLinkWidget(context),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// helpers
|
||||
Widget menuButton(BuildContext context, String title, String key) {
|
||||
return new Padding(
|
||||
padding: new EdgeInsets.all(4.0),
|
||||
child: new ConstrainedBox(
|
||||
constraints: new BoxConstraints(minHeight: 42.0),
|
||||
child: new FlatButton(
|
||||
Widget menuButton(
|
||||
BuildContext context, String assetSrc, String title, String key) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.all(4.0),
|
||||
child: Container(
|
||||
height: 42.0,
|
||||
child: FlatButton(
|
||||
color: const Color(0x22FFFFFF),
|
||||
highlightColor: const Color(0x11FFFFFF),
|
||||
splashColor: const Color(0x22FFFFFF),
|
||||
child: new Text(
|
||||
title,
|
||||
style: new TextStyle(
|
||||
color: const Color(0xAA001133),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10),
|
||||
child: Container(
|
||||
height: 36,
|
||||
child: Image.asset(
|
||||
assetSrc,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: const Color(0xAA001133),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
tappedMenuButton(context, key);
|
||||
|
@ -173,7 +222,7 @@ class HomeComponentState extends State<HomeComponent> {
|
|||
hexCode = "#7d41f4";
|
||||
message =
|
||||
"When you close this screen you should see the current day of the week";
|
||||
result = "Today is ${_daysOfWeek[new DateTime.now().weekday - 1]}!";
|
||||
result = "Today is ${_daysOfWeek[DateTime.now().weekday - 1]}!";
|
||||
}
|
||||
|
||||
String route = "/demo?message=$message&color_hex=$hexCode";
|
||||
|
@ -195,9 +244,9 @@ class HomeComponentState extends State<HomeComponent> {
|
|||
"This screen should have appeared with a crazy custom transition";
|
||||
var transition = (BuildContext context, Animation<double> animation,
|
||||
Animation<double> secondaryAnimation, Widget child) {
|
||||
return new ScaleTransition(
|
||||
return ScaleTransition(
|
||||
scale: animation,
|
||||
child: new RotationTransition(
|
||||
child: RotationTransition(
|
||||
turns: animation,
|
||||
child: child,
|
||||
),
|
||||
|
|
|
@ -13,49 +13,48 @@ import 'package:flutter/painting.dart';
|
|||
import 'package:fluro/fluro.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
var rootHandler = new Handler(
|
||||
var rootHandler = Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
return new HomeComponent();
|
||||
return HomeComponent();
|
||||
});
|
||||
|
||||
var demoRouteHandler = new Handler(
|
||||
var demoRouteHandler = Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
String message = params["message"]?.first;
|
||||
String colorHex = params["color_hex"]?.first;
|
||||
String result = params["result"]?.first;
|
||||
Color color = new Color(0xFFFFFFFF);
|
||||
Color color = Color(0xFFFFFFFF);
|
||||
if (colorHex != null && colorHex.length > 0) {
|
||||
color = new Color(ColorHelpers.fromHexString(colorHex));
|
||||
color = Color(ColorHelpers.fromHexString(colorHex));
|
||||
}
|
||||
return new DemoSimpleComponent(
|
||||
message: message, color: color, result: result);
|
||||
return DemoSimpleComponent(message: message, color: color, result: result);
|
||||
});
|
||||
|
||||
var demoFunctionHandler = new Handler(
|
||||
var demoFunctionHandler = Handler(
|
||||
type: HandlerType.function,
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
String message = params["message"]?.first;
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return new AlertDialog(
|
||||
title: new Text(
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
"Hey Hey!",
|
||||
style: new TextStyle(
|
||||
style: TextStyle(
|
||||
color: const Color(0xFF00D6F7),
|
||||
fontFamily: "Lazer84",
|
||||
fontSize: 22.0,
|
||||
),
|
||||
),
|
||||
content: new Text("$message"),
|
||||
content: Text("$message"),
|
||||
actions: <Widget>[
|
||||
new Padding(
|
||||
padding: new EdgeInsets.only(bottom: 8.0, right: 8.0),
|
||||
child: new FlatButton(
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 8.0, right: 8.0),
|
||||
child: FlatButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(true);
|
||||
},
|
||||
child: new Text("OK"),
|
||||
child: Text("OK"),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -68,14 +67,14 @@ var demoFunctionHandler = new Handler(
|
|||
/// To test on Android:
|
||||
///
|
||||
/// `adb shell am start -W -a android.intent.action.VIEW -d "fluro://deeplink?path=/message&mesage=fluro%20rocks%21%21" com.theyakka.fluro`
|
||||
var deepLinkHandler = new Handler(
|
||||
var deepLinkHandler = Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
String colorHex = params["color_hex"]?.first;
|
||||
String result = params["result"]?.first;
|
||||
Color color = new Color(0xFFFFFFFF);
|
||||
Color color = Color(0xFFFFFFFF);
|
||||
if (colorHex != null && colorHex.length > 0) {
|
||||
color = new Color(ColorHelpers.fromHexString(colorHex));
|
||||
color = Color(ColorHelpers.fromHexString(colorHex));
|
||||
}
|
||||
return new DemoSimpleComponent(
|
||||
return DemoSimpleComponent(
|
||||
message: "DEEEEEP LINK!!!", color: color, result: result);
|
||||
});
|
||||
|
|
|
@ -18,7 +18,7 @@ class Routes {
|
|||
static String deepLink = "/message";
|
||||
|
||||
static void configureRoutes(Router router) {
|
||||
router.notFoundHandler = new Handler(
|
||||
router.notFoundHandler = Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
print("ROUTE WAS NOT FOUND !!!");
|
||||
});
|
||||
|
|
|
@ -48,10 +48,10 @@ class ColorHelpers {
|
|||
if (value >= _kMinContrastModifierRange &&
|
||||
value <= _kMaxContrastModifierRange) {
|
||||
return prefer == ContrastPreference.light
|
||||
? new Color(0xFFFFFFFF)
|
||||
: new Color(0xFF000000);
|
||||
? Color(0xFFFFFFFF)
|
||||
: Color(0xFF000000);
|
||||
}
|
||||
}
|
||||
return value > 0.6 ? new Color(0xFF000000) : new Color(0xFFFFFFFF);
|
||||
return value > 0.6 ? Color(0xFF000000) : Color(0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,5 +10,5 @@ import 'components/app/app_component.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
void main() {
|
||||
runApp(new AppComponent());
|
||||
runApp(AppComponent());
|
||||
}
|
||||
|
|
|
@ -11,6 +11,13 @@ flutter:
|
|||
assets:
|
||||
- assets/images/logo_fluro.png
|
||||
- assets/images/acc_boom.png
|
||||
- assets/images/ic_result_hz.png
|
||||
- assets/images/ic_function_hz.png
|
||||
- assets/images/ic_transform_custom_hz.png
|
||||
- assets/images/ic_transform_fade_in_hz.png
|
||||
- assets/images/ic_transform_fade_out_hz.png
|
||||
- assets/images/ic_transform_global_hz.png
|
||||
- assets/images/ic_transform_native_hz.png
|
||||
fonts:
|
||||
- family: Lazer84
|
||||
fonts:
|
||||
|
|
|
@ -46,6 +46,8 @@ enum TransitionType {
|
|||
inFromBottom,
|
||||
fadeIn,
|
||||
custom, // if using custom then you must also provide a transition
|
||||
material,
|
||||
materialFullScreenDialog,
|
||||
cupertino,
|
||||
cupertinoFullScreenDialog,
|
||||
}
|
||||
|
|
|
@ -12,14 +12,14 @@ import 'dart:io';
|
|||
|
||||
import 'package:fluro/fluro.dart';
|
||||
import 'package:fluro/src/common.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Router {
|
||||
static final appRouter = new Router();
|
||||
static final appRouter = Router();
|
||||
|
||||
/// The tree structure that stores the defined routes
|
||||
final RouteTree _routeTree = new RouteTree();
|
||||
final RouteTree _routeTree = RouteTree();
|
||||
|
||||
/// Generic handler for when a route has not been defined
|
||||
Handler notFoundHandler;
|
||||
|
@ -28,7 +28,8 @@ class Router {
|
|||
void define(String routePath,
|
||||
{@required Handler handler, TransitionType transitionType}) {
|
||||
_routeTree.addRoute(
|
||||
new AppRoute(routePath, handler, transitionType: transitionType));
|
||||
AppRoute(routePath, handler, transitionType: transitionType),
|
||||
);
|
||||
}
|
||||
|
||||
/// Finds a defined [AppRoute] for the path value. If no [AppRoute] definition was found
|
||||
|
@ -51,7 +52,7 @@ class Router {
|
|||
transitionsBuilder: transitionBuilder,
|
||||
transitionDuration: transitionDuration);
|
||||
Route<dynamic> route = routeMatch.route;
|
||||
Completer completer = new Completer();
|
||||
Completer completer = Completer();
|
||||
Future future = completer.future;
|
||||
if (routeMatch.matchType == RouteMatchType.nonVisual) {
|
||||
completer.complete("Non visual route type.");
|
||||
|
@ -83,13 +84,13 @@ class Router {
|
|||
Route<Null> _notFoundRoute(BuildContext context, String path) {
|
||||
RouteCreator<Null> creator =
|
||||
(RouteSettings routeSettings, Map<String, List<String>> parameters) {
|
||||
return new MaterialPageRoute<Null>(
|
||||
return MaterialPageRoute<Null>(
|
||||
settings: routeSettings,
|
||||
builder: (BuildContext context) {
|
||||
return notFoundHandler.handlerFunc(context, parameters);
|
||||
});
|
||||
};
|
||||
return creator(new RouteSettings(name: path), null);
|
||||
return creator(RouteSettings(name: path), null);
|
||||
}
|
||||
|
||||
///
|
||||
|
@ -100,7 +101,7 @@ class Router {
|
|||
RouteTransitionsBuilder transitionsBuilder}) {
|
||||
RouteSettings settingsToUse = routeSettings;
|
||||
if (routeSettings == null) {
|
||||
settingsToUse = new RouteSettings(name: path);
|
||||
settingsToUse = RouteSettings(name: path);
|
||||
}
|
||||
AppRouteMatch match = _routeTree.matchRoute(path);
|
||||
AppRoute route = match?.route;
|
||||
|
@ -110,7 +111,7 @@ class Router {
|
|||
transition = route != null ? route.transitionType : TransitionType.native;
|
||||
}
|
||||
if (route == null && notFoundHandler == null) {
|
||||
return new RouteMatch(
|
||||
return RouteMatch(
|
||||
matchType: RouteMatchType.noMatch,
|
||||
errorMessage: "No matching route was found");
|
||||
}
|
||||
|
@ -118,7 +119,7 @@ class Router {
|
|||
match?.parameters ?? <String, List<String>>{};
|
||||
if (handler.type == HandlerType.function) {
|
||||
handler.handlerFunc(buildContext, parameters);
|
||||
return new RouteMatch(matchType: RouteMatchType.nonVisual);
|
||||
return RouteMatch(matchType: RouteMatchType.nonVisual);
|
||||
}
|
||||
|
||||
RouteCreator creator =
|
||||
|
@ -127,29 +128,38 @@ class Router {
|
|||
transition == TransitionType.nativeModal);
|
||||
if (isNativeTransition) {
|
||||
if (Platform.isIOS) {
|
||||
return new CupertinoPageRoute<dynamic>(
|
||||
return CupertinoPageRoute<dynamic>(
|
||||
settings: routeSettings,
|
||||
fullscreenDialog: transition == TransitionType.nativeModal,
|
||||
builder: (BuildContext context) {
|
||||
return handler.handlerFunc(context, parameters);
|
||||
});
|
||||
} else if (transition == TransitionType.cupertino ||
|
||||
transition == TransitionType.cupertinoFullScreenDialog) {
|
||||
return new CupertinoPageRoute<dynamic>(
|
||||
settings: routeSettings,
|
||||
fullscreenDialog:
|
||||
transition == TransitionType.cupertinoFullScreenDialog,
|
||||
builder: (BuildContext context) {
|
||||
return handler.handlerFunc(context, parameters);
|
||||
});
|
||||
} else {
|
||||
return new MaterialPageRoute<dynamic>(
|
||||
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) {
|
||||
|
@ -157,7 +167,7 @@ class Router {
|
|||
} else {
|
||||
routeTransitionsBuilder = _standardTransitionsBuilder(transition);
|
||||
}
|
||||
return new PageRouteBuilder<dynamic>(
|
||||
return PageRouteBuilder<dynamic>(
|
||||
settings: routeSettings,
|
||||
pageBuilder: (BuildContext context, Animation<double> animation,
|
||||
Animation<double> secondaryAnimation) {
|
||||
|
@ -168,7 +178,7 @@ class Router {
|
|||
);
|
||||
}
|
||||
};
|
||||
return new RouteMatch(
|
||||
return RouteMatch(
|
||||
matchType: RouteMatchType.visual,
|
||||
route: creator(settingsToUse, parameters),
|
||||
);
|
||||
|
@ -179,7 +189,7 @@ class Router {
|
|||
return (BuildContext context, Animation<double> animation,
|
||||
Animation<double> secondaryAnimation, Widget child) {
|
||||
if (transitionType == TransitionType.fadeIn) {
|
||||
return new FadeTransition(opacity: animation, child: child);
|
||||
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);
|
||||
|
@ -194,8 +204,8 @@ class Router {
|
|||
endOffset = topLeft;
|
||||
}
|
||||
|
||||
return new SlideTransition(
|
||||
position: new Tween<Offset>(
|
||||
return SlideTransition(
|
||||
position: Tween<Offset>(
|
||||
begin: startOffset,
|
||||
end: endOffset,
|
||||
).animate(animation),
|
||||
|
|
|
@ -71,7 +71,7 @@ class RouteTree {
|
|||
// could be affected
|
||||
throw ("Default route was already defined");
|
||||
}
|
||||
var node = new RouteTreeNode(path, RouteTreeNodeType.component);
|
||||
var node = RouteTreeNode(path, RouteTreeNodeType.component);
|
||||
node.routes = [route];
|
||||
_nodes.add(node);
|
||||
_hasDefaultRoute = true;
|
||||
|
@ -87,7 +87,7 @@ class RouteTree {
|
|||
RouteTreeNode node = _nodeForComponent(component, parent);
|
||||
if (node == null) {
|
||||
RouteTreeNodeType type = _typeForComponent(component);
|
||||
node = new RouteTreeNode(component, type);
|
||||
node = RouteTreeNode(component, type);
|
||||
node.parent = parent;
|
||||
if (parent == null) {
|
||||
_nodes.add(node);
|
||||
|
@ -135,7 +135,7 @@ class RouteTree {
|
|||
if (isMatch) {
|
||||
RouteTreeNodeMatch parentMatch = nodeMatches[node.parent];
|
||||
RouteTreeNodeMatch match =
|
||||
new RouteTreeNodeMatch.fromMatch(parentMatch, node);
|
||||
RouteTreeNodeMatch.fromMatch(parentMatch, node);
|
||||
if (node.isParameter()) {
|
||||
String paramKey = node.part.substring(1);
|
||||
match.parameters[paramKey] = [pathPart];
|
||||
|
@ -165,7 +165,7 @@ class RouteTree {
|
|||
nodeToUse.routes != null &&
|
||||
nodeToUse.routes.length > 0) {
|
||||
List<AppRoute> routes = nodeToUse.routes;
|
||||
AppRouteMatch routeMatch = new AppRouteMatch(routes[0]);
|
||||
AppRouteMatch routeMatch = AppRouteMatch(routes[0]);
|
||||
routeMatch.parameters = match.parameters;
|
||||
return routeMatch;
|
||||
}
|
||||
|
@ -219,8 +219,8 @@ class RouteTree {
|
|||
}
|
||||
|
||||
Map<String, List<String>> parseQueryString(String query) {
|
||||
var search = new RegExp('([^&=]+)=?([^&]*)');
|
||||
var params = new Map<String, List<String>>();
|
||||
var search = RegExp('([^&=]+)=?([^&]*)');
|
||||
var params = Map<String, List<String>>();
|
||||
if (query.startsWith('?')) query = query.substring(1);
|
||||
decode(String s) => Uri.decodeComponent(s.replaceAll('+', ' '));
|
||||
for (Match match in search.allMatches(query)) {
|
||||
|
|
|
@ -2,7 +2,7 @@ name: fluro
|
|||
description: >
|
||||
Fluro is a Flutter routing library that adds flexible routing options like wildcards, named
|
||||
parameters and clear route definitions.
|
||||
version: 1.5.0
|
||||
version: 1.5.1
|
||||
author: Yakka, LLC <apps@theyakka.com>
|
||||
homepage: https://github.com/theyakka/fluro
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ void main() {
|
|||
(WidgetTester tester) async {
|
||||
String path = "/users/1234";
|
||||
String route = "/users/:id";
|
||||
Router router = new Router();
|
||||
Router router = Router();
|
||||
router.define(route, handler: null);
|
||||
AppRouteMatch match = router.match(path);
|
||||
expect(
|
||||
|
@ -29,7 +29,7 @@ void main() {
|
|||
(WidgetTester tester) async {
|
||||
String path = "/users/1234?name=luke";
|
||||
String route = "/users/:id";
|
||||
Router router = new Router();
|
||||
Router router = Router();
|
||||
router.define(route, handler: null);
|
||||
AppRouteMatch match = router.match(path);
|
||||
expect(
|
||||
|
@ -44,7 +44,7 @@ void main() {
|
|||
(WidgetTester tester) async {
|
||||
String path = "/users/create?name=luke&phrase=hello%20world&number=7";
|
||||
String route = "/users/create";
|
||||
Router router = new Router();
|
||||
Router router = Router();
|
||||
router.define(route, handler: null);
|
||||
AppRouteMatch match = router.match(path);
|
||||
expect(
|
||||
|
@ -61,7 +61,7 @@ void main() {
|
|||
String path =
|
||||
"/users/create?name=luke&phrase=hello%20world&number=7&number=10&number=13";
|
||||
String route = "/users/create";
|
||||
Router router = new Router();
|
||||
Router router = Router();
|
||||
router.define(route, handler: null);
|
||||
AppRouteMatch match = router.match(path);
|
||||
expect(
|
||||
|
@ -76,7 +76,7 @@ void main() {
|
|||
(WidgetTester tester) async {
|
||||
String path = "/users/1234";
|
||||
String route = "/users/:id";
|
||||
Router router = new Router();
|
||||
Router router = Router();
|
||||
router.define(route,
|
||||
handler: null, transitionType: TransitionType.inFromRight);
|
||||
AppRouteMatch match = router.match(path);
|
||||
|
|