mirror of
https://github.com/Xevion/paperless-mobile.git
synced 2025-12-10 02:07:57 -06:00
feat: bugfixes, finished go_router migration, implemented better visibility of states
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
final rootNavigatorKey = GlobalKey<NavigatorState>();
|
||||
final outerShellNavigatorKey = GlobalKey<NavigatorState>();
|
||||
final landingNavigatorKey = GlobalKey<NavigatorState>();
|
||||
final documentsNavigatorKey = GlobalKey<NavigatorState>();
|
||||
final scannerNavigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
@@ -2,9 +2,10 @@ class R {
|
||||
const R._();
|
||||
static const landing = "landing";
|
||||
static const login = "login";
|
||||
static const loginToExistingAccount = 'loginToExistingAccount';
|
||||
static const documents = "documents";
|
||||
static const verifyIdentity = "verifyIdentity";
|
||||
static const switchingAccounts = "switchingAccounts";
|
||||
static const switchingAccount = "switchingAccount";
|
||||
static const savedView = "savedView";
|
||||
static const createSavedView = "createSavedView";
|
||||
static const editSavedView = "editSavedView";
|
||||
@@ -21,6 +22,8 @@ class R {
|
||||
static const linkedDocuments = "linkedDocuments";
|
||||
static const bulkEditDocuments = "bulkEditDocuments";
|
||||
static const uploadQueue = "uploadQueue";
|
||||
static const checkingLogin = "checkingLogin";
|
||||
static const authenticating = "authenticating";
|
||||
static const loggingOut = "loggingOut";
|
||||
static const restoringSession = "restoringSession";
|
||||
static const addAccount = 'addAccount';
|
||||
}
|
||||
|
||||
@@ -54,7 +54,8 @@ class DocumentsRoute extends GoRouteData {
|
||||
}
|
||||
|
||||
class DocumentDetailsRoute extends GoRouteData {
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey =
|
||||
outerShellNavigatorKey;
|
||||
|
||||
final bool isLabelClickable;
|
||||
final DocumentModel $extra;
|
||||
@@ -86,7 +87,8 @@ class DocumentDetailsRoute extends GoRouteData {
|
||||
}
|
||||
|
||||
class EditDocumentRoute extends GoRouteData {
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey =
|
||||
outerShellNavigatorKey;
|
||||
|
||||
final DocumentModel $extra;
|
||||
|
||||
@@ -114,7 +116,8 @@ class EditDocumentRoute extends GoRouteData {
|
||||
}
|
||||
|
||||
class DocumentPreviewRoute extends GoRouteData {
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey =
|
||||
outerShellNavigatorKey;
|
||||
|
||||
final DocumentModel $extra;
|
||||
final String? title;
|
||||
|
||||
@@ -49,7 +49,8 @@ class LabelsRoute extends GoRouteData {
|
||||
}
|
||||
|
||||
class EditLabelRoute extends GoRouteData {
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey =
|
||||
outerShellNavigatorKey;
|
||||
|
||||
final Label $extra;
|
||||
|
||||
@@ -67,7 +68,8 @@ class EditLabelRoute extends GoRouteData {
|
||||
}
|
||||
|
||||
class CreateLabelRoute extends GoRouteData {
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey =
|
||||
outerShellNavigatorKey;
|
||||
final LabelType $extra;
|
||||
final String? name;
|
||||
|
||||
@@ -88,7 +90,8 @@ class CreateLabelRoute extends GoRouteData {
|
||||
}
|
||||
|
||||
class LinkedDocumentsRoute extends GoRouteData {
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey =
|
||||
outerShellNavigatorKey;
|
||||
final DocumentFilter $extra;
|
||||
|
||||
const LinkedDocumentsRoute(this.$extra);
|
||||
|
||||
@@ -52,7 +52,8 @@ class ScannerRoute extends GoRouteData {
|
||||
}
|
||||
|
||||
class DocumentUploadRoute extends GoRouteData {
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey =
|
||||
outerShellNavigatorKey;
|
||||
final FutureOr<Uint8List> $extra;
|
||||
final String? title;
|
||||
final String? filename;
|
||||
@@ -72,6 +73,7 @@ class DocumentUploadRoute extends GoRouteData {
|
||||
context.read(),
|
||||
context.read(),
|
||||
context.read(),
|
||||
context.read(),
|
||||
),
|
||||
child: DocumentUploadPreparationPage(
|
||||
title: title,
|
||||
|
||||
@@ -11,7 +11,8 @@ part 'upload_queue_route.g.dart';
|
||||
name: R.uploadQueue,
|
||||
)
|
||||
class UploadQueueRoute extends GoRouteData {
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey =
|
||||
outerShellNavigatorKey;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, GoRouterState state) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
|
||||
import 'package:paperless_mobile/core/factory/paperless_api_factory.dart';
|
||||
import 'package:paperless_mobile/features/home/view/home_shell_widget.dart';
|
||||
import 'package:paperless_mobile/features/sharing/cubit/receive_share_cubit.dart';
|
||||
import 'package:paperless_mobile/features/sharing/view/widgets/upload_queue_shell.dart';
|
||||
import 'package:paperless_mobile/features/sharing/view/widgets/event_listener_shell.dart';
|
||||
import 'package:paperless_mobile/routes/navigation_keys.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
@@ -50,7 +50,7 @@ import 'package:provider/provider.dart';
|
||||
// )
|
||||
class ProviderShellRoute extends ShellRouteData {
|
||||
final PaperlessApiFactory apiFactory;
|
||||
static final GlobalKey<NavigatorState> $navigatorKey = rootNavigatorKey;
|
||||
static final GlobalKey<NavigatorState> $navigatorKey = outerShellNavigatorKey;
|
||||
|
||||
const ProviderShellRoute(this.apiFactory);
|
||||
|
||||
@@ -77,7 +77,7 @@ class ProviderShellRoute extends ShellRouteData {
|
||||
child: ChangeNotifierProvider(
|
||||
create: (context) => ConsumptionChangeNotifier()
|
||||
..loadFromConsumptionDirectory(userId: currentUserId),
|
||||
child: UploadQueueShell(child: navigator),
|
||||
child: EventListenerShell(child: navigator),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
80
lib/routes/typed/top_level/add_account_route.dart
Normal file
80
lib/routes/typed/top_level/add_account_route.dart
Normal file
@@ -0,0 +1,80 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_mobile/core/model/info_message_exception.dart';
|
||||
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
||||
import 'package:paperless_mobile/features/login/model/login_form_credentials.dart';
|
||||
import 'package:paperless_mobile/features/login/view/add_account_page.dart';
|
||||
import 'package:paperless_mobile/features/settings/view/dialogs/switch_account_dialog.dart';
|
||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||
import 'package:paperless_mobile/helpers/message_helpers.dart';
|
||||
import 'package:paperless_mobile/routes/navigation_keys.dart';
|
||||
import 'package:paperless_mobile/routes/routes.dart';
|
||||
|
||||
part 'add_account_route.g.dart';
|
||||
|
||||
@TypedGoRoute<AddAccountRoute>(
|
||||
path: '/add-account',
|
||||
name: R.addAccount,
|
||||
)
|
||||
class AddAccountRoute extends GoRouteData {
|
||||
const AddAccountRoute();
|
||||
|
||||
static final $parentNavigatorKey = rootNavigatorKey;
|
||||
@override
|
||||
Widget build(BuildContext context, GoRouterState state) {
|
||||
return AddAccountPage(
|
||||
titleText: S.of(context)!.addAccount,
|
||||
onSubmit:
|
||||
(context, username, password, serverUrl, clientCertificate) async {
|
||||
try {
|
||||
final userId = await context.read<AuthenticationCubit>().addAccount(
|
||||
credentials: LoginFormCredentials(
|
||||
username: username,
|
||||
password: password,
|
||||
),
|
||||
clientCertificate: clientCertificate,
|
||||
serverUrl: serverUrl,
|
||||
enableBiometricAuthentication: false,
|
||||
locale: Localizations.localeOf(context).languageCode,
|
||||
);
|
||||
final shoudSwitch = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => const SwitchAccountDialog(),
|
||||
) ??
|
||||
false;
|
||||
if (shoudSwitch) {
|
||||
await context.read<AuthenticationCubit>().switchAccount(userId);
|
||||
} else {
|
||||
while (context.canPop()) {
|
||||
context.pop();
|
||||
}
|
||||
}
|
||||
} on PaperlessApiException catch (error, stackTrace) {
|
||||
showErrorMessage(context, error, stackTrace);
|
||||
// context.pop();
|
||||
} on PaperlessFormValidationException catch (exception, stackTrace) {
|
||||
if (exception.hasUnspecificErrorMessage()) {
|
||||
showLocalizedError(context, exception.unspecificErrorMessage()!);
|
||||
// context.pop();
|
||||
} else {
|
||||
showGenericError(
|
||||
context,
|
||||
exception.validationMessages.values.first,
|
||||
stackTrace,
|
||||
); //TODO: Check if we can show error message directly on field here.
|
||||
}
|
||||
} on InfoMessageException catch (error) {
|
||||
showInfoMessage(context, error);
|
||||
// context.pop();
|
||||
} catch (unknownError, stackTrace) {
|
||||
showGenericError(context, unknownError.toString(), stackTrace);
|
||||
// context.pop();
|
||||
}
|
||||
},
|
||||
submitText: S.of(context)!.addAccount,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:paperless_mobile/routes/routes.dart';
|
||||
|
||||
part 'checking_login_route.g.dart';
|
||||
|
||||
@TypedGoRoute<CheckingLoginRoute>(
|
||||
path: "/checking-login",
|
||||
name: R.checkingLogin,
|
||||
)
|
||||
class CheckingLoginRoute extends GoRouteData {
|
||||
const CheckingLoginRoute();
|
||||
@override
|
||||
Widget build(BuildContext context, GoRouterState state) {
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: Text("Logging in..."),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,12 @@ import 'package:paperless_mobile/routes/routes.dart';
|
||||
|
||||
part 'logging_out_route.g.dart';
|
||||
|
||||
@TypedGoRoute<LogginOutRoute>(
|
||||
@TypedGoRoute<LoggingOutRoute>(
|
||||
path: "/logging-out",
|
||||
name: R.loggingOut,
|
||||
)
|
||||
class LogginOutRoute extends GoRouteData {
|
||||
const LogginOutRoute();
|
||||
class LoggingOutRoute extends GoRouteData {
|
||||
const LoggingOutRoute();
|
||||
@override
|
||||
Widget build(BuildContext context, GoRouterState state) {
|
||||
return Scaffold(
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hive_flutter/adapters.dart';
|
||||
import 'package:paperless_mobile/core/config/hive/hive_extensions.dart';
|
||||
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
||||
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
||||
import 'package:paperless_mobile/features/login/view/login_page.dart';
|
||||
import 'package:paperless_mobile/features/login/view/login_to_existing_account_page.dart';
|
||||
import 'package:paperless_mobile/features/login/view/verify_identity_page.dart';
|
||||
import 'package:paperless_mobile/features/login/view/widgets/login_transition_page.dart';
|
||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||
import 'package:paperless_mobile/routes/navigation_keys.dart';
|
||||
import 'package:paperless_mobile/routes/routes.dart';
|
||||
|
||||
part 'login_route.g.dart';
|
||||
@@ -12,12 +20,51 @@ part 'login_route.g.dart';
|
||||
@TypedGoRoute<LoginRoute>(
|
||||
path: "/login",
|
||||
name: R.login,
|
||||
routes: [
|
||||
TypedGoRoute<SwitchingAccountsRoute>(
|
||||
path: "switching-account",
|
||||
name: R.switchingAccount,
|
||||
),
|
||||
TypedGoRoute<AuthenticatingRoute>(
|
||||
path: 'authenticating',
|
||||
name: R.authenticating,
|
||||
),
|
||||
TypedGoRoute<VerifyIdentityRoute>(
|
||||
path: 'verify-identity',
|
||||
name: R.verifyIdentity,
|
||||
),
|
||||
TypedGoRoute<LoginToExistingAccountRoute>(
|
||||
path: 'existing',
|
||||
name: R.loginToExistingAccount,
|
||||
),
|
||||
TypedGoRoute<RestoringSessionRoute>(
|
||||
path: 'restoring-session',
|
||||
name: R.restoringSession,
|
||||
),
|
||||
],
|
||||
)
|
||||
class LoginRoute extends GoRouteData {
|
||||
const LoginRoute();
|
||||
static final $parentNavigatorKey = rootNavigatorKey;
|
||||
final String? serverUrl;
|
||||
final String? username;
|
||||
final String? password;
|
||||
final ClientCertificate? $extra;
|
||||
|
||||
const LoginRoute({
|
||||
this.serverUrl,
|
||||
this.username,
|
||||
this.password,
|
||||
this.$extra,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, GoRouterState state) {
|
||||
return const LoginPage();
|
||||
return LoginPage(
|
||||
initialServerUrl: serverUrl,
|
||||
initialUsername: username,
|
||||
initialPassword: password,
|
||||
initialClientCertificate: $extra,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -28,3 +75,77 @@ class LoginRoute extends GoRouteData {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class SwitchingAccountsRoute extends GoRouteData {
|
||||
static final $parentNavigatorKey = rootNavigatorKey;
|
||||
|
||||
const SwitchingAccountsRoute();
|
||||
@override
|
||||
Widget build(BuildContext context, GoRouterState state) {
|
||||
return LoginTransitionPage(
|
||||
text: S.of(context)!.switchingAccountsPleaseWait,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AuthenticatingRoute extends GoRouteData {
|
||||
static final $parentNavigatorKey = rootNavigatorKey;
|
||||
|
||||
final String checkLoginStageName;
|
||||
const AuthenticatingRoute(this.checkLoginStageName);
|
||||
@override
|
||||
Widget build(BuildContext context, GoRouterState state) {
|
||||
final stage = AuthenticatingStage.values.byName(checkLoginStageName);
|
||||
final text = switch (stage) {
|
||||
AuthenticatingStage.authenticating => S.of(context)!.authenticatingDots,
|
||||
AuthenticatingStage.persistingLocalUserData =>
|
||||
S.of(context)!.persistingUserInformation,
|
||||
AuthenticatingStage.fetchingUserInformation =>
|
||||
S.of(context)!.fetchingUserInformation,
|
||||
};
|
||||
|
||||
return LoginTransitionPage(text: text);
|
||||
}
|
||||
}
|
||||
|
||||
class VerifyIdentityRoute extends GoRouteData {
|
||||
static final $parentNavigatorKey = rootNavigatorKey;
|
||||
|
||||
final String userId;
|
||||
const VerifyIdentityRoute({required this.userId});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, GoRouterState state) {
|
||||
return VerifyIdentityPage(userId: userId);
|
||||
}
|
||||
}
|
||||
|
||||
class LoginToExistingAccountRoute extends GoRouteData {
|
||||
static final $parentNavigatorKey = rootNavigatorKey;
|
||||
|
||||
const LoginToExistingAccountRoute();
|
||||
|
||||
@override
|
||||
FutureOr<String?> redirect(BuildContext context, GoRouterState state) {
|
||||
if (Hive.localUserAccountBox.isEmpty) {
|
||||
return "/login";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, GoRouterState state) {
|
||||
return const LoginToExistingAccountPage();
|
||||
}
|
||||
}
|
||||
|
||||
class RestoringSessionRoute extends GoRouteData {
|
||||
static final $parentNavigatorKey = rootNavigatorKey;
|
||||
|
||||
const RestoringSessionRoute();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, GoRouterState state) {
|
||||
return LoginTransitionPage(text: S.of(context)!.restoringSession);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ part 'settings_route.g.dart';
|
||||
name: R.settings,
|
||||
)
|
||||
class SettingsRoute extends GoRouteData {
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey = rootNavigatorKey;
|
||||
static final GlobalKey<NavigatorState> $parentNavigatorKey = outerShellNavigatorKey;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, GoRouterState state) {
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:paperless_mobile/features/settings/view/pages/switching_accounts_page.dart';
|
||||
import 'package:paperless_mobile/routes/routes.dart';
|
||||
|
||||
part 'switching_accounts_route.g.dart';
|
||||
|
||||
@TypedGoRoute<SwitchingAccountsRoute>(
|
||||
path: '/switching-accounts',
|
||||
name: R.switchingAccounts,
|
||||
)
|
||||
class SwitchingAccountsRoute extends GoRouteData {
|
||||
const SwitchingAccountsRoute();
|
||||
@override
|
||||
Widget build(BuildContext context, GoRouterState state) {
|
||||
return const SwitchingAccountsPage();
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:paperless_mobile/features/home/view/widget/verify_identity_page.dart';
|
||||
import 'package:paperless_mobile/routes/routes.dart';
|
||||
|
||||
part 'verify_identity_route.g.dart';
|
||||
|
||||
@TypedGoRoute<VerifyIdentityRoute>(
|
||||
path: '/verify-identity',
|
||||
name: R.verifyIdentity,
|
||||
)
|
||||
class VerifyIdentityRoute extends GoRouteData {
|
||||
const VerifyIdentityRoute();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, GoRouterState state) {
|
||||
return const VerifyIdentityPage();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user