Skip to content

Commit

Permalink
准备给To增加继承的能力,观察下是否把接口适配放在layout还是To更合适
Browse files Browse the repository at this point in the history
  • Loading branch information
chen56 committed Apr 27, 2024
1 parent a3393d3 commit ab8509c
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 49 deletions.
5 changes: 5 additions & 0 deletions notes/flutter_web/lib/routes/notes/layout.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import 'package:flutter/widgets.dart';
import 'package:you_flutter/router.dart';
import 'package:you_note_dart/note.dart';
import 'package:you_note_dart/note_layouts.dart';

PageBuilder layout(NoteBuilder builder) {
return (context, uri) => NoteLayoutStyle1(uri: uri, builder: builder);
}

Widget layout2(BuildContext context, ToUri uri, NoteBuilder builder) {
return NoteLayoutStyle1(uri: uri, builder: builder);
}
48 changes: 31 additions & 17 deletions notes/learn_dart/test/syntax/types/types_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,11 @@ void main() {
Symbol? a = #a;
Symbol? a2 = #a;
check(a).equals(a2);

});
test('Object equals', () {
check(const Object()==const Object()).equals(true);
check( Object()!=const Object()).equals(true);
check( Object()!= Object()).equals(true);

check(const Object() == const Object()).equals(true);
check(Object() != const Object()).equals(true);
check(Object() != Object()).equals(true);
});
});
group("Enum", () {
Expand Down Expand Up @@ -77,40 +75,51 @@ void main() {
});
});
group("runtimeType 关系?", () {
test('type ==', () {
// 2s多
DoubleLinkedQueue q = DoubleLinkedQueue();
check(q.runtimeType == DoubleLinkedQueue).isTrue();
check(q.runtimeType != Queue).isTrue();
});

test('SpecificTypeFuncInject扩展Function后可在里面加点料,方便mate模型生成代码', () {
// 2s多
for(int i=0;i<1000*1000*1000;i++){
for (int i = 0; i < 1000 * 1000 * 1000; i++) {
// ignore: unused_local_variable
var x =[] is ListBase;
var x = [] is ListBase;
// check([] is ListBase).equals(true);
}
});

});
group("Unique", () {
test(' x', () {
Uniquely x = Uniquely(name: "x") ;
check(x==x).equals(false);
Uniquely x = Uniquely(name: "x");
check(x == x).equals(false);
});
});
}

class SegmentedButton$Mate<T> {
String injectInfo;

SegmentedButton$Mate({this.onSelectionChanged}) : injectInfo = "${onSelectionChanged?.name}";
void Function<T>(Set<T>)? onSelectionChanged;
}

extension SpecificTypeFuncInject<T> on void Function<T>(Set<T> selected) {
static final _name = Expando<String>();

String get name => _name[this] ?? "";

set name(String v) => _name[this] = v;

inject({
required String func,
}) {
_name[this] = func;
}
}

class Uniquely {
final String name;

Expand All @@ -131,18 +140,23 @@ class Uniquely {
extension FuncCodeInject on Function {
static final _from = Expando<String>();
static final _mode = Expando<InjectMode>();

String get from => _from[this] ?? "";

InjectMode get mode => _mode[this] ?? InjectMode.embed;

set name(String v) => _from[this] = v;

inject(
/// the Mate field Referenced function name
String func, {
/// expected inject code mode
InjectMode mode = InjectMode.refer,

/// is copy function context code
bool copyContext = true,
}) {
/// the Mate field Referenced function name
String func, {
/// expected inject code mode
InjectMode mode = InjectMode.refer,

/// is copy function context code
bool copyContext = true,
}) {
_from[this] = func;
_mode[this] = mode;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/you_flutter/lib/router.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
library you_router;

export 'package:you_flutter/src/router.dart' show YouRouter,To,ToUri,PageBuilder,LazyPageBuilder;
export 'package:you_flutter/src/router.dart' show YouRouter,To,ToUri,PageBuilder,LazyPageBuilder,PageLayoutBuilder;
112 changes: 82 additions & 30 deletions packages/you_flutter/lib/src/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ ref:
*/

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

Expand Down Expand Up @@ -132,25 +133,26 @@ enum RoutePartType {
/// To == go_router.GoRoute
/// 官方的go_router内部略显复杂,且没有我们想要的layout等功能,所以自定一个简化版的to_router
base class To {
/// template is a uri path segment template
/// part may be a template
/// /[user]/[repository]
/// - /dart-lang/sdk => {"user":"dart-lang","repository":"sdk"}
/// - /flutter/flutter => {"user":"flutter","repository":"flutter"}
final String part;
late final String _name;
late final RoutePartType _type;

// TODO 可以使之非空,改为root指向自己
late To _parent = this;

final List<To> children;
late PageBuilder? _builder;
final PageBuilder? _builder;
final PageLayoutBuilder? layout;

To(
this.part, {
Widget Function(BuildContext, ToUri)? builder,
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 @@ -161,25 +163,32 @@ base class To {
}
}

To.lazy(
this.part, {
To.lazy(String part, {
LazyPageBuilder? builder,
this.children = const [],
}) {
_builder = builder == null
? null
: (BuildContext context, ToUri uri) => FutureBuilder<Widget>(
future: builder().then((b) => b(context, uri)),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Text('page load error($uri): ${snapshot.error} \n${snapshot.stackTrace}');
}
return snapshot.data!;
}
return const CircularProgressIndicator();
},
);
List<To> children = const [],
}) : this(
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)),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Text('page load error($uri): ${snapshot.error} \n${snapshot.stackTrace}');
}
return snapshot.data!;
}
return const CircularProgressIndicator();
},
);
}

bool get isRoot => _parent == this;
Expand All @@ -200,6 +209,29 @@ base class To {

int get level => isRoot ? 0 : _parent.level + 1;

To? findLayoutNode() {
return _findLayoutNode(this);
}
/// To类型完全相同,才认为节点兼容
To? _findLayoutNode(To toFind) {
if (isRoot) {
// 路由To类型不兼容
if (runtimeType != toFind.runtimeType) {
return null;
}
// 路由To类型兼容再看是不是有layout
return layout == null ? null : this;
}

// 现在是非root, 不兼容就向上找
if (runtimeType != toFind.runtimeType) {
return _parent._findLayoutNode(toFind);
}

// 没有就继续向上找
return layout != null ? this : _parent._findLayoutNode(toFind);
}

ToUri _match({
required Uri uri,
required List<String> segments,
Expand All @@ -216,9 +248,14 @@ 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 @@ -320,7 +357,11 @@ ${" " * 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 @@ -352,7 +393,8 @@ 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 @@ -451,7 +493,17 @@ 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 Down
1 change: 1 addition & 0 deletions packages/you_note_dart/lib/note.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
library note;

export 'src/note.dart' show Cell, NoteBuilder, LazyNoteBuilder, NoteSystem;
export 'src/contents/contents.dart' show contents;
export 'src/contents/mockup.dart' show MockupWindow;
export 'src/contents/markdown_content.dart' show MD;
3 changes: 2 additions & 1 deletion packages/you_note_dart/lib/note_layouts.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
library note;

export 'src/layouts/note_layout_style_1.dart' show NoteLayoutStyle1;
export 'src/layouts/note_layout_style_1.dart' show NoteLayoutStyle1;
export 'src/layouts/note_layout_default.dart' show NoteLayoutDefault;
39 changes: 39 additions & 0 deletions packages/you_note_dart/lib/src/layouts/note_layout_default.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

import 'package:flutter/material.dart';
import 'package:you_flutter/router.dart';
import 'package:you_flutter/state.dart';
import 'package:you_note_dart/note.dart';

final class NoteLayoutDefault extends StatelessWidget {
final NoteBuilder builder;
final ToUri uri;

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

@override
Widget build(BuildContext context) {
// collect note page contents(from print(xxx))
Cell rootCell = Cell.empty();
builder(context, rootCell);

return Scaffold(
body: SafeArea(
child: SelectionArea(
/// Watch是you_flutter的state管理组件, 被其包裹的状态可以被观测刷新(ref: Cell._contents = [].signal())
child: Watch((context) {
// contents是收集到调用print(xx)的所有结果
var pageContents = rootCell.toList().expand((cell) sync* {
for (var content in cell.contents) {
yield Align(
alignment: Alignment.centerLeft,
child: contents.contentToWidget(content),
);
}
}).toList();
return ListView(children: pageContents);
}),
),
),
);
}
}
21 changes: 21 additions & 0 deletions packages/you_note_dart/lib/src/layouts/page_layout_default.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'package:flutter/material.dart';
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});

@override
Widget build(BuildContext context) {
var pageBody = builder(context, uri);
return Scaffold(
body: SafeArea(
child: SelectionArea(
child: pageBody,
),
),
);
}
}
Loading

0 comments on commit ab8509c

Please sign in to comment.