165 lines
5.4 KiB
Dart
165 lines
5.4 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:flutter/widgets.dart';
|
|
|
|
import 'package:go_router/go_router.dart';
|
|
|
|
import 'package:sxchnge_wallet/sxchnge_wallet.dart';
|
|
|
|
import '../auth/page.dart';
|
|
import '../kyc/page.dart';
|
|
import '../security/challenge.dart';
|
|
import '../verification/page.dart';
|
|
import '../workspace/accounts.dart';
|
|
import '../workspace/activity.dart';
|
|
import '../workspace/limits.dart';
|
|
import '../workspace/operation.dart';
|
|
import '../workspace/settings.dart';
|
|
import '../workspace/shell.dart';
|
|
import '../workspace/transfer.dart';
|
|
import 'routes.dart';
|
|
|
|
GoRouter createAppRouter({bool Function()? authenticated}) {
|
|
final topUpKey = GlobalKey<TransferPageState>();
|
|
final exchangeKey = GlobalKey<TransferPageState>();
|
|
final payoutKey = GlobalKey<TransferPageState>();
|
|
final identityKey = GlobalKey<IdentityPageState>();
|
|
return GoRouter(
|
|
redirect: (context, state) {
|
|
if (authenticated == null || authenticated()) return null;
|
|
final path = state.uri.path;
|
|
if (path == '/' ||
|
|
path == '/verify-email' ||
|
|
path == '/verification-sent' ||
|
|
path == '/two-factor') {
|
|
return null;
|
|
}
|
|
return '/';
|
|
},
|
|
// Signup email is an in-memory navigation extra, never browser-history data.
|
|
extraCodec: const _TransientExtras(),
|
|
routes: [
|
|
GoRoute(
|
|
path: '/two-factor',
|
|
redirect: (context, state) =>
|
|
state.extra is FactorRouteRequest ? null : '/',
|
|
builder: (context, state) =>
|
|
FactorRoute(request: state.extra as FactorRouteRequest),
|
|
onExit: (context, state) =>
|
|
state.extra is! FactorRouteRequest ||
|
|
!(state.extra as FactorRouteRequest).provider.busy,
|
|
),
|
|
ShellRoute(
|
|
builder: (context, state, child) =>
|
|
WorkspaceShell(path: state.uri.path, child: child),
|
|
routes: [
|
|
GoRoute(
|
|
path: '/accounts',
|
|
builder: (context, state) => const AccountsPage(),
|
|
routes: [
|
|
GoRoute(
|
|
path: ':accountId',
|
|
builder: (context, state) =>
|
|
AccountsPage(accountId: state.pathParameters['accountId']),
|
|
),
|
|
],
|
|
),
|
|
GoRoute(
|
|
path: '/activity',
|
|
builder: (context, state) => const ActivityPage(),
|
|
routes: [
|
|
GoRoute(
|
|
path: ':operationId',
|
|
builder: (context, state) =>
|
|
OperationPage(id: state.pathParameters['operationId']!),
|
|
),
|
|
],
|
|
),
|
|
GoRoute(
|
|
path: '/limits',
|
|
builder: (context, state) => const LimitsPage(),
|
|
),
|
|
GoRoute(
|
|
path: '/settings',
|
|
builder: (context, state) => const SettingsPage(),
|
|
),
|
|
GoRoute(
|
|
path: '/top-up',
|
|
builder: (context, state) => TransferPage(
|
|
key: topUpKey,
|
|
kind: TransferKind.topUp,
|
|
source: state.extra is String ? state.extra as String : null,
|
|
),
|
|
onExit: (context, state) async =>
|
|
await topUpKey.currentState?.allowExit() ?? true,
|
|
),
|
|
GoRoute(
|
|
path: '/exchange',
|
|
builder: (context, state) => TransferPage(
|
|
key: exchangeKey,
|
|
kind: TransferKind.exchange,
|
|
source: state.extra is String ? state.extra as String : null,
|
|
),
|
|
onExit: (context, state) async =>
|
|
await exchangeKey.currentState?.allowExit() ?? true,
|
|
),
|
|
GoRoute(
|
|
path: '/payout',
|
|
builder: (context, state) => TransferPage(
|
|
key: payoutKey,
|
|
kind: TransferKind.payout,
|
|
source: state.extra is String ? state.extra as String : null,
|
|
),
|
|
onExit: (context, state) async =>
|
|
await payoutKey.currentState?.allowExit() ?? true,
|
|
),
|
|
GoRoute(
|
|
path: '/identity',
|
|
name: AppRoutes.identity,
|
|
builder: (context, state) => IdentityPage(
|
|
key: identityKey,
|
|
onboarding: state.uri.queryParameters['onboarding'] == '1',
|
|
),
|
|
onExit: (context, state) async =>
|
|
await identityKey.currentState?.allowExit() ?? true,
|
|
),
|
|
],
|
|
),
|
|
GoRoute(
|
|
path: '/',
|
|
name: AppRoutes.login,
|
|
builder: (context, state) => const AuthPage(),
|
|
),
|
|
GoRoute(
|
|
path: '/verification-sent',
|
|
name: AppRoutes.verificationSent,
|
|
builder: (context, state) => VerificationPage(
|
|
email: state.extra is String ? state.extra as String : null,
|
|
),
|
|
),
|
|
GoRoute(
|
|
path: '/verify-email',
|
|
name: AppRoutes.verifyEmail,
|
|
builder: (context, state) =>
|
|
VerificationPage(token: state.uri.queryParameters['token'] ?? ''),
|
|
),
|
|
],
|
|
// Preserve the existing fallback, and keep the visible URL canonical.
|
|
onException: (context, state, router) => router.goNamed(AppRoutes.login),
|
|
);
|
|
}
|
|
|
|
class _TransientExtras extends Codec<Object?, Object?> {
|
|
const _TransientExtras();
|
|
@override
|
|
Converter<Object?, Object?> get encoder => const _DiscardExtra();
|
|
@override
|
|
Converter<Object?, Object?> get decoder => const _DiscardExtra();
|
|
}
|
|
|
|
class _DiscardExtra extends Converter<Object?, Object?> {
|
|
const _DiscardExtra();
|
|
@override
|
|
Object? convert(Object? input) => null;
|
|
}
|