Skip to content

Commit

Permalink
feat: support redirect by NavigatorPushBeginHandle & support popResul…
Browse files Browse the repository at this point in the history
…t by NavigatorPushEndHandle
  • Loading branch information
foxsofter committed Sep 5, 2024
1 parent 5da639f commit f063c3a
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 22 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 4.17.0

- feat: support redirect by NavigatorPushBeginHandle
- feat: support popResult by NavigatorPushEndHandle

## 4.16.3

- fix: try to fix NavigatorPageView RangeError
Expand Down
19 changes: 17 additions & 2 deletions lib/src/navigator/navigator_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

// ignore_for_file: avoid_positional_boolean_parameters

import 'dart:async';

import 'package:flutter/widgets.dart';

import 'navigator_route.dart';
Expand Down Expand Up @@ -65,10 +67,23 @@ typedef NavigatorRoutePushHandle = Future<NavigatorRoutePushHandleType>
bool animated,
});

/// Signature of push begin/return handler with url.
typedef NavigatorPushHandle = Future<void> Function<TParams>(
/// Signature of push begin handler with url.
///
/// return a new url for redirect.
///
typedef NavigatorPushBeginHandle = Future<String?> Function<TParams>(
String url, {
TParams? params,
String? fromURL,
String? innerURL,
});

/// Signature of push end handler.
///
typedef NavigatorPushEndHandle = Future<void> Function<TParams, TPopParams>(
String url, {
TParams? params,
String? fromURL,
String? innerURL,
TPopParams? popResult,
});
7 changes: 4 additions & 3 deletions lib/src/navigator/thrio_navigator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ import 'thrio_navigator_implement.dart';
abstract class ThrioNavigator {
/// Register a handle called before push.
///
static VoidCallback registerPushBeginHandle(NavigatorPushHandle handle) =>
static VoidCallback registerPushBeginHandle(
NavigatorPushBeginHandle handle) =>
ThrioNavigatorImplement.shared().registerPushBeginHandle(handle);

/// Register a handle called before the push return.
///
static VoidCallback registerPushReturnHandle(NavigatorPushHandle handle) =>
ThrioNavigatorImplement.shared().registerPushReturnHandle(handle);
static VoidCallback registerPushEndHandle(NavigatorPushEndHandle handle) =>
ThrioNavigatorImplement.shared().registerPushEndHandle(handle);

/// Push the page onto the navigation stack.
///
Expand Down
46 changes: 31 additions & 15 deletions lib/src/navigator/thrio_navigator_implement.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import '../extension/thrio_uri_string.dart';
import '../module/module_anchor.dart';
import '../module/module_types.dart';
import '../module/thrio_module.dart';
import '../registry/registry_set.dart';
import '../registry/registry_order_set.dart';
import 'navigator_dialog_route.dart';
import 'navigator_material_app.dart';
import 'navigator_observer_manager.dart';
Expand Down Expand Up @@ -111,9 +111,9 @@ class ThrioNavigatorImplement {

NavigatorWidgetState? get navigatorState => _stateKey.currentState;

final _pushBeginHandlers = RegistrySet<NavigatorPushHandle>();
final _pushBeginHandlers = RegistryOrderSet<NavigatorPushBeginHandle>();

final _pushReturnHandlers = RegistrySet<NavigatorPushHandle>();
final _pushEndHandlers = RegistryOrderSet<NavigatorPushEndHandle>();

final poppedResults = <String, NavigatorParamsCallback>{};

Expand Down Expand Up @@ -146,11 +146,11 @@ class ThrioNavigatorImplement {
_channel.invokeMethod<bool>('ready');
}

VoidCallback registerPushBeginHandle(NavigatorPushHandle handle) =>
VoidCallback registerPushBeginHandle(NavigatorPushBeginHandle handle) =>
_pushBeginHandlers.registry(handle);

VoidCallback registerPushReturnHandle(NavigatorPushHandle handle) =>
_pushReturnHandlers.registry(handle);
VoidCallback registerPushEndHandle(NavigatorPushEndHandle handle) =>
_pushEndHandlers.registry(handle);

Future<TPopParams?> push<TParams, TPopParams>({
required String url,
Expand All @@ -160,7 +160,7 @@ class ThrioNavigatorImplement {
String? fromURL,
String? innerURL,
}) async {
await _onPushBeginHandle(
final newURL = await _onPushBeginHandle(
url: url,
params: params,
fromURL: fromURL,
Expand All @@ -170,7 +170,7 @@ class ThrioNavigatorImplement {
final completer = Completer<TPopParams?>();

final handled = await _pushToHandler(
url: url,
url: newURL,
params: params,
animated: animated,
completer: completer,
Expand All @@ -182,7 +182,7 @@ class ThrioNavigatorImplement {
Future<void> pushFuture() {
final resultCompleter = Completer();
_pushToNative<TParams, TPopParams>(
url: url,
url: newURL,
params: params,
animated: animated,
completer: completer,
Expand All @@ -201,25 +201,40 @@ class ThrioNavigatorImplement {
return completer.future;
}

Future<void> _onPushBeginHandle<TParams>({
Future<String> _onPushBeginHandle<TParams>({
required String url,
TParams? params,
String? fromURL,
String? innerURL,
}) async {
for (final handle in _pushBeginHandlers) {
await handle(url, params: params, fromURL: fromURL, innerURL: innerURL);
final reversed = _pushBeginHandlers.reversed;
var newURL = url;
for (final handle in reversed) {
final ret = await handle(url,
params: params, fromURL: fromURL, innerURL: innerURL);
if (ret != null) {
newURL = ret;
}
}
return newURL;
}

Future<void> _onPushReturnHandle<TParams>({
Future<void> _onPushReturnHandle<TParams, TPopParams>({
required String url,
TParams? params,
String? fromURL,
String? innerURL,
TPopParams? popResult,
}) async {
for (final handle in _pushReturnHandlers) {
await handle(url, params: params, fromURL: fromURL, innerURL: innerURL);
final reversed = _pushEndHandlers.reversed;
for (final handle in reversed) {
await handle(
url,
params: params,
fromURL: fromURL,
innerURL: innerURL,
popResult: popResult,
);
}
}

Expand Down Expand Up @@ -719,6 +734,7 @@ class ThrioNavigatorImplement {
params: params,
fromURL: fromURL,
innerURL: innerURL,
popResult: value,
);
}));

Expand Down
53 changes: 53 additions & 0 deletions lib/src/registry/registry_order_set.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// The MIT License (MIT)
//
// Copyright (c) 2024 foxsofter
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

import 'dart:collection';
import 'package:flutter/foundation.dart';

class RegistryOrderSet<T> with IterableMixin<T> {
final List<T> _sets = [];

VoidCallback registry(T value) {
assert(value != null, 'value must not be null.');
_sets
..remove(value)
..add(value);
return () {
_sets.remove(value);
};
}

VoidCallback registryAll(Set<T> values) {
assert(values.isNotEmpty, 'values must not be null or empty');
values.forEach(_sets.remove);
_sets.addAll(values);
return () {
values.forEach(_sets.remove);
};
}

void clear() => _sets.clear();

@override
Iterator<T> get iterator => _sets.iterator;

Iterable<T> get reversed => _sets.reversed;
}
1 change: 0 additions & 1 deletion lib/src/registry/registry_set.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import 'dart:collection';
import 'package:flutter/foundation.dart';

// ignore: prefer_mixin
class RegistrySet<T> with IterableMixin<T> {
final Set<T> _sets = {};

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: flutter_thrio
description: Thrio makes it easy and fast to add flutter to existing mobile applications, and provide a simple and consistent navigator APIs.
version: 4.16.3
version: 4.17.0
homepage: https://github.com/flutter-thrio/flutter_thrio

environment:
Expand Down

0 comments on commit f063c3a

Please sign in to comment.