Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[go_router] Return a value on pop #2416

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
2f515a8
Added Asyncs pushes and a pop result
NazarenoCavazzon Jul 9, 2022
25577e2
Update go_router.dart
NazarenoCavazzon Jul 9, 2022
2be6daa
Added pushAsync
NazarenoCavazzon Jul 9, 2022
05ab251
Added documentation to the _completers variable
NazarenoCavazzon Jul 9, 2022
9f20a71
Update go_router.dart
NazarenoCavazzon Jul 9, 2022
90954e1
Update go_router_delegate.dart
NazarenoCavazzon Jul 9, 2022
1750b55
Changed T to dynamic
NazarenoCavazzon Jul 9, 2022
06a2ae5
Update go_router.dart
NazarenoCavazzon Jul 9, 2022
b77cc10
Revert "Update go_router.dart"
NazarenoCavazzon Jul 9, 2022
a5a1df9
CHANGELOG updated and version updated in the pubspec.yaml
NazarenoCavazzon Jul 9, 2022
977606e
Added a space
NazarenoCavazzon Jul 9, 2022
d57d39f
Merge remote-tracking branch 'upstream/main' into feat/pop-with-result
NazarenoCavazzon Aug 4, 2022
f1bfddd
Test
NazarenoCavazzon Aug 4, 2022
46d5899
Extension update
NazarenoCavazzon Aug 4, 2022
38814a8
Update extensions.dart
NazarenoCavazzon Aug 4, 2022
8e99376
Update extensions.dart
NazarenoCavazzon Aug 4, 2022
1e6abfe
Test working
NazarenoCavazzon Aug 4, 2022
87818e2
Pop with result working
NazarenoCavazzon Aug 4, 2022
6de9f2a
Test Made
NazarenoCavazzon Aug 4, 2022
121c560
Changelog and version updated
NazarenoCavazzon Aug 4, 2022
63057b5
Changed dynamic to T
NazarenoCavazzon Aug 4, 2022
2c56459
Pop updated to T
NazarenoCavazzon Aug 4, 2022
48688b8
Merge branch 'feat/return-value-on-pop' into feat/pop-with-result
NazarenoCavazzon Aug 5, 2022
5b94f01
Updated pop in extensions :)
NazarenoCavazzon Aug 5, 2022
fbc8d0c
Merge branch 'feat/return-value-on-pop' into feat/pop-with-result
NazarenoCavazzon Aug 5, 2022
dd05959
Update readme
NazarenoCavazzon Aug 5, 2022
5e27ae3
Updated comments and also added documentation for this in the readme
NazarenoCavazzon Aug 5, 2022
0488a2e
Changed sync methods to the async ones
NazarenoCavazzon Aug 5, 2022
10e1181
Merge branch 'feat/return-value-on-pop' into feat/pop-with-result
NazarenoCavazzon Aug 5, 2022
b7431c8
Update Replace
NazarenoCavazzon Aug 8, 2022
3fb8ccd
Update on how we handle replace
NazarenoCavazzon Aug 8, 2022
0061c32
element updated to element2
NazarenoCavazzon Aug 8, 2022
5fffdf3
go_router_builder version updated
NazarenoCavazzon Aug 8, 2022
133e621
Merged main
NazarenoCavazzon Aug 8, 2022
12c7d13
Merge branch 'feat/return-value-on-pop' into feat/pop-with-result
NazarenoCavazzon Aug 11, 2022
12eef5e
go and go named async
NazarenoCavazzon Aug 12, 2022
30449ef
Test updated for go and goNamed
NazarenoCavazzon Aug 12, 2022
57f7f82
Merge remote-tracking branch 'upstream/main' into feat/return-value-o…
NazarenoCavazzon Aug 16, 2022
a1397dc
Completers saved in RouteMatchs rather than in a completer list in th…
NazarenoCavazzon Aug 16, 2022
6fe7ae0
Merge remote-tracking branch 'upstream/main' into feat/return-value-o…
NazarenoCavazzon Aug 18, 2022
5a7418d
Updated PR
NazarenoCavazzon Aug 18, 2022
f8eab3a
Merge remote-tracking branch 'upstream/main' into feat/return-value-o…
NazarenoCavazzon Sep 27, 2022
6f9fa08
Final updates
NazarenoCavazzon Sep 27, 2022
5d909fe
Merge remote-tracking branch 'upstream/main' into feat/return-value-o…
NazarenoCavazzon Oct 12, 2022
6ef8dfd
Update CHANGELOG.md
NazarenoCavazzon Oct 12, 2022
ce29ba7
Final updates
NazarenoCavazzon Oct 12, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
611 changes: 2 additions & 609 deletions packages/go_router/CHANGELOG.md

Large diffs are not rendered by default.

37 changes: 28 additions & 9 deletions packages/go_router/README.md
@@ -1,16 +1,35 @@
# go_router
# go_router_flow

A Declarative Routing Package for Flutter.
This package was created for [SportsVisio's](https://sportsvisio.com/) apps, and it's currently in use and tested, and it'll be updated until the day go_router implements it.

This package uses the Flutter framework's Router API to provide a
convenient, url-based API for navigating between different screens. You can
define URL patterns, navigate using a URL, handle deep links,
and a number of other navigation-related scenarios.
This is a fork of the go_router package that let's you communicate between pages by returning values on pop like in navigator 1.0. This was implemented by adding completers in the routes and waiting for the values when requested.

## Returning values
This is the reason for this package, to be able to return stuff when a screens pop.

Waiting for a value to be returned:

```dart
onTap: () {
// In the new page you can do 'context.pop<bool>(someValue)' to return a value.
final bool? result = await context.push<bool>('/page2');

WidgetsBinding.instance.addPostFrameCallback((_) {
if(result ?? false)...
});
}
```

Returning a value:

```dart
onTap: () => context.pop(true)
```

## Getting Started

Follow the [package install instructions](https://pub.dev/packages/go_router/install),
and you can start using go_router in your app:
Follow the [package install instructions](https://pub.dev/packages/go_router_flow/install),
and you can start using go_router_flow in your app:

```dart
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -204,7 +223,7 @@ final _router = GoRouter(
For more details, see the
[ShellRoute](https://pub.dev/documentation/go_router/latest/go_router/ShellRoute-class.html)
API documentation. For a complete
example, see the
example, see the
[ShellRoute sample](https://github.com/flutter/packages/tree/main/packages/go_router/example/lib/shell_route.dart)
in the example/ directory.

Expand Down
8 changes: 4 additions & 4 deletions packages/go_router/example/lib/async_redirection.dart
Expand Up @@ -5,16 +5,16 @@
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

// This scenario demonstrates how to use redirect to handle a asynchronous
// sign-in flow.
//
// The `StreamAuth` is a mock of google_sign_in. This example wraps it with an
// InheritedNotifier, StreamAuthScope, and relies on
// `dependOnInheritedWidgetOfExactType` to create a dependency between the
// notifier and go_router's parsing pipeline. When StreamAuth broadcasts new
// event, the dependency will cause the go_router to reparse the current url
// notifier and go_router_flow's parsing pipeline. When StreamAuth broadcasts new
// event, the dependency will cause the go_router_flow to reparse the current url
// which will also trigger the redirect.

void main() => runApp(StreamAuthScope(child: App()));
Expand Down Expand Up @@ -52,7 +52,7 @@ class App extends StatelessWidget {
// redirect to the login page if the user is not logged in
redirect: (BuildContext context, GoRouterState state) async {
// Using `of` method creates a dependency of StreamAuthScope. It will
// cause go_router to reparse current route if StreamAuth has new sign-in
// cause go_router_flow to reparse current route if StreamAuth has new sign-in
// information.
final bool loggedIn = await StreamAuthScope.of(context).isSignedIn();
final bool loggingIn = state.subloc == '/login';
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/example/lib/books/main.dart
Expand Up @@ -4,7 +4,7 @@

import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

import 'src/auth.dart';
import 'src/data/author.dart';
Expand Down
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

import '../data.dart';
import '../widgets/book_list.dart';
Expand Down
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

import '../data.dart';
import '../widgets/author_list.dart';
Expand Down
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';
import 'package:url_launcher/link.dart';

import '../data.dart';
Expand Down
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

import '../data.dart';
import '../widgets/book_list.dart';
Expand Down
Expand Up @@ -5,7 +5,7 @@
import 'package:adaptive_navigation/adaptive_navigation.dart';
import 'package:flutter/material.dart';

import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

/// The enum for scaffold tab.
enum ScaffoldTab {
Expand Down
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';
import 'package:url_launcher/link.dart';

import '../auth.dart';
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/example/lib/main.dart
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

// This scenario demonstrates a simple two-page app.
//
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/example/lib/named_routes.dart
Expand Up @@ -8,7 +8,7 @@
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

// This scenario demonstrates how to navigate using named locations instead of
// URLs.
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/example/lib/others/error_screen.dart
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

void main() => runApp(App());

Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/example/lib/others/extra_param.dart
Expand Up @@ -8,7 +8,7 @@
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

final Map<String, dynamic> _families = const JsonDecoder().convert('''
{
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/example/lib/others/init_loc.dart
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

void main() => runApp(App());

Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/example/lib/others/nav_observer.dart
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';
import 'package:logging/logging.dart';

void main() => runApp(App());
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/example/lib/others/push.dart
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

void main() => runApp(App());

Expand Down
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

void main() => runApp(App());

Expand Down
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

void main() => runApp(
const RootRestorationScope(restorationId: 'root', child: App()),
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/example/lib/others/transitions.dart
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

void main() => runApp(App());

Expand Down
Expand Up @@ -8,7 +8,7 @@
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

// This scenario demonstrates how to use path parameters and query parameters.
//
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/example/lib/redirection.dart
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';
import 'package:provider/provider.dart';

// This scenario demonstrates how to use redirect to handle a sign-in flow.
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/example/lib/shell_route.dart
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

final GlobalKey<NavigatorState> _rootNavigatorKey =
GlobalKey<NavigatorState>(debugLabel: 'root');
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/example/lib/sub_routes.dart
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:go_router_flow/go_router.dart';

// This scenario demonstrates an app with multi-level routing.
//
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/example/pubspec.yaml
Expand Up @@ -14,7 +14,7 @@ dependencies:
cupertino_icons: ^1.0.2
flutter:
sdk: flutter
go_router:
go_router_flow:
path: ..
logging: ^1.0.0
package_info_plus: ^1.3.0
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/lib/go_router.dart
Expand Up @@ -4,7 +4,7 @@

/// A declarative router for Flutter based on Navigation 2 supporting
/// deep linking, data-driven routes and more.
library go_router;
library go_router_flow;

export 'src/configuration.dart'
show GoRoute, GoRouterState, RouteBase, ShellRoute;
Expand Down
27 changes: 22 additions & 5 deletions packages/go_router/lib/src/delegate.dart
Expand Up @@ -87,18 +87,24 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList>
return navigator.maybePop();
}

/// Pushes the given location onto the page stack
void push(RouteMatch match) {
/// Pushes the given location onto the page stack with an optional promise.
// Remap the pageKey to allow any number of the same page on the stack.
Future<T?> push<T extends Object?>(RouteMatch match) {
if (match.route is ShellRoute) {
throw GoError('ShellRoutes cannot be pushed');
}

// Remap the pageKey to allow any number of the same page on the stack
final String fullPath = match.fullpath;

// Create a completer for the promise and store it in the completers map.
final Completer<T?> completer = Completer<T?>();

final int count = (_pushCounts[fullPath] ?? 0) + 1;
_pushCounts[fullPath] = count;
final ValueKey<String> pageKey = ValueKey<String>('$fullPath-p$count');
final RouteMatch newPageKeyMatch = RouteMatch(
completer: completer,
route: match.route,
subloc: match.subloc,
fullpath: match.fullpath,
Expand All @@ -112,6 +118,7 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList>

_matchList.push(newPageKeyMatch);
notifyListeners();
return completer.future;
}

/// Returns `true` if the active Navigator can pop.
Expand Down Expand Up @@ -140,8 +147,16 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList>
return navigatorKey.currentState?.canPop() ?? false;
}

/// Pop the top page off the GoRouter's page stack.
void pop() {
/// Pop the top page off the GoRouter's page stack and complete a promise if
/// there is one.
void pop<T extends Object?>([T? value]) {
johnpryan marked this conversation as resolved.
Show resolved Hide resolved
final RouteMatch last = _matchList.last;

// If there is a promise for this page, complete it.
if (last.completer != null) {
last.completer?.complete(value);
}

_matchList.pop();
notifyListeners();
}
Expand All @@ -150,9 +165,11 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList>
///
/// See also:
/// * [push] which pushes the given location onto the page stack.
void replace(RouteMatch match) {
Future<T?>? replace<T extends Object?>(RouteMatch match) {
_matchList.matches.last = match;

notifyListeners();
return match.completer?.future as Future<T?>?;
}

/// For internal use; visible for testing only.
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/lib/src/information_provider.dart
Expand Up @@ -7,7 +7,7 @@ import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'parser.dart';

/// The [RouteInformationProvider] created by go_router.
/// The [RouteInformationProvider] created by go_router_flow.
class GoRouteInformationProvider extends RouteInformationProvider
with WidgetsBindingObserver, ChangeNotifier {
/// Creates a [GoRouteInformationProvider].
Expand Down