Skip to content

Commit

Permalink
remove PageBuilder ToUri args
Browse files Browse the repository at this point in the history
  • Loading branch information
chen56 committed Apr 30, 2024
1 parent a34ba78 commit 48b6981
Show file tree
Hide file tree
Showing 12 changed files with 106 additions and 125 deletions.
8 changes: 4 additions & 4 deletions bake
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,9 @@ _run() {
caller_line=$(caller 0 | awk '{print $1}')

if ! _is_cmd "$cmd" ; then
echo "$_ROOT_BAKE_PATH:$caller_line ⚪️ ▶︎${FUNCNAME[1]}() ▶︎【$workdir$ $*"
echo "$_ROOT_BAKE_PATH:$caller_line ⚪️ ▶︎${FUNCNAME[1]}() ▶︎【$PWD$ $*"
else
echo "$_ROOT_BAKE_PATH:$caller_line 🔵 ▶︎${FUNCNAME[1]}() ▶︎【$workdir$ $*"
echo "$_ROOT_BAKE_PATH:$caller_line 🔵 ▶︎${FUNCNAME[1]}() ▶︎【$PWD$ $*"
"$@"
fi
# 退出工作目录,不弄脏环境,不需要打印popd执行结果
Expand All @@ -123,7 +123,7 @@ _run() {
##########################################


pkgs() { for pkg in ${!_pkgs[*]} ; do echo "$pkg:${_pkgs[$pkg]}"; done; }
pkgs() { for pkg in ${!_pkgs[*]} ; do echo "$pkg:${_pkgs[$pkg]}"; done; }
run() { for pkg in ${!_pkgs[*]} ; do _run "$pkg" "$@" ; done }
install() { _run_all install; }
get() { _run_all install; }
Expand All @@ -132,7 +132,7 @@ upgrade() { _run_all upgrade; }
clean() { _run_all clean; }
test() { _run_all test; }
gen() { _run_all gen; }

dart_fix() { run dart fix $@; }

# 根项目,主要是bin/辅助工具等
root.run() { _run root "$@"; }
Expand Down
9 changes: 3 additions & 6 deletions notes/flutter_web/lib/routes/layout.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,23 @@ import 'package:flutter/material.dart';
import 'package:you_flutter/router.dart';

/// ref: [PageLayoutBuilder]
Widget layout(BuildContext context, ToUri uri, PageBuilder builder) {
Widget layout(BuildContext context, PageBuilder builder) {
// ignore: unnecessary_type_check
assert(layout is PageLayoutBuilder);
return RootLayout(
uri: uri,
builder: builder,
);
}

@immutable
final class RootLayout extends StatelessWidget {
final PageBuilder builder;
final ToUri uri;

const RootLayout({super.key, required this.uri, required this.builder});
const RootLayout({super.key, required this.builder});

@override
Widget build(BuildContext context) {
var child = builder(context, uri);

var child = builder(context);

NavigationRailDestination rail({required String title, required IconData icon}) {
return NavigationRailDestination(
Expand Down
8 changes: 3 additions & 5 deletions notes/flutter_web/lib/routes/page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
import 'package:flutter/material.dart';
import 'package:you_flutter/router.dart';

RootPage build(BuildContext context, ToUri uri) {
return RootPage(uri: uri);
RootPage build(BuildContext context) {
return const RootPage();
}

class RootPage extends StatelessWidget {
final ToUri uri;

const RootPage({required this.uri, super.key});
const RootPage({super.key});

@override
Widget build(BuildContext context) {
Expand Down
1 change: 0 additions & 1 deletion packages/you_cli/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ dependencies:
you_dart: ^0.0.4

dev_dependencies:
lints: ^3.0.0
test:


Expand Down
1 change: 0 additions & 1 deletion packages/you_dart/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ dependencies:
collection: ^1.18.0

dev_dependencies:
lints: ^3.0.0
test: ^1.24.0
flutter_test:
sdk: flutter
Expand Down
137 changes: 67 additions & 70 deletions packages/you_flutter/lib/src/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,57 @@ ref:
*/

typedef PageBuilder = Widget Function(BuildContext context, ToUri uri);
typedef PageLayoutBuilder = Widget Function(BuildContext context, ToUri uri, PageBuilder builder);
typedef PageBuilder = Widget Function(BuildContext context);
typedef PageLayoutBuilder = Widget Function(BuildContext context, PageBuilder builder);
typedef LazyPageBuilder = Future<PageBuilder> Function();
// typedef PageBuilderAsync = Future<Widget> Function(BuildContext context, ToUri uri);

class NotFoundError extends ArgumentError {
NotFoundError({required Uri invalidValue, String name = "uri", String message = "Not Found"}) : super.value(invalidValue, name, message);
}

mixin RouterMixin {
YouRouter get router;

ToUri match(Uri uri) {
var root = router.root;
assert(uri.path.startsWith("/"));
if (uri.path == "/") return ToUri._(uri: uri, to: root, routeParameters: const {});

Map<String, String> params = {};
return root._match(uri: uri, segments: uri.pathSegments, params: params);
}

void to(Uri uri) {
ToUri to = match(uri);
var result = router._routerDelegate.setNewRoutePath(to);
bool completed = false;
result.whenComplete(() => completed = true);
assert(completed, "bug: internal ensure routerDelegate.setNewRoutePath is sync implement");
}
}

class RouteContext with RouterMixin {
RouteContext._(this.router, this.uri);

@override
final YouRouter router;
final ToUri uri;
}

/// TODO P1 应针对2种flutter 支持的route模式进行适配:
/// path base: https://example.com/product/1
/// fragment base: https://example.com/base-harf/#/product/1
///
class YouRouter {
class YouRouter with RouterMixin {
YouRouter({
required this.root,

/// [PlatformRouteInformationProvider.initialRouteInformation]
required this.initial,
required GlobalKey<NavigatorState> navigatorKey,
}) : _navigatorKey = navigatorKey, assert(root.templatePath == "/") {
}) : _navigatorKey = navigatorKey,
assert(root.templatePath == "/") {
_routerDelegate = LoggableRouterDelegate(logger: logger, delegate: _RouterDelegate(navigatorKey: _navigatorKey, router: this));
_config = RouterConfig<Object>(
routeInformationProvider: PlatformRouteInformationProvider(initialRouteInformation: RouteInformation(uri: initial)),
Expand All @@ -75,31 +105,16 @@ class YouRouter {
late final RouterConfig<Object> _config;
late final RouterDelegate<Object> _routerDelegate;

static YouRouter of(BuildContext context) {
var result = context.findAncestorWidgetOfExactType<_RouterScope>();
static RouteContext of(BuildContext context) {
var result = context.findAncestorWidgetOfExactType<_RouteScope>();
assert(result != null, "YouRouter not found, please: MaterialApp.router(routerConfig:YouRouter(...).config())");
return result!.router;
}

ToUri matchUri(Uri uri) {
assert(uri.path.startsWith("/"));
if (uri.path == "/") return ToUri._(uri: uri, to: root, routeParameters: const {});

Map<String, String> params = {};
return root._match(uri: uri, segments: uri.pathSegments, params: params);
return RouteContext._(result!.router, result.uri);
}

ToUri match(String uri) => matchUri(Uri.parse(uri));

RouterConfig<Object> config() => _config;

void to(Uri uri) {
ToUri to = matchUri(uri);
var result = _routerDelegate.setNewRoutePath(to);
bool completed = false;
result.whenComplete(() => completed = true);
assert(completed, "bug: internal ensure routerDelegate.setNewRoutePath is sync implement");
}
@override
YouRouter get router => this;
}

enum RoutePartType {
Expand Down Expand Up @@ -143,12 +158,12 @@ base class To {
final PageLayoutBuilder? layout;

// TODO P1 root Node的part是routes,有问题!
To(this.part, {
To(
this.part, {
PageBuilder? builder,
this.layout,
this.children = const [],
})
: _builder = builder,
}) : _builder = builder,
assert(part == "/" || !part.contains("/"), "part:'$part' should be '/' or legal directory name") {
var parsed = _parse(part);
_name = parsed.$1;
Expand All @@ -159,26 +174,27 @@ base class To {
}
}

To.lazy(String part, {
To.lazy(
String part, {
LazyPageBuilder? builder,
List<To> children = const [],
}) : this(
part,
builder: _asyncToSync(builder),
children: children,
);
part,
builder: _asyncToSync(builder),
children: children,
);

static PageBuilder? _asyncToSync(LazyPageBuilder? builder) {
if (builder == null) {
return null;
}
return (BuildContext context, ToUri uri) =>
FutureBuilder<Widget>(
future: builder().then((b) => b(context, uri)),
return (BuildContext context) => FutureBuilder<Widget>(
future: builder().then((b) => b(context)),
builder: (context, snapshot) {
final router = YouRouter.of(context);
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Text('page load error($uri): ${snapshot.error} \n${snapshot.stackTrace}');
return Text('page load error(${router.uri}): ${snapshot.error} \n${snapshot.stackTrace}');
}
return snapshot.data!;
}
Expand Down Expand Up @@ -208,7 +224,8 @@ base class To {
To? findLayoutNode() {
return _findLayoutNode(this);
}
/// To类型完全相同,才认为节点兼容

/// To类型完全相同,才认为节点兼容
To? _findLayoutNode(To toFind) {
if (isRoot) {
// 路由To类型不兼容
Expand Down Expand Up @@ -244,14 +261,9 @@ base class To {
}

To? matchChild({required String segment}) {
To? matched = children
.where((e) => e._type == RoutePartType.static)
.where((e) => segment == e._name)
.firstOrNull;
To? matched = children.where((e) => e._type == RoutePartType.static).where((e) => segment == e._name).firstOrNull;
if (matched != null) return matched;
matched = children
.where((e) => e._type == RoutePartType.dynamic || e._type == RoutePartType.dynamicRest)
.firstOrNull;
matched = children.where((e) => e._type == RoutePartType.dynamic || e._type == RoutePartType.dynamicRest).firstOrNull;
if (matched != null) return matched;
return null;
}
Expand Down Expand Up @@ -353,11 +365,7 @@ ${" " * level}</Route>''';
}

To? find(String templatePath) {
return _findBySegments(Uri
.parse(templatePath)
.pathSegments
.where((e) => e.isNotEmpty)
.toList());
return _findBySegments(Uri.parse(templatePath).pathSegments.where((e) => e.isNotEmpty).toList());
}

To? _findBySegments(List<String> segments) {
Expand Down Expand Up @@ -389,8 +397,7 @@ class ToUri implements Uri {
required Uri uri,
required this.to,
required Map<String, String> routeParameters,
})
: _uri = uri,
}) : _uri = uri,
_routeParameters = /*safe copy*/ Map.from(routeParameters);

Map<String, String> get routeParameters {
Expand Down Expand Up @@ -489,17 +496,7 @@ class ToUri implements Uri {
Map<String, dynamic>? queryParameters,
String? fragment,
}) {
return ToUri._(to: to,
routeParameters: routeParameters,
uri: _uri.replace(scheme: scheme,
userInfo: userInfo,
host: host,
port: port,
path: path,
pathSegments: pathSegments,
query: query,
queryParameters: queryParameters,
fragment: fragment));
return ToUri._(to: to, routeParameters: routeParameters, uri: _uri.replace(scheme: scheme, userInfo: userInfo, host: host, port: port, path: path, pathSegments: pathSegments, query: query, queryParameters: queryParameters, fragment: fragment));
}

@override
Expand All @@ -520,16 +517,16 @@ class ToUri implements Uri {

/// this class only use for [router] ,
/// ref: [YouRouter.of]
class _RouterScope extends StatelessWidget {
const _RouterScope({
class _RouteScope extends StatelessWidget {
const _RouteScope({
required this.router,
required this.builder,
required this.routerDelegate,
required this.uri,
});

final YouRouter router;
final WidgetBuilder builder;
final _RouterDelegate routerDelegate;
final ToUri uri;

@override
Widget build(BuildContext context) {
Expand All @@ -545,7 +542,7 @@ class _RouteInformationParser extends RouteInformationParser<ToUri> {
// TODO P1 routeInformation.uri 这个在web上是fragments或path base路由,要区分
@override
Future<ToUri> parseRouteInformation(RouteInformation routeInformation) {
ToUri location = router.matchUri(routeInformation.uri);
ToUri location = router.match(routeInformation.uri);
return SynchronousFuture(location);
}

Expand Down Expand Up @@ -596,11 +593,11 @@ class _RouterDelegate extends RouterDelegate<ToUri> with ChangeNotifier, PopNavi
throw NotFoundError(invalidValue: uri);
}
// 在本router api稳定下来之前,不暴露flutter Page 相关api
return MaterialPage(key: ValueKey(uri), child: uri.to._builder!(context, uri));
return MaterialPage(key: ValueKey(uri), child: uri.to._builder!(context));
}

return _RouterScope(
routerDelegate: this,
return _RouteScope(
uri: stack.first,
router: router,
builder: (context) {
return Navigator(
Expand Down
1 change: 0 additions & 1 deletion packages/you_flutter/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^3.0.0
checks: ^0.3.0

dependency_overrides:
Expand Down
6 changes: 3 additions & 3 deletions packages/you_flutter/test/router_to_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void main() {
// Tos.root.user("chen56").repository("note").tree.branch("main").file("a/b/c.dart");
// Tos.user_repository_tree_branch_file(user:"chen56",repository:"note",branch:"main",file:"a/b");
void match(String path, {required ({String location, Map<String, String> routeParameters}) expected}) {
var match = router.match(path);
var match = router.match(Uri.parse(path));
expect(match.to.templatePath, equals(expected.location));
expect(match.routeParameters, equals(expected.routeParameters));
}
Expand Down Expand Up @@ -93,14 +93,14 @@ void main() {
);

void match(String path, {required String matched, required Map<String, String> params}) {
var match = router.match(path);
var match = router.match(Uri.parse(path));
expect(match.to.templatePath, equals(matched));
expect(match.routeParameters, equals(params));
}

void checkNotFound({required String uri}) {
try {
router.match(uri);
router.match(Uri.parse(uri));
fail("Never");
} catch (e) {
check(e).isA<NotFoundError>();
Expand Down
Loading

0 comments on commit 48b6981

Please sign in to comment.