Skip to content

Instantly share code, notes, and snippets.

@esDotDev
Last active January 30, 2022 23:17
Show Gist options
  • Save esDotDev/b3c7593cd76d54ea24c7ee766d918ee8 to your computer and use it in GitHub Desktop.
Save esDotDev/b3c7593cd76d54ea24c7ee766d918ee8 to your computer and use it in GitHub Desktop.
class UrlRouter extends RouterDelegate<String> with ChangeNotifier, PopNavigatorRouterDelegateMixin {
UrlRouter({String url = '/', this.onGeneratePages, this.builder, this.onPopPage, this.onChanging}) {
_initialUrl = url;
assert(onGeneratePages != null || builder != null,
'UrlRouter expects you to implement `builder` or `onGeneratePages` (or both)');
}
/// This delegat analagous to MaterialApp.routes / onGenerateRoute
final List<Page<dynamic>> Function(UrlRouter router)? onGeneratePages;
/// Wrap widgets around the [Navigator] widget.
final Widget Function(UrlRouter router, Widget navigator)? builder;
/// Optionally provide a way for the parent to implement custom `onPopPage` logic.
final PopPageCallback? onPopPage;
/// Set from inside the build method, allows us to avoid passing context into delegates
late BuildContext context;
@override
@protected
String? get currentConfiguration => _url;
@override
GlobalKey<NavigatorState>? get navigatorKey => _navKey;
final GlobalKey<NavigatorState> _navKey = GlobalKey();
late final String _initialUrl;
String _url = '';
String get url => _url;
set url(String value) {
if (value != _url) {
if (newUrl != null) {
_url = newUrl;
notifyListeners();
}
}
}
@override
Future<void> setInitialRoutePath(String configuration) {
if (configuration == '/') {
configuration = _url = _initialUrl;
}
url = configuration;
super.setInitialRoutePath(url);
return SynchronousFuture(null);
}
@override
Widget build(BuildContext context) {
final pages = onGeneratePages?.call(this) ?? [];
bool handlePopPage(Route<dynamic> route, dynamic settings) {
if (pages.length > 1 && route.didPop(settings)) {
return true;
}
return false;
}
this.context = context;
Widget content = Navigator(
key: _navKey,
onPopPage: onPopPage ?? handlePopPage,
pages: pages,
);
if (builder != null) {
content = builder!.call(this, content);
}
return content;
}
@override
SynchronousFuture<void> setNewRoutePath(configuration) {
url = configuration;
return SynchronousFuture(null);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment