chore: Update go_router configuration to use go_router_builder

This commit is contained in:
Anton Stubenbord
2023-10-08 16:42:42 +02:00
parent a17b041a0d
commit d4951e1c82
44 changed files with 388 additions and 437 deletions

View File

@@ -12,6 +12,7 @@ import 'package:paperless_mobile/features/sharing/cubit/receive_share_cubit.dart
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
import 'package:paperless_mobile/routes/typed/branches/upload_queue_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
import 'package:paperless_mobile/routes/typed/top_level/settings_route.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher_string.dart';

View File

@@ -218,7 +218,7 @@ class DocumentDetailsCubit extends Cubit<DocumentDetailsState> {
throw Exception("An error occurred while downloading the document.");
}
Printing.layoutPdf(
name: state.document.title,
name: state.document.title ?? 'Document',
onLayout: (format) => file.readAsBytesSync(),
);
}

View File

@@ -23,6 +23,7 @@ import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/helpers/connectivity_aware_action_wrapper.dart';
import 'package:paperless_mobile/helpers/message_helpers.dart';
import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
class DocumentDetailsPage extends StatefulWidget {
final bool isLabelClickable;
@@ -48,6 +49,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
final hasMultiUserSupport =
context.watch<LocalUserAccount>().hasMultiUserSupport;
final tabLength = 4 + (hasMultiUserSupport && false ? 1 : 0);
final title = context.watch<DocumentDetailsCubit>().state.document.title;
return WillPopScope(
onWillPop: () async {
Navigator.of(context)
@@ -74,11 +76,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
handle:
NestedScrollView.sliverOverlapAbsorberHandleFor(context),
sliver: SliverAppBar(
title: Text(context
.watch<DocumentDetailsCubit>()
.state
.document
.title),
title: title != null ? Text(title) : null,
leading: const BackButton(),
pinned: true,
forceElevated: innerBoxIsScrolled,
@@ -103,6 +101,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
enableHero: false,
document: state.document,
fit: BoxFit.cover,
alignment: Alignment.topCenter,
),
),
Positioned.fill(
@@ -221,10 +220,6 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
document: state.document,
itemSpacing: _itemSpacing,
queryString: widget.titleAndContentQueryString,
availableCorrespondents: state.correspondents,
availableDocumentTypes: state.documentTypes,
availableTags: state.tags,
availableStoragePaths: state.storagePaths,
),
],
),

View File

@@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
import 'package:paperless_mobile/core/repository/label_repository.dart';
import 'package:paperless_mobile/core/widgets/highlighted_text.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/document_details/view/widgets/details_item.dart';
@@ -12,81 +13,68 @@ import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
class DocumentOverviewWidget extends StatelessWidget {
final DocumentModel document;
final Map<int, Correspondent> availableCorrespondents;
final Map<int, DocumentType> availableDocumentTypes;
final Map<int, Tag> availableTags;
final Map<int, StoragePath> availableStoragePaths;
final String? queryString;
final double itemSpacing;
const DocumentOverviewWidget({
super.key,
required this.document,
this.queryString,
required this.itemSpacing,
required this.availableCorrespondents,
required this.availableDocumentTypes,
required this.availableTags,
required this.availableStoragePaths,
});
@override
Widget build(BuildContext context) {
final user = context.watch<LocalUserAccount>().paperlessUser;
final availableLabels = context.watch<LabelRepository>().state;
return SliverList.list(
children: [
DetailsItem(
label: S.of(context)!.title,
content: HighlightedText(
text: document.title,
highlights: queryString?.split(" ") ?? [],
style: Theme.of(context).textTheme.bodyLarge,
),
).paddedOnly(bottom: itemSpacing),
if (document.title != null)
DetailsItem(
label: S.of(context)!.title,
content: HighlightedText(
text: document.title!,
highlights: queryString?.split(" ") ?? [],
style: Theme.of(context).textTheme.bodyLarge,
),
).paddedOnly(bottom: itemSpacing),
DetailsItem.text(
DateFormat.yMMMMd().format(document.created),
context: context,
label: S.of(context)!.createdAt,
).paddedOnly(bottom: itemSpacing),
if (document.documentType != null &&
context
.watch<LocalUserAccount>()
.paperlessUser
.canViewDocumentTypes)
if (document.documentType != null && user.canViewDocumentTypes)
DetailsItem(
label: S.of(context)!.documentType,
content: LabelText<DocumentType>(
style: Theme.of(context).textTheme.bodyLarge,
label: availableDocumentTypes[document.documentType],
label: availableLabels.documentTypes[document.documentType],
),
).paddedOnly(bottom: itemSpacing),
if (document.correspondent != null &&
context
.watch<LocalUserAccount>()
.paperlessUser
.canViewCorrespondents)
if (document.correspondent != null && user.canViewCorrespondents)
DetailsItem(
label: S.of(context)!.correspondent,
content: LabelText<Correspondent>(
style: Theme.of(context).textTheme.bodyLarge,
label: availableCorrespondents[document.correspondent],
label: availableLabels.correspondents[document.correspondent],
),
).paddedOnly(bottom: itemSpacing),
if (document.storagePath != null &&
context.watch<LocalUserAccount>().paperlessUser.canViewStoragePaths)
if (document.storagePath != null && user.canViewStoragePaths)
DetailsItem(
label: S.of(context)!.storagePath,
content: LabelText<StoragePath>(
label: availableStoragePaths[document.storagePath],
label: availableLabels.storagePaths[document.storagePath],
),
).paddedOnly(bottom: itemSpacing),
if (document.tags.isNotEmpty &&
context.watch<LocalUserAccount>().paperlessUser.canViewTags)
if (document.tags.isNotEmpty && user.canViewTags)
DetailsItem(
label: S.of(context)!.tags,
content: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: TagsWidget(
isClickable: false,
tags: document.tags.map((e) => availableTags[e]!).toList(),
tags:
document.tags.map((e) => availableLabels.tags[e]!).toList(),
),
),
).paddedOnly(bottom: itemSpacing),

View File

@@ -26,6 +26,7 @@ import 'package:paperless_mobile/helpers/connectivity_aware_action_wrapper.dart'
import 'package:paperless_mobile/helpers/message_helpers.dart';
import 'package:paperless_mobile/helpers/permission_helpers.dart';
import 'package:paperless_mobile/routes/typed/branches/scanner_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
import 'package:path/path.dart' as p;
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;

View File

@@ -11,6 +11,7 @@ import 'package:paperless_mobile/features/documents/view/widgets/adaptive_docume
import 'package:paperless_mobile/features/documents/view/widgets/selection/view_type_selection_widget.dart';
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
class DocumentSearchPage extends StatefulWidget {
const DocumentSearchPage({super.key});

View File

@@ -25,6 +25,7 @@ import 'package:paperless_mobile/features/tasks/model/pending_tasks_notifier.dar
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/helpers/message_helpers.dart';
import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
import 'package:sliver_tools/sliver_tools.dart';
class DocumentFilterIntent {
@@ -620,9 +621,9 @@ class _DocumentsPageState extends State<DocumentsPage> {
final cubit = context.read<DocumentsCubit>();
try {
switch (cubit.state.filter.storagePath){
case SetIdQueryParameter(id: var id):
if (id == pathId) {
switch (cubit.state.filter.storagePath) {
case SetIdQueryParameter(id: var id):
if (id == pathId) {
cubit.updateCurrentFilter(
(filter) =>
filter.copyWith(storagePath: const UnsetIdQueryParameter()),
@@ -634,14 +635,13 @@ class _DocumentsPageState extends State<DocumentsPage> {
);
}
break;
default:
cubit.updateCurrentFilter(
default:
cubit.updateCurrentFilter(
(filter) =>
filter.copyWith(storagePath: SetIdQueryParameter(id: pathId)),
filter.copyWith(storagePath: SetIdQueryParameter(id: pathId)),
);
break;
}
} on PaperlessApiException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace);
}

View File

@@ -20,7 +20,7 @@ class DeleteDocumentConfirmationDialog extends StatelessWidget {
),
const SizedBox(height: 16),
Text(
document.title,
document.title ?? document.originalFileName ?? '-',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(

View File

@@ -4,6 +4,7 @@ import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/helpers/connectivity_aware_action_wrapper.dart';
import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
import 'package:provider/provider.dart';
import 'package:shimmer/shimmer.dart';

View File

@@ -110,7 +110,7 @@ class DocumentDetailedItem extends DocumentItem {
],
).paddedLTRB(8, 8, 8, 4),
Text(
document.title,
document.title ?? '-',
style: Theme.of(context).textTheme.titleMedium,
maxLines: 2,
overflow: TextOverflow.ellipsis,

View File

@@ -113,7 +113,7 @@ class DocumentGridItem extends DocumentItem {
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(
document.title,
document.title ?? '-',
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.titleMedium,

View File

@@ -58,7 +58,7 @@ class DocumentListItem extends DocumentItem {
],
),
Text(
document.title,
document.title ?? '-',
overflow: TextOverflow.ellipsis,
maxLines: 1,
),

View File

@@ -44,7 +44,7 @@ class BulkDeleteConfirmationDialog extends StatelessWidget {
return ListTile(
dense: true,
title: Text(
doc.title,
doc.title ?? doc.originalFileName ?? '-',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(

View File

@@ -7,6 +7,7 @@ import 'package:paperless_mobile/features/documents/view/widgets/selection/bulk_
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/helpers/message_helpers.dart';
import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
class DocumentSelectionSliverAppBar extends StatelessWidget {
final DocumentsState state;

View File

@@ -16,6 +16,7 @@ import 'package:paperless_mobile/features/labels/view/widgets/label_text.dart';
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/helpers/connectivity_aware_action_wrapper.dart';
import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
class InboxItemPlaceholder extends StatelessWidget {
const InboxItemPlaceholder({super.key});
@@ -350,7 +351,7 @@ class _InboxItemState extends State<InboxItem> {
Text _buildTitle() {
return Text(
widget.document.title,
widget.document.title ?? '-',
overflow: TextOverflow.ellipsis,
maxLines: 2,
style: Theme.of(context).textTheme.titleSmall,

View File

@@ -15,6 +15,7 @@ import 'package:paperless_mobile/features/labels/view/widgets/label_tab_view.dar
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/helpers/connectivity_aware_action_wrapper.dart';
import 'package:paperless_mobile/routes/typed/branches/labels_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
class LabelsPage extends StatefulWidget {
const LabelsPage({Key? key}) : super(key: key);

View File

@@ -4,6 +4,7 @@ import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
import 'package:paperless_mobile/helpers/format_helpers.dart';
import 'package:paperless_mobile/routes/typed/branches/labels_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
class LabelItem<T extends Label> extends StatelessWidget {
final T label;

View File

@@ -12,6 +12,7 @@ import 'package:paperless_mobile/features/saved_view_details/view/saved_view_pre
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
import 'package:paperless_mobile/routes/typed/branches/inbox_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
class LandingPage extends StatefulWidget {
const LandingPage({super.key});

View File

@@ -7,6 +7,7 @@ import 'package:paperless_mobile/features/linked_documents/cubit/linked_document
import 'package:paperless_mobile/features/paged_document_view/view/document_paging_view_mixin.dart';
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
class LinkedDocumentsPage extends StatefulWidget {
const LinkedDocumentsPage({super.key});

View File

@@ -13,6 +13,7 @@ import 'package:paperless_mobile/features/login/model/login_form_credentials.dar
import 'package:paperless_mobile/features/login/view/add_account_page.dart';
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/helpers/message_helpers.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
import 'package:paperless_mobile/routes/typed/top_level/login_route.dart';
class LoginPage extends StatelessWidget {

View File

@@ -5,6 +5,7 @@ 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/users/view/widgets/user_account_list_tile.dart';
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
import 'package:paperless_mobile/routes/typed/top_level/login_route.dart';
class LoginToExistingAccountPage extends StatelessWidget {

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
import 'package:paperless_mobile/routes/typed/top_level/login_route.dart';
import 'package:provider/provider.dart';

View File

@@ -8,6 +8,7 @@ import 'package:paperless_mobile/features/landing/view/widgets/expansion_card.da
import 'package:paperless_mobile/features/saved_view_details/cubit/saved_view_preview_cubit.dart';
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
import 'package:provider/provider.dart';
class SavedViewPreview extends StatelessWidget {

View File

@@ -7,6 +7,7 @@ import 'package:paperless_mobile/features/settings/view/dialogs/switch_account_d
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
import 'package:paperless_mobile/features/users/view/widgets/user_account_list_tile.dart';
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
import 'package:paperless_mobile/routes/typed/top_level/add_account_route.dart';
import 'package:provider/provider.dart';
@@ -146,35 +147,7 @@ class ManageAccountsPage extends StatelessWidget {
Future<void> _onAddAccount(BuildContext context, String currentUser) async {
Navigator.of(context).pop();
AddAccountRoute().push<String>(context);
// final userId = await Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => 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,
// //TODO: Ask user whether to enable biometric authentication
// enableBiometricAuthentication: false,
// );
// Navigator.of(context).pop<String?>(userId);
// } on PaperlessFormValidationException catch (error) {}
// },
// submitText: S.of(context)!.addAccount,
// ),
// ),
// );
const AddAccountRoute().push<String>(context);
}
void _onSwitchAccount(

View File

@@ -23,6 +23,7 @@ import 'package:paperless_mobile/features/tasks/model/pending_tasks_notifier.dar
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/helpers/message_helpers.dart';
import 'package:paperless_mobile/routes/typed/branches/scanner_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
import 'package:path/path.dart' as p;
import 'package:receive_sharing_intent/receive_sharing_intent.dart';

View File

@@ -9,6 +9,7 @@ import 'package:paperless_mobile/features/similar_documents/cubit/similar_docume
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/helpers/message_helpers.dart';
import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
class SimilarDocumentsView extends StatefulWidget {
final ScrollController pagingScrollController;

View File

@@ -36,15 +36,8 @@ import 'package:paperless_mobile/features/notifications/services/local_notificat
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
import 'package:paperless_mobile/routes/navigation_keys.dart';
import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
import 'package:paperless_mobile/routes/typed/branches/inbox_route.dart';
import 'package:paperless_mobile/routes/typed/branches/labels_route.dart';
import 'package:paperless_mobile/routes/typed/branches/landing_route.dart';
import 'package:paperless_mobile/routes/typed/branches/saved_views_route.dart';
import 'package:paperless_mobile/routes/typed/branches/scanner_route.dart';
import 'package:paperless_mobile/routes/typed/branches/upload_queue_route.dart';
import 'package:paperless_mobile/routes/typed/shells/provider_shell_route.dart';
import 'package:paperless_mobile/routes/typed/shells/scaffold_shell_route.dart';
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
import 'package:paperless_mobile/routes/typed/top_level/add_account_route.dart';
import 'package:paperless_mobile/routes/typed/top_level/logging_out_route.dart';
import 'package:paperless_mobile/routes/typed/top_level/login_route.dart';
@@ -197,12 +190,14 @@ void main() async {
value: localNotificationService),
Provider.value(value: DocumentChangedNotifier()),
],
child: MultiBlocProvider(
child: MultiProvider(
providers: [
BlocProvider<ConnectivityCubit>.value(value: connectivityCubit),
BlocProvider.value(value: authenticationCubit),
Provider<ConnectivityCubit>.value(value: connectivityCubit),
Provider.value(value: authenticationCubit),
],
child: GoRouterShell(apiFactory: apiFactory),
child: GoRouterShell(
apiFactory: apiFactory,
),
),
),
);
@@ -221,10 +216,7 @@ void main() async {
class GoRouterShell extends StatefulWidget {
final PaperlessApiFactory apiFactory;
const GoRouterShell({
super.key,
required this.apiFactory,
});
const GoRouterShell({super.key, required this.apiFactory});
@override
State<GoRouterShell> createState() => _GoRouterShellState();
@@ -267,50 +259,53 @@ class _GoRouterShellState extends State<GoRouterShell> {
routes: [
ShellRoute(
builder: (context, state, child) {
return BlocListener<AuthenticationCubit, AuthenticationState>(
listener: (context, state) {
switch (state) {
case UnauthenticatedState(
redirectToAccountSelection: var shouldRedirect
):
if (shouldRedirect) {
const LoginToExistingAccountRoute().go(context);
} else {
const LoginRoute().go(context);
}
break;
case RestoringSessionState():
const RestoringSessionRoute().go(context);
break;
case VerifyIdentityState(userId: var userId):
VerifyIdentityRoute(userId: userId).go(context);
break;
case SwitchingAccountsState():
const SwitchingAccountsRoute().push(context);
break;
case AuthenticatedState():
const LandingRoute().go(context);
break;
case AuthenticatingState state:
AuthenticatingRoute(state.currentStage.name).push(context);
break;
case LoggingOutState():
const LoggingOutRoute().go(context);
break;
case AuthenticationErrorState():
if (context.canPop()) {
context.pop();
}
// LoginRoute(
// $extra: errorState.clientCertificate,
// password: errorState.password,
// serverUrl: errorState.serverUrl,
// username: errorState.username,
// ).go(context);
break;
}
},
child: child,
return Provider.value(
value: widget.apiFactory,
child: BlocListener<AuthenticationCubit, AuthenticationState>(
listener: (context, state) {
switch (state) {
case UnauthenticatedState(
redirectToAccountSelection: var shouldRedirect
):
if (shouldRedirect) {
const LoginToExistingAccountRoute().go(context);
} else {
const LoginRoute().go(context);
}
break;
case RestoringSessionState():
const RestoringSessionRoute().go(context);
break;
case VerifyIdentityState(userId: var userId):
VerifyIdentityRoute(userId: userId).go(context);
break;
case SwitchingAccountsState():
const SwitchingAccountsRoute().push(context);
break;
case AuthenticatedState():
const LandingRoute().go(context);
break;
case AuthenticatingState state:
AuthenticatingRoute(state.currentStage.name).push(context);
break;
case LoggingOutState():
const LoggingOutRoute().go(context);
break;
case AuthenticationErrorState():
if (context.canPop()) {
context.pop();
}
// LoginRoute(
// $extra: errorState.clientCertificate,
// password: errorState.password,
// serverUrl: errorState.serverUrl,
// username: errorState.username,
// ).go(context);
break;
}
},
child: child,
),
);
},
navigatorKey: rootNavigatorKey,
@@ -318,44 +313,7 @@ class _GoRouterShellState extends State<GoRouterShell> {
$loginRoute,
$loggingOutRoute,
$addAccountRoute,
ShellRoute(
navigatorKey: outerShellNavigatorKey,
builder: ProviderShellRoute(widget.apiFactory).build,
routes: [
$settingsRoute,
$savedViewsRoute,
$uploadQueueRoute,
StatefulShellRoute(
navigatorContainerBuilder:
(context, navigationShell, children) {
return children[navigationShell.currentIndex];
},
builder: const ScaffoldShellRoute().builder,
branches: [
StatefulShellBranch(
navigatorKey: landingNavigatorKey,
routes: [$landingRoute],
),
StatefulShellBranch(
navigatorKey: documentsNavigatorKey,
routes: [$documentsRoute],
),
StatefulShellBranch(
navigatorKey: scannerNavigatorKey,
routes: [$scannerRoute],
),
StatefulShellBranch(
navigatorKey: labelsNavigatorKey,
routes: [$labelsRoute],
),
StatefulShellBranch(
navigatorKey: inboxNavigatorKey,
routes: [$inboxRoute],
),
],
),
],
),
$providerShellRoute,
],
),
],

View File

@@ -17,35 +17,11 @@ import 'package:paperless_mobile/routes/navigation_keys.dart';
import 'package:paperless_mobile/routes/routes.dart';
import 'package:paperless_mobile/theme.dart';
part 'documents_route.g.dart';
class DocumentsBranch extends StatefulShellBranchData {
static final GlobalKey<NavigatorState> $navigatorKey = documentsNavigatorKey;
const DocumentsBranch();
}
@TypedGoRoute<DocumentsRoute>(
path: "/documents",
name: R.documents,
routes: [
TypedGoRoute<EditDocumentRoute>(
path: "edit",
name: R.editDocument,
),
TypedGoRoute<DocumentDetailsRoute>(
path: "details",
name: R.documentDetails,
),
TypedGoRoute<DocumentPreviewRoute>(
path: "preview",
name: R.documentPreview,
),
TypedGoRoute<BulkEditDocumentsRoute>(
path: "bulk-edit",
name: R.bulkEditDocuments,
),
],
)
class DocumentsRoute extends GoRouteData {
@override
Widget build(BuildContext context, GoRouterState state) {

View File

@@ -1,14 +1,14 @@
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:paperless_mobile/features/inbox/view/pages/inbox_page.dart';
import 'package:paperless_mobile/routes/routes.dart';
import 'package:paperless_mobile/routes/navigation_keys.dart';
part 'inbox_route.g.dart';
class InboxBranch extends StatefulShellBranchData {
static final GlobalKey<NavigatorState> $navigatorKey = inboxNavigatorKey;
const InboxBranch();
}
@TypedGoRoute<InboxRoute>(
path: "/inbox",
name: R.inbox,
)
class InboxRoute extends GoRouteData {
@override
Widget build(BuildContext context, GoRouterState state) {

View File

@@ -14,33 +14,12 @@ import 'package:paperless_mobile/features/labels/view/pages/labels_page.dart';
import 'package:paperless_mobile/features/linked_documents/cubit/linked_documents_cubit.dart';
import 'package:paperless_mobile/features/linked_documents/view/linked_documents_page.dart';
import 'package:paperless_mobile/routes/navigation_keys.dart';
import 'package:paperless_mobile/routes/routes.dart';
part 'labels_route.g.dart';
class LabelsBranch extends StatefulShellBranchData {
static final GlobalKey<NavigatorState> $navigatorKey = labelsNavigatorKey;
const LabelsBranch();
}
@TypedGoRoute<LabelsRoute>(
path: "/labels",
name: R.labels,
routes: [
TypedGoRoute<EditLabelRoute>(
path: "edit",
name: R.editLabel,
),
TypedGoRoute<CreateLabelRoute>(
path: "create",
name: R.createLabel,
),
TypedGoRoute<LinkedDocumentsRoute>(
path: "linked-documents",
name: R.linkedDocuments,
),
],
)
class LabelsRoute extends GoRouteData {
@override
Widget build(BuildContext context, GoRouterState state) {

View File

@@ -4,18 +4,12 @@ import 'package:paperless_mobile/features/landing/view/landing_page.dart';
import 'package:paperless_mobile/routes/navigation_keys.dart';
import 'package:paperless_mobile/routes/routes.dart';
part 'landing_route.g.dart';
class LandingBranch extends StatefulShellBranchData {
static final GlobalKey<NavigatorState> $navigatorKey = landingNavigatorKey;
const LandingBranch();
}
@TypedGoRoute<LandingRoute>(
path: "/landing",
name: R.landing,
)
class LandingRoute extends GoRouteData {
const LandingRoute();
@override

View File

@@ -10,38 +10,12 @@ import 'package:paperless_mobile/features/document_upload/view/document_upload_p
import 'package:paperless_mobile/routes/navigation_keys.dart';
import 'package:paperless_mobile/routes/routes.dart';
part 'scanner_route.g.dart';
// @TypedStatefulShellBranch<ScannerBranch>(
// routes: [
// TypedGoRoute<ScannerRoute>(
// path: "/scanner",
// name: R.scanner,
// routes: [
// TypedGoRoute<DocumentUploadRoute>(
// path: "upload",
// name: R.uploadDocument,
// ),
// ],
// ),
// ],
// )
class ScannerBranch extends StatefulShellBranchData {
static final GlobalKey<NavigatorState> $navigatorKey = scannerNavigatorKey;
const ScannerBranch();
}
@TypedGoRoute<ScannerRoute>(
path: "/scanner",
name: R.scanner,
routes: [
TypedGoRoute<DocumentUploadRoute>(
path: "upload",
name: R.uploadDocument,
),
],
)
class ScannerRoute extends GoRouteData {
const ScannerRoute();

View File

@@ -0,0 +1,155 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart';
import 'package:hive_flutter/adapters.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
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/home/view/scaffold_with_navigation_bar.dart';
import 'package:paperless_mobile/features/sharing/cubit/receive_share_cubit.dart';
import 'package:paperless_mobile/features/sharing/view/widgets/event_listener_shell.dart';
import 'package:paperless_mobile/routes/navigation_keys.dart';
import 'package:paperless_mobile/routes/routes.dart';
import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
import 'package:paperless_mobile/routes/typed/branches/inbox_route.dart';
import 'package:paperless_mobile/routes/typed/branches/labels_route.dart';
import 'package:paperless_mobile/routes/typed/branches/landing_route.dart';
import 'package:paperless_mobile/routes/typed/branches/scanner_route.dart';
import 'package:paperless_mobile/routes/typed/shells/scaffold_shell_route.dart';
import 'package:paperless_mobile/routes/typed/top_level/settings_route.dart';
import 'package:provider/provider.dart';
/// Key used to access
part 'authenticated_route.g.dart';
@TypedShellRoute<ProviderShellRoute>(
routes: [
TypedGoRoute<SettingsRoute>(
path: "/settings",
name: R.settings,
),
TypedStatefulShellRoute<ScaffoldShellRoute>(
branches: [
TypedStatefulShellBranch<LandingBranch>(
routes: [
TypedGoRoute<LandingRoute>(
path: "/landing",
name: R.landing,
)
],
),
TypedStatefulShellBranch<DocumentsBranch>(
routes: [
TypedGoRoute<DocumentsRoute>(
path: "/documents",
routes: [
TypedGoRoute<DocumentDetailsRoute>(
path: "details",
name: R.documentDetails,
),
TypedGoRoute<EditDocumentRoute>(
path: "edit",
name: R.editDocument,
),
TypedGoRoute<BulkEditDocumentsRoute>(
path: "bulk-edit",
name: R.bulkEditDocuments,
),
TypedGoRoute<DocumentPreviewRoute>(
path: 'preview',
name: R.documentPreview,
),
],
)
],
),
TypedStatefulShellBranch<ScannerBranch>(
routes: [
TypedGoRoute<ScannerRoute>(
path: "/scanner",
name: R.scanner,
routes: [
TypedGoRoute<DocumentUploadRoute>(
path: "upload",
name: R.uploadDocument,
),
],
),
],
),
TypedStatefulShellBranch<LabelsBranch>(
routes: [
TypedGoRoute<LabelsRoute>(
path: "/labels",
name: R.labels,
routes: [
TypedGoRoute<EditLabelRoute>(
path: "edit",
name: R.editLabel,
),
TypedGoRoute<CreateLabelRoute>(
path: "create",
name: R.createLabel,
),
TypedGoRoute<LinkedDocumentsRoute>(
path: "linked-documents",
name: R.linkedDocuments,
),
],
),
],
),
TypedStatefulShellBranch<InboxBranch>(
routes: [
TypedGoRoute<InboxRoute>(
path: "/inbox",
name: R.inbox,
)
],
),
],
),
],
)
class ProviderShellRoute extends ShellRouteData {
static final GlobalKey<NavigatorState> $navigatorKey = outerShellNavigatorKey;
const ProviderShellRoute();
@override
Widget builder(
BuildContext context,
GoRouterState state,
Widget navigator,
) {
final currentUserId = Hive.box<GlobalSettings>(HiveBoxes.globalSettings)
.getValue()!
.loggedInUserId;
if (currentUserId == null) {
return const SizedBox.shrink();
}
final authenticatedUser =
Hive.box<LocalUserAccount>(HiveBoxes.localUserAccount).get(
currentUserId,
)!;
final apiFactory = context.read<PaperlessApiFactory>();
return HomeShellWidget(
localUserId: authenticatedUser.id,
paperlessApiVersion: authenticatedUser.apiVersion,
paperlessProviderFactory: apiFactory,
child: ChangeNotifierProvider(
create: (context) => ConsumptionChangeNotifier()
..loadFromConsumptionDirectory(userId: currentUserId),
child: EventListenerShell(
child: navigator,
),
),
);
}
}

View File

@@ -1,84 +0,0 @@
import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart';
import 'package:hive_flutter/adapters.dart';
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
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/event_listener_shell.dart';
import 'package:paperless_mobile/routes/navigation_keys.dart';
import 'package:provider/provider.dart';
/// Key used to access
//part 'provider_shell_route.g.dart';
//TODO: Wait for https://github.com/flutter/flutter/issues/127371 to be merged
// @TypedShellRoute<ProviderShellRoute>(
// routes: [
// TypedStatefulShellRoute(
// branches: [
// TypedStatefulShellBranch<LandingBranch>(
// routes: [
// TypedGoRoute<LandingRoute>(
// path: "/landing",
// // name: R.landing,
// )
// ],
// ),
// TypedStatefulShellBranch<DocumentsBranch>(
// routes: [
// TypedGoRoute<DocumentsRoute>(
// path: "/documents",
// routes: [
// TypedGoRoute<DocumentDetailsRoute>(
// path: "details",
// // name: R.documentDetails,
// ),
// TypedGoRoute<DocumentEditRoute>(
// path: "edit",
// // name: R.editDocument,
// ),
// ],
// )
// ],
// ),
// ],
// ),
// ],
// )
class ProviderShellRoute extends ShellRouteData {
final PaperlessApiFactory apiFactory;
static final GlobalKey<NavigatorState> $navigatorKey = outerShellNavigatorKey;
const ProviderShellRoute(this.apiFactory);
Widget build(
BuildContext context,
GoRouterState state,
Widget navigator,
) {
final currentUserId = Hive.box<GlobalSettings>(HiveBoxes.globalSettings)
.getValue()!
.loggedInUserId;
if (currentUserId == null) {
return const SizedBox.shrink();
}
final authenticatedUser =
Hive.box<LocalUserAccount>(HiveBoxes.localUserAccount).get(
currentUserId,
)!;
return HomeShellWidget(
localUserId: authenticatedUser.id,
paperlessApiVersion: authenticatedUser.apiVersion,
paperlessProviderFactory: apiFactory,
child: ChangeNotifierProvider(
create: (context) => ConsumptionChangeNotifier()
..loadFromConsumptionDirectory(userId: currentUserId),
child: EventListenerShell(child: navigator),
),
);
}
}

View File

@@ -8,6 +8,12 @@ import 'package:paperless_mobile/features/home/view/scaffold_with_navigation_bar
class ScaffoldShellRoute extends StatefulShellRouteData {
const ScaffoldShellRoute();
static Widget $navigatorContainerBuilder(BuildContext context,
StatefulNavigationShell navigationShell, List<Widget> children) {
return children[navigationShell.currentIndex];
}
@override
Widget builder(
BuildContext context,

View File

@@ -1,5 +1,4 @@
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';
@@ -23,58 +22,61 @@ 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();
Page<void> buildPage(BuildContext context, GoRouterState state) {
return NoTransitionPage(
child: 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()!);
} 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();
} 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,
},
submitText: S.of(context)!.addAccount,
),
);
}
}

View File

@@ -1,7 +1,6 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:paperless_mobile/routes/navigation_keys.dart';
import 'package:paperless_mobile/routes/routes.dart';
part 'logging_out_route.g.dart';
@@ -11,12 +10,16 @@ part 'logging_out_route.g.dart';
name: R.loggingOut,
)
class LoggingOutRoute extends GoRouteData {
static final $parentNavigatorKey = rootNavigatorKey;
const LoggingOutRoute();
@override
Widget build(BuildContext context, GoRouterState state) {
return Scaffold(
body: Center(
child: Text("Logging out..."),
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const NoTransitionPage(
child: Scaffold(
body: Center(
child: Text("Logging out..."), //TODO: INTL
),
),
);
}

View File

@@ -14,7 +14,6 @@ import 'package:paperless_mobile/features/login/view/widgets/login_transition_pa
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';
@TypedGoRoute<LoginRoute>(
@@ -80,10 +79,13 @@ class SwitchingAccountsRoute extends GoRouteData {
static final $parentNavigatorKey = rootNavigatorKey;
const SwitchingAccountsRoute();
@override
Widget build(BuildContext context, GoRouterState state) {
return LoginTransitionPage(
text: S.of(context)!.switchingAccountsPleaseWait,
Page<void> buildPage(BuildContext context, GoRouterState state) {
return NoTransitionPage(
child: LoginTransitionPage(
text: S.of(context)!.switchingAccountsPleaseWait,
),
);
}
}
@@ -93,8 +95,9 @@ class AuthenticatingRoute extends GoRouteData {
final String checkLoginStageName;
const AuthenticatingRoute(this.checkLoginStageName);
@override
Widget build(BuildContext context, GoRouterState state) {
Page<void> buildPage(BuildContext context, GoRouterState state) {
final stage = AuthenticatingStage.values.byName(checkLoginStageName);
final text = switch (stage) {
AuthenticatingStage.authenticating => S.of(context)!.authenticatingDots,
@@ -103,8 +106,11 @@ class AuthenticatingRoute extends GoRouteData {
AuthenticatingStage.fetchingUserInformation =>
S.of(context)!.fetchingUserInformation,
};
return LoginTransitionPage(text: text);
return NoTransitionPage(
child: LoginTransitionPage(
text: text,
),
);
}
}
@@ -115,8 +121,10 @@ class VerifyIdentityRoute extends GoRouteData {
const VerifyIdentityRoute({required this.userId});
@override
Widget build(BuildContext context, GoRouterState state) {
return VerifyIdentityPage(userId: userId);
Page<void> buildPage(BuildContext context, GoRouterState state) {
return NoTransitionPage(
child: VerifyIdentityPage(userId: userId),
);
}
}
@@ -134,8 +142,10 @@ class LoginToExistingAccountRoute extends GoRouteData {
}
@override
Widget build(BuildContext context, GoRouterState state) {
return const LoginToExistingAccountPage();
Page<void> buildPage(BuildContext context, GoRouterState state) {
return const NoTransitionPage(
child: LoginToExistingAccountPage(),
);
}
}
@@ -145,7 +155,11 @@ class RestoringSessionRoute extends GoRouteData {
const RestoringSessionRoute();
@override
Widget build(BuildContext context, GoRouterState state) {
return LoginTransitionPage(text: S.of(context)!.restoringSession);
Page<void> buildPage(BuildContext context, GoRouterState state) {
return NoTransitionPage(
child: LoginTransitionPage(
text: S.of(context)!.restoringSession,
),
);
}
}

View File

@@ -6,14 +6,9 @@ import 'package:paperless_mobile/routes/navigation_keys.dart';
import 'package:paperless_mobile/routes/routes.dart';
import 'package:paperless_mobile/theme.dart';
part 'settings_route.g.dart';
@TypedGoRoute<SettingsRoute>(
path: "/settings",
name: R.settings,
)
class SettingsRoute extends GoRouteData {
static final GlobalKey<NavigatorState> $parentNavigatorKey = outerShellNavigatorKey;
static final GlobalKey<NavigatorState> $parentNavigatorKey =
outerShellNavigatorKey;
@override
Widget build(BuildContext context, GoRouterState state) {

View File

@@ -185,7 +185,7 @@ class DocumentFilter extends Equatable {
added.matches(document.added) &&
modified.matches(document.modified) &&
query.matches(
title: document.title,
title: document.title ?? '',
content: document.content,
asn: document.archiveSerialNumber,
);

View File

@@ -26,7 +26,7 @@ class DocumentModel extends Equatable {
static const storagePathKey = 'storage_path';
final int id;
final String title;
final String? title;
final String? content;
final Iterable<int> tags;
final int? documentType;
@@ -71,7 +71,8 @@ class DocumentModel extends Equatable {
this.permissions,
});
factory DocumentModel.fromJson(Map<String, dynamic> json) => _$DocumentModelFromJson(json);
factory DocumentModel.fromJson(Map<String, dynamic> json) =>
_$DocumentModelFromJson(json);
Map<String, dynamic> toJson() => _$DocumentModelToJson(this);
@@ -94,15 +95,17 @@ class DocumentModel extends Equatable {
title: title ?? this.title,
content: content ?? this.content,
documentType: documentType != null ? documentType() : this.documentType,
correspondent: correspondent != null ? correspondent() : this.correspondent,
correspondent:
correspondent != null ? correspondent() : this.correspondent,
storagePath: storagePath != null ? storagePath() : this.storagePath,
tags: tags ?? this.tags,
created: created ?? this.created,
modified: modified ?? this.modified,
added: added ?? this.added,
originalFileName: originalFileName ?? this.originalFileName,
archiveSerialNumber:
archiveSerialNumber != null ? archiveSerialNumber() : this.archiveSerialNumber,
archiveSerialNumber: archiveSerialNumber != null
? archiveSerialNumber()
: this.archiveSerialNumber,
archivedFileName: archivedFileName ?? this.archivedFileName,
);
}

View File

@@ -748,10 +748,10 @@ packages:
dependency: "direct dev"
description:
name: go_router_builder
sha256: "89585f7cf2ddd35a3f05908c5bb54339d3f891fc5aac4f30e2864469d7ddc92b"
sha256: b004ed761578fd1326054ff9c97daaf7b94f109b24cad843ca8bd349a810f947
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.3.3"
graphs:
dependency: transitive
description:

View File

@@ -118,8 +118,7 @@ dev_dependencies:
hive_generator: ^2.0.1
mock_server:
path: packages/mock_server
go_router_builder: ^2.2.4
go_router_builder: ^2.3.3
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.

View File

@@ -0,0 +1,5 @@
#!/bin/bash
echo "Updating source language..."
crowdin download sources --identity=../crowdin_credentials.yml --config ../crowdin.yml --no-preserve-hierarchy
echo "Updating translations..."
crowdin download --identity=../crowdin_credentials.yml --config ../crowdin.yml