Navigation now flows entirely through go_router

This commit is contained in:
Arseni
2025-12-08 17:40:25 +03:00
parent f478219990
commit 64ad8c8b38
21 changed files with 705 additions and 550 deletions

View File

@@ -1,6 +1,8 @@
import 'package:flutter/widgets.dart';
import 'package:collection/collection.dart';
import 'package:go_router/go_router.dart';
import 'package:pshared/models/payment/type.dart';
import 'package:pweb/widgets/sidebar/destinations.dart';
@@ -17,6 +19,9 @@ class PayoutRoutes {
static const editWallet = 'payout-edit-wallet';
static const walletTopUp = 'payout-wallet-top-up';
static const paymentTypeQuery = 'paymentType';
static const returnToQuery = 'returnTo';
static const dashboardPath = '/dashboard';
static const recipientsPath = '/dashboard/recipients';
static const addRecipientPath = '/dashboard/recipients/add';
@@ -103,10 +108,70 @@ class PayoutRoutes {
return null;
}
}
static Map<String, String> buildQueryParameters({
PaymentType? paymentType,
PayoutDestination? returnTo,
}) {
final params = <String, String>{
if (paymentType != null) paymentTypeQuery: paymentType.name,
if (returnTo != null) returnToQuery: nameFor(returnTo),
};
return params;
}
static PaymentType? paymentTypeFromState(GoRouterState state) =>
paymentTypeFromRaw(state.uri.queryParameters[paymentTypeQuery]);
static PaymentType? paymentTypeFromRaw(String? raw) => raw == null
? null
: PaymentType.values.firstWhereOrNull((type) => type.name == raw);
static PayoutDestination fallbackFromState(
GoRouterState state, {
PayoutDestination defaultDestination = PayoutDestination.dashboard,
}) {
final raw = state.uri.queryParameters[returnToQuery];
return destinationFor(raw) ?? defaultDestination;
}
}
extension PayoutNavigation on BuildContext {
void goToPayout(PayoutDestination destination) => goNamed(PayoutRoutes.nameFor(destination));
void pushToPayout(PayoutDestination destination) => pushNamed(PayoutRoutes.nameFor(destination));
}
void goToPayment({
PaymentType? paymentType,
PayoutDestination? returnTo,
}) =>
goNamed(
PayoutRoutes.payment,
queryParameters: PayoutRoutes.buildQueryParameters(
paymentType: paymentType,
returnTo: returnTo,
),
);
void pushToPayment({
PaymentType? paymentType,
PayoutDestination? returnTo,
}) =>
pushNamed(
PayoutRoutes.payment,
queryParameters: PayoutRoutes.buildQueryParameters(
paymentType: paymentType,
returnTo: returnTo,
),
);
void pushToWalletTopUp({PayoutDestination? returnTo}) => pushNamed(
PayoutRoutes.walletTopUp,
queryParameters: PayoutRoutes.buildQueryParameters(returnTo: returnTo),
);
void pushToEditWallet({PayoutDestination? returnTo}) => pushNamed(
PayoutRoutes.editWallet,
queryParameters: PayoutRoutes.buildQueryParameters(returnTo: returnTo),
);
}

View File

@@ -4,10 +4,13 @@ import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:pshared/models/payment/type.dart';
import 'package:pshared/models/recipient/recipient.dart';
import 'package:pshared/provider/recipient/provider.dart';
import 'package:pweb/app/router/pages.dart';
import 'package:pweb/app/router/payout_routes.dart';
import 'package:pweb/models/wallet.dart';
import 'package:pweb/pages/address_book/form/page.dart';
import 'package:pweb/pages/address_book/page/page.dart';
import 'package:pweb/pages/dashboard/dashboard.dart';
@@ -17,7 +20,7 @@ import 'package:pweb/pages/payout_page/wallet/edit/page.dart';
import 'package:pweb/pages/report/page.dart';
import 'package:pweb/pages/settings/profile/page.dart';
import 'package:pweb/pages/wallet_top_up/page.dart';
import 'package:pweb/providers/page_selector.dart';
import 'package:pweb/providers/wallets.dart';
import 'package:pweb/widgets/error/snackbar.dart';
import 'package:pweb/widgets/sidebar/destinations.dart';
import 'package:pweb/widgets/sidebar/page.dart';
@@ -36,15 +39,22 @@ RouteBase payoutShellRoute() => ShellRoute(
path: routerPage(Pages.dashboard),
pageBuilder: (context, _) => NoTransitionPage(
child: DashboardPage(
onRecipientSelected: (recipient) => context
.read<PageSelectorProvider>()
.selectRecipient(context, recipient),
onGoToPaymentWithoutRecipient: (type) => context
.read<PageSelectorProvider>()
.startPaymentWithoutRecipient(context, type),
onTopUp: (wallet) => context
.read<PageSelectorProvider>()
.openWalletTopUp(context, wallet),
onRecipientSelected: (recipient) => _startPayment(
context,
recipient: recipient,
returnTo: PayoutDestination.dashboard,
),
onGoToPaymentWithoutRecipient: (type) => _startPayment(
context,
recipient: null,
paymentType: type,
returnTo: PayoutDestination.dashboard,
),
onTopUp: (wallet) => _openWalletTopUp(
context,
wallet,
returnTo: PayoutDestination.dashboard,
),
),
),
),
@@ -55,15 +65,16 @@ RouteBase payoutShellRoute() => ShellRoute(
final loc = AppLocalizations.of(context)!;
return NoTransitionPage(
child: RecipientAddressBookPage(
onRecipientSelected: (recipient) => context
.read<PageSelectorProvider>()
.selectRecipient(context, recipient, fromList: true),
onAddRecipient: () => context
.read<PageSelectorProvider>()
.goToAddRecipient(context),
onEditRecipient: (recipient) => context
.read<PageSelectorProvider>()
.editRecipient(context, recipient, fromList: true),
onRecipientSelected: (recipient) => _startPayment(
context,
recipient: recipient,
returnTo: PayoutDestination.recipients,
),
onAddRecipient: () => _openAddRecipient(context),
onEditRecipient: (recipient) => _openAddRecipient(
context,
recipient: recipient,
),
onDeleteRecipient: (recipient) => executeActionWithNotification(
context: context,
action: () async =>
@@ -79,15 +90,11 @@ RouteBase payoutShellRoute() => ShellRoute(
name: PayoutRoutes.addRecipient,
path: PayoutRoutes.addRecipientPath,
pageBuilder: (context, _) {
final selector = context.read<PageSelectorProvider>();
final recipient = selector.recipientProvider.currentObject;
final recipient = context.read<RecipientsProvider>().currentObject;
return NoTransitionPage(
child: AdressBookRecipientForm(
recipient: recipient,
onSaved: (_) => selector.selectPage(
context,
PayoutDestination.recipients,
),
onSaved: (_) => context.goToPayout(PayoutDestination.recipients),
),
);
},
@@ -95,13 +102,20 @@ RouteBase payoutShellRoute() => ShellRoute(
GoRoute(
name: PayoutRoutes.payment,
path: PayoutRoutes.paymentPath,
pageBuilder: (context, _) => NoTransitionPage(
child: PaymentPage(
onBack: (_) => context
.read<PageSelectorProvider>()
.goBackFromPayment(context),
),
),
pageBuilder: (context, state) {
final fallbackDestination = PayoutRoutes.fallbackFromState(
state,
defaultDestination: PayoutDestination.dashboard,
);
return NoTransitionPage(
child: PaymentPage(
onBack: (_) => _popOrGo(context, fallbackDestination),
initialPaymentType: PayoutRoutes.paymentTypeFromState(state),
fallbackDestination: fallbackDestination,
),
);
},
),
GoRoute(
name: PayoutRoutes.settings,
@@ -122,24 +136,30 @@ RouteBase payoutShellRoute() => ShellRoute(
path: PayoutRoutes.methodsPath,
pageBuilder: (context, _) => NoTransitionPage(
child: PaymentConfigPage(
onWalletTap: (wallet) => context
.read<PageSelectorProvider>()
.selectWallet(context, wallet),
onWalletTap: (wallet) => _openWalletEdit(
context,
wallet,
returnTo: PayoutDestination.methods,
),
),
),
),
GoRoute(
name: PayoutRoutes.editWallet,
path: PayoutRoutes.editWalletPath,
pageBuilder: (context, _) {
final provider = context.read<PageSelectorProvider>();
final wallet = provider.walletsProvider.selectedWallet;
pageBuilder: (context, state) {
final walletsProvider = context.read<WalletsProvider>();
final wallet = walletsProvider.selectedWallet;
final loc = AppLocalizations.of(context)!;
final fallbackDestination = PayoutRoutes.fallbackFromState(
state,
defaultDestination: PayoutDestination.methods,
);
return NoTransitionPage(
child: wallet != null
? WalletEditPage(
onBack: () => provider.goBackFromWalletEdit(context),
onBack: () => _popOrGo(context, fallbackDestination),
)
: Center(child: Text(loc.noWalletSelected)),
);
@@ -148,13 +168,65 @@ RouteBase payoutShellRoute() => ShellRoute(
GoRoute(
name: PayoutRoutes.walletTopUp,
path: PayoutRoutes.walletTopUpPath,
pageBuilder: (context, _) => NoTransitionPage(
child: WalletTopUpPage(
onBack: () => context
.read<PageSelectorProvider>()
.goBackFromWalletTopUp(context),
),
),
pageBuilder: (context, state) {
final fallbackDestination = PayoutRoutes.fallbackFromState(
state,
defaultDestination: PayoutDestination.dashboard,
);
return NoTransitionPage(
child: WalletTopUpPage(
onBack: () => _popOrGo(context, fallbackDestination),
),
);
},
),
],
);
void _startPayment(
BuildContext context, {
Recipient? recipient,
PaymentType? paymentType,
required PayoutDestination returnTo,
}) {
context.read<RecipientsProvider>().setCurrentObject(recipient?.id);
context.pushToPayment(
paymentType: paymentType,
returnTo: returnTo,
);
}
void _openAddRecipient(
BuildContext context, {
Recipient? recipient,
}) {
context.read<RecipientsProvider>().setCurrentObject(recipient?.id);
context.pushNamed(PayoutRoutes.addRecipient);
}
void _openWalletEdit(
BuildContext context,
Wallet wallet, {
required PayoutDestination returnTo,
}) {
context.read<WalletsProvider>().selectWallet(wallet);
context.pushToEditWallet(returnTo: returnTo);
}
void _openWalletTopUp(
BuildContext context,
Wallet wallet, {
required PayoutDestination returnTo,
}) {
context.read<WalletsProvider>().selectWallet(wallet);
context.pushToWalletTopUp(returnTo: returnTo);
}
void _popOrGo(BuildContext context, PayoutDestination destination) {
if (Navigator.of(context).canPop()) {
Navigator.of(context).pop();
} else {
context.goToPayout(destination);
}
}