From 48b698185dc160c0f58a6e5fdb405515e1900011 Mon Sep 17 00:00:00 2001 From: Chen Peng Date: Tue, 30 Apr 2024 13:48:11 +0800 Subject: [PATCH] remove PageBuilder ToUri args --- bake | 8 +- notes/flutter_web/lib/routes/layout.dart | 9 +- notes/flutter_web/lib/routes/page.dart | 8 +- packages/you_cli/pubspec.yaml | 1 - packages/you_dart/pubspec.yaml | 1 - packages/you_flutter/lib/src/router.dart | 137 +++++++++--------- packages/you_flutter/pubspec.yaml | 1 - packages/you_flutter/test/router_to_test.dart | 6 +- .../lib/src/contents/markdown_content.dart | 52 +++---- .../lib/src/layouts/note_layout_style_1.dart | 2 +- .../lib/src/layouts/page_layout_default.dart | 5 +- packages/you_note_dart/pubspec.yaml | 1 - 12 files changed, 106 insertions(+), 125 deletions(-) diff --git a/bake b/bake index bd4270d3..04c0cfe5 100755 --- a/bake +++ b/bake @@ -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执行结果 @@ -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; } @@ -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 "$@"; } diff --git a/notes/flutter_web/lib/routes/layout.dart b/notes/flutter_web/lib/routes/layout.dart index fa8d3684..c51a4cb1 100644 --- a/notes/flutter_web/lib/routes/layout.dart +++ b/notes/flutter_web/lib/routes/layout.dart @@ -3,11 +3,10 @@ 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, ); } @@ -15,14 +14,12 @@ Widget layout(BuildContext context, ToUri uri, PageBuilder 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( diff --git a/notes/flutter_web/lib/routes/page.dart b/notes/flutter_web/lib/routes/page.dart index 1b1d4019..a03ada9e 100644 --- a/notes/flutter_web/lib/routes/page.dart +++ b/notes/flutter_web/lib/routes/page.dart @@ -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) { diff --git a/packages/you_cli/pubspec.yaml b/packages/you_cli/pubspec.yaml index f76bb9bd..fcc106be 100644 --- a/packages/you_cli/pubspec.yaml +++ b/packages/you_cli/pubspec.yaml @@ -29,7 +29,6 @@ dependencies: you_dart: ^0.0.4 dev_dependencies: - lints: ^3.0.0 test: diff --git a/packages/you_dart/pubspec.yaml b/packages/you_dart/pubspec.yaml index cf31f801..77b012ba 100644 --- a/packages/you_dart/pubspec.yaml +++ b/packages/you_dart/pubspec.yaml @@ -15,7 +15,6 @@ dependencies: collection: ^1.18.0 dev_dependencies: - lints: ^3.0.0 test: ^1.24.0 flutter_test: sdk: flutter diff --git a/packages/you_flutter/lib/src/router.dart b/packages/you_flutter/lib/src/router.dart index 710786a5..84ac41b0 100644 --- a/packages/you_flutter/lib/src/router.dart +++ b/packages/you_flutter/lib/src/router.dart @@ -40,8 +40,8 @@ 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 Function(); // typedef PageBuilderAsync = Future Function(BuildContext context, ToUri uri); @@ -49,18 +49,48 @@ 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 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 navigatorKey, - }) : _navigatorKey = navigatorKey, assert(root.templatePath == "/") { + }) : _navigatorKey = navigatorKey, + assert(root.templatePath == "/") { _routerDelegate = LoggableRouterDelegate(logger: logger, delegate: _RouterDelegate(navigatorKey: _navigatorKey, router: this)); _config = RouterConfig( routeInformationProvider: PlatformRouteInformationProvider(initialRouteInformation: RouteInformation(uri: initial)), @@ -75,31 +105,16 @@ class YouRouter { late final RouterConfig _config; late final RouterDelegate _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 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 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 { @@ -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; @@ -159,26 +174,27 @@ base class To { } } - To.lazy(String part, { + To.lazy( + String part, { LazyPageBuilder? builder, List 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( - future: builder().then((b) => b(context, uri)), + return (BuildContext context) => FutureBuilder( + 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!; } @@ -208,7 +224,8 @@ base class To { To? findLayoutNode() { return _findLayoutNode(this); } - /// To类型完全相同,才认为节点兼容 + + /// To类型完全相同,才认为节点兼容 To? _findLayoutNode(To toFind) { if (isRoot) { // 路由To类型不兼容 @@ -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; } @@ -353,11 +365,7 @@ ${" " * level}'''; } 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 segments) { @@ -389,8 +397,7 @@ class ToUri implements Uri { required Uri uri, required this.to, required Map routeParameters, - }) - : _uri = uri, + }) : _uri = uri, _routeParameters = /*safe copy*/ Map.from(routeParameters); Map get routeParameters { @@ -489,17 +496,7 @@ class ToUri implements Uri { Map? 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 @@ -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) { @@ -545,7 +542,7 @@ class _RouteInformationParser extends RouteInformationParser { // TODO P1 routeInformation.uri 这个在web上是fragments或path base路由,要区分 @override Future parseRouteInformation(RouteInformation routeInformation) { - ToUri location = router.matchUri(routeInformation.uri); + ToUri location = router.match(routeInformation.uri); return SynchronousFuture(location); } @@ -596,11 +593,11 @@ class _RouterDelegate extends RouterDelegate 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( diff --git a/packages/you_flutter/pubspec.yaml b/packages/you_flutter/pubspec.yaml index d79214f2..31f2e7d0 100644 --- a/packages/you_flutter/pubspec.yaml +++ b/packages/you_flutter/pubspec.yaml @@ -19,7 +19,6 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^3.0.0 checks: ^0.3.0 dependency_overrides: diff --git a/packages/you_flutter/test/router_to_test.dart b/packages/you_flutter/test/router_to_test.dart index 4bb9b9da..196b498a 100644 --- a/packages/you_flutter/test/router_to_test.dart +++ b/packages/you_flutter/test/router_to_test.dart @@ -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 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)); } @@ -93,14 +93,14 @@ void main() { ); void match(String path, {required String matched, required Map 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(); diff --git a/packages/you_note_dart/lib/src/contents/markdown_content.dart b/packages/you_note_dart/lib/src/contents/markdown_content.dart index 994af551..1a5b707c 100644 --- a/packages/you_note_dart/lib/src/contents/markdown_content.dart +++ b/packages/you_note_dart/lib/src/contents/markdown_content.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; -import 'package:flutter_highlight/themes/vs2015.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:markdown/markdown.dart' as md; import 'package:meta/meta.dart'; import 'package:you_note_dart/src/contents/outline.dart'; -import 'package:you_note_dart/src/flutter_highlight.dart'; +// import 'package:you_note_dart/src/flutter_highlight.dart'; +// import 'package:flutter_highlight/themes/vs2015.dart'; class MD extends StatelessWidget { final String text; @@ -107,33 +107,27 @@ class _PreBuilder extends MarkdownElementBuilder { @override Widget? visitText(md.Text text, TextStyle? preferredStyle) { - var highlight = HighlightView( - // The original code to be highlighted - text.textContent, - - // Specify language - // It is recommended to give it a value for performance - language: 'dart', - - // Specify highlight theme - // All available themes are listed in `themes` folder - theme: vs2015Theme, - - // Specify padding - padding: const EdgeInsets.all(12), - - // Specify text style - textStyle: const TextStyle( - fontFamily: 'My awesome monospace font', - fontSize: 16, - ), - ); - var noScroll = Row( - children: [ - Expanded(child: highlight), - ], - ); - + // var highlight = HighlightView( + // // The original code to be highlighted + // text.textContent, + // + // // Specify language + // // It is recommended to give it a value for performance + // language: 'dart', + // + // // Specify highlight theme + // // All available themes are listed in `themes` folder + // theme: vs2015Theme, + // + // // Specify padding + // padding: const EdgeInsets.all(12), + // + // // Specify text style + // textStyle: const TextStyle( + // fontFamily: 'My awesome monospace font', + // fontSize: 16, + // ), + // ); //目前看,markdown中的code/prd 不滚动是不是更好些,一般内容不会很长 return Container( padding: const EdgeInsets.only(right: 100), diff --git a/packages/you_note_dart/lib/src/layouts/note_layout_style_1.dart b/packages/you_note_dart/lib/src/layouts/note_layout_style_1.dart index 1f25f57f..541e2ed9 100644 --- a/packages/you_note_dart/lib/src/layouts/note_layout_style_1.dart +++ b/packages/you_note_dart/lib/src/layouts/note_layout_style_1.dart @@ -51,7 +51,7 @@ class _NoteTreeView extends StatelessWidget { @override Widget build(BuildContext context) { - YouRouter router = YouRouter.of(context); + final router = YouRouter.of(context); var validRoutes = uri.to.root.toList().where((e) => !e.isLeaf || (e.isValid)); var routeWidgets = validRoutes.map((node) { diff --git a/packages/you_note_dart/lib/src/layouts/page_layout_default.dart b/packages/you_note_dart/lib/src/layouts/page_layout_default.dart index e6b5ee1f..173ed5ff 100644 --- a/packages/you_note_dart/lib/src/layouts/page_layout_default.dart +++ b/packages/you_note_dart/lib/src/layouts/page_layout_default.dart @@ -3,13 +3,12 @@ import 'package:you_flutter/router.dart'; final class PageLayoutDefault extends StatelessWidget { final PageBuilder builder; - final ToUri uri; - const PageLayoutDefault({super.key, required this.uri, required this.builder}); + const PageLayoutDefault({super.key, required this.builder}); @override Widget build(BuildContext context) { - var pageBody = builder(context, uri); + var pageBody = builder(context); return Scaffold( body: SafeArea( child: SelectionArea( diff --git a/packages/you_note_dart/pubspec.yaml b/packages/you_note_dart/pubspec.yaml index 4a580b49..e8306a14 100644 --- a/packages/you_note_dart/pubspec.yaml +++ b/packages/you_note_dart/pubspec.yaml @@ -43,7 +43,6 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - flutter_lints: # for NoteDevTool checks: ^0.3.0