diff --git a/analysis_options.yaml b/analysis_options.yaml index 61b6c4de..af09f85c 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -23,7 +23,6 @@ linter: # producing the lint. rules: # avoid_print: false # Uncomment to disable the `avoid_print` rule - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options diff --git a/lib/core/bloc/bloc_changes_observer.dart b/lib/core/bloc/bloc_changes_observer.dart new file mode 100644 index 00000000..5e9e9254 --- /dev/null +++ b/lib/core/bloc/bloc_changes_observer.dart @@ -0,0 +1,11 @@ +import 'dart:developer'; + +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:paperless_mobile/features/inbox/bloc/inbox_cubit.dart'; + +class BlocChangesObserver extends BlocObserver { + @override + void onChange(BlocBase bloc, Change change) { + super.onChange(bloc, change); + } +} diff --git a/lib/core/logic/timeout_client.dart b/lib/core/logic/timeout_client.dart index f0fe55d6..35cca34c 100644 --- a/lib/core/logic/timeout_client.dart +++ b/lib/core/logic/timeout_client.dart @@ -171,7 +171,6 @@ class TimeoutClient implements BaseClient { // try to parse contained error message, otherwise return response final JSON json = jsonDecode(utf8.decode(response.bodyBytes)); final PaperlessValidationErrors errorMessages = {}; - //TODO: This could be simplified, look at error message format of paperless-ngx for (final entry in json.entries) { if (entry.value is List) { errorMessages.putIfAbsent( diff --git a/lib/core/service/file_service.dart b/lib/core/service/file_service.dart index b13151c6..558c319e 100644 --- a/lib/core/service/file_service.dart +++ b/lib/core/service/file_service.dart @@ -12,7 +12,7 @@ class FileService { ) async { final dir = await documentsDirectory; if (dir == null) { - throw ErrorMessage.unknown(); //TODO: better handling + throw const ErrorMessage.unknown(); //TODO: better handling } File file = File("${dir.path}/$filename"); return file..writeAsBytes(bytes); diff --git a/lib/core/service/github_issue_service.dart b/lib/core/service/github_issue_service.dart index aec05978..38568b9a 100644 --- a/lib/core/service/github_issue_service.dart +++ b/lib/core/service/github_issue_service.dart @@ -1,8 +1,6 @@ import 'dart:developer'; import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:paperless_mobile/core/model/github_error_report.model.dart'; import 'package:paperless_mobile/core/widgets/error_report_page.dart'; import 'package:url_launcher/url_launcher.dart'; diff --git a/lib/core/widgets/documents_list_loading_widget.dart b/lib/core/widgets/documents_list_loading_widget.dart index 9d31cfe2..f1acb1fe 100644 --- a/lib/core/widgets/documents_list_loading_widget.dart +++ b/lib/core/widgets/documents_list_loading_widget.dart @@ -4,12 +4,18 @@ import 'package:flutter/material.dart'; import 'package:shimmer/shimmer.dart'; class DocumentsListLoadingWidget extends StatelessWidget { + final List above; + final List below; static const tags = [" ", " ", " "]; static const titleLengths = [double.infinity, 150.0, 200.0]; static const correspondentLengths = [200.0, 300.0, 150.0]; static const fontSize = 16.0; - const DocumentsListLoadingWidget({super.key}); + const DocumentsListLoadingWidget({ + super.key, + this.above = const [], + this.below = const [], + }); @override Widget build(BuildContext context) { @@ -27,58 +33,67 @@ class DocumentsListLoadingWidget extends StatelessWidget { highlightColor: Theme.of(context).brightness == Brightness.light ? Colors.grey[100]! : Colors.grey[600]!, - child: ListView.builder( - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - final r = Random(index); - final tagCount = r.nextInt(tags.length + 1); - final correspondentLength = correspondentLengths[ - r.nextInt(correspondentLengths.length - 1)]; - final titleLength = - titleLengths[r.nextInt(titleLengths.length - 1)]; - return ListTile( - isThreeLine: true, - leading: ClipRRect( - borderRadius: BorderRadius.circular(8), - child: Container( - color: Colors.white, - height: 50, - width: 35, - ), - ), - title: Container( - padding: const EdgeInsets.symmetric(vertical: 2.0), - width: correspondentLength, - height: fontSize, - color: Colors.white, - ), - subtitle: Padding( - padding: const EdgeInsets.symmetric(vertical: 2.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Container( + child: Column( + children: [ + ...above, + Expanded( + child: ListView.builder( + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + final r = Random(index); + final tagCount = r.nextInt(tags.length + 1); + final correspondentLength = correspondentLengths[ + r.nextInt(correspondentLengths.length - 1)]; + final titleLength = + titleLengths[r.nextInt(titleLengths.length - 1)]; + return ListTile( + isThreeLine: true, + leading: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: Container( + color: Colors.white, + height: 50, + width: 35, + ), + ), + title: Container( padding: const EdgeInsets.symmetric(vertical: 2.0), + width: correspondentLength, height: fontSize, - width: titleLength, color: Colors.white, ), - Wrap( - spacing: 2.0, - children: List.generate( - tagCount, - (index) => InputChip( - label: Text(tags[r.nextInt(tags.length)]), - ), + subtitle: Padding( + padding: const EdgeInsets.symmetric(vertical: 2.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Container( + padding: + const EdgeInsets.symmetric(vertical: 2.0), + height: fontSize, + width: titleLength, + color: Colors.white, + ), + Wrap( + spacing: 2.0, + children: List.generate( + tagCount, + (index) => InputChip( + label: Text(tags[r.nextInt(tags.length)]), + ), + ), + ), + ], ), ), - ], - ), + ); + }, + itemCount: 25, ), - ); - }, - itemCount: 25, + ), + ...below, + ], ), ), ), diff --git a/lib/core/widgets/error_report_page.dart b/lib/core/widgets/error_report_page.dart index 6098e0a9..e93eb383 100644 --- a/lib/core/widgets/error_report_page.dart +++ b/lib/core/widgets/error_report_page.dart @@ -1,9 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter/src/widgets/container.dart'; -import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; -import 'package:form_builder_validators/form_builder_validators.dart'; import 'package:paperless_mobile/core/model/github_error_report.model.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart'; @@ -18,8 +15,8 @@ class ErrorReportPage extends StatefulWidget { class _ErrorReportPageState extends State { final GlobalKey _formKey = GlobalKey(); - static const String shortDescriptionKey = "shortDescription"; - static const String longDescriptionKey = "longDescription"; + static const String shortDescriptionKey = 'shortDescription'; + static const String longDescriptionKey = 'longDescription'; bool _stackTraceCopied = false; @override @@ -27,11 +24,11 @@ class _ErrorReportPageState extends State { return Scaffold( resizeToAvoidBottomInset: true, appBar: AppBar( - title: Text("Report error"), + title: const Text('Report error'), actions: [ TextButton( onPressed: _onSubmit, - child: Text("Submit"), + child: const Text('Submit'), ), ], ), @@ -40,31 +37,31 @@ class _ErrorReportPageState extends State { child: ListView( children: [ Text( - """Oops, an error has occurred! + '''Oops, an error has occurred! In order to improve the app and prevent messages like these, it is greatly appreciated if you report this error with a description of what happened and the actions leading up to this window. Please fill the fields below and create a new issue in GitHub. Thanks! -Note: If you have the GitHub Android app installed, the descriptions will not be taken into account! Skip these here and fill them in the GitHub issues form after submitting this report.""", +Note: If you have the GitHub Android app installed, the descriptions will not be taken into account! Skip these here and fill them in the GitHub issues form after submitting this report.''', style: Theme.of(context).textTheme.bodyMedium, ).padded(), Text( - "Description", + 'Description', style: Theme.of(context).textTheme.subtitle1, ).padded(), FormBuilderTextField( name: shortDescriptionKey, decoration: const InputDecoration( - label: Text("Short Description"), + label: Text('Short Description'), hintText: - "Please provide a brief description of what went wrong."), + 'Please provide a brief description of what went wrong.'), ).padded(), FormBuilderTextField( name: shortDescriptionKey, maxLines: null, keyboardType: TextInputType.multiline, decoration: const InputDecoration( - label: Text("Detailled Description"), + label: Text('Detailled Description'), hintText: - "Please describe the exact actions taken that caused this error. Provide as much details as possible.", + 'Please describe the exact actions taken that caused this error. Provide as much details as possible.', ), ).padded(), if (widget.stackTrace != null) ...[ @@ -72,19 +69,19 @@ Note: If you have the GitHub Android app installed, the descriptions will not be mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - "Stack Trace", + 'Stack Trace', style: Theme.of(context).textTheme.subtitle1, ).padded( const EdgeInsets.only(top: 8.0, left: 8.0, right: 8.0)), TextButton.icon( - label: const Text("Copy"), + label: const Text('Copy'), icon: const Icon(Icons.copy), onPressed: _copyStackTrace, ), ], ), Text( - "Since stack traces cannot be attached to the GitHub issue url, please copy the content of the stackTrace and paste it in the issue description. This will greatly increase the chance of quickly resolving the issue!", + 'Since stack traces cannot be attached to the GitHub issue url, please copy the content of the stackTrace and paste it in the issue description. This will greatly increase the chance of quickly resolving the issue!', style: Theme.of(context).textTheme.caption, ).padded(), Text( @@ -107,7 +104,7 @@ Note: If you have the GitHub Android app installed, the descriptions will not be ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text( - "Stack trace copied to clipboard.", + 'Stack trace copied to clipboard.', ), duration: Duration(seconds: 2), ), @@ -123,25 +120,25 @@ Note: If you have the GitHub Android app installed, the descriptions will not be final continueSubmission = await showDialog( context: context, builder: (context) => AlertDialog( - title: const Text("Continue without stack trace?"), + title: const Text('Continue without stack trace?'), content: const Text( - "It seems you have not yet copied the stack trace. The stack trace provides valuable insights into where an error came from and how it could be fixed. Are you sure you want to continue without providing the stack trace?", + 'It seems you have not yet copied the stack trace. The stack trace provides valuable insights into where an error came from and how it could be fixed. Are you sure you want to continue without providing the stack trace?', ), actionsAlignment: MainAxisAlignment.end, actions: [ TextButton( - child: const Text("Yes, continue"), + child: const Text('Yes, continue'), onPressed: () => Navigator.pop(context, true), ), TextButton( - child: const Text("No, copy stack trace"), + child: const Text('No, copy stack trace'), onPressed: () { _copyStackTrace(); Navigator.pop(context, true); }, ), TextButton( - child: const Text("Cancel"), + child: const Text('Cancel'), onPressed: () => Navigator.pop(context, false), ), ], diff --git a/lib/extensions/dart_extensions.dart b/lib/extensions/dart_extensions.dart index 11af7da6..8e216019 100644 --- a/lib/extensions/dart_extensions.dart +++ b/lib/extensions/dart_extensions.dart @@ -22,3 +22,17 @@ extension DuplicateCheckable on Iterable { return toSet().length != length; } } + +extension DateHelpers on DateTime { + bool get isToday { + final now = DateTime.now(); + return now.day == day && now.month == month && now.year == year; + } + + bool get isYesterday { + final yesterday = DateTime.now().subtract(const Duration(days: 1)); + return yesterday.day == day && + yesterday.month == month && + yesterday.year == year; + } +} diff --git a/lib/features/app_intro/application_intro_slideshow.dart b/lib/features/app_intro/application_intro_slideshow.dart index 17a5442d..b91d5712 100644 --- a/lib/features/app_intro/application_intro_slideshow.dart +++ b/lib/features/app_intro/application_intro_slideshow.dart @@ -17,6 +17,7 @@ class ApplicationIntroSlideshow extends StatefulWidget { _ApplicationIntroSlideshowState(); } +//TODO: INTL ALL class _ApplicationIntroSlideshowState extends State { AssetImage secureImage = AssetImages.secureDocuments.image; AssetImage successImage = AssetImages.success.image; diff --git a/lib/features/document_details/bloc/document_details_cubit.dart b/lib/features/document_details/bloc/document_details_cubit.dart index b13f5c26..f4c92c50 100644 --- a/lib/features/document_details/bloc/document_details_cubit.dart +++ b/lib/features/document_details/bloc/document_details_cubit.dart @@ -1,6 +1,5 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; -import 'package:injectable/injectable.dart'; import 'package:paperless_mobile/features/documents/model/document.model.dart'; import 'package:paperless_mobile/features/documents/repository/document_repository.dart'; diff --git a/lib/features/document_details/view/pages/document_details_page.dart b/lib/features/document_details/view/pages/document_details_page.dart index a0140c56..f278fa31 100644 --- a/lib/features/document_details/view/pages/document_details_page.dart +++ b/lib/features/document_details/view/pages/document_details_page.dart @@ -58,7 +58,6 @@ class _DocumentDetailsPageState extends State { Widget build(BuildContext context) { return WillPopScope( onWillPop: () { - print("Returning document..."); Navigator.of(context) .pop(BlocProvider.of(context).state.document); return Future.value(false); diff --git a/lib/features/documents/bloc/documents_cubit.dart b/lib/features/documents/bloc/documents_cubit.dart index ca257922..0cb1c5a9 100644 --- a/lib/features/documents/bloc/documents_cubit.dart +++ b/lib/features/documents/bloc/documents_cubit.dart @@ -79,8 +79,10 @@ class DocumentsCubit extends Cubit { } final newFilter = state.filter.copyWith(page: state.filter.page + 1); final result = await documentRepository.find(newFilter); - emit(DocumentsState( - isLoaded: true, value: [...state.value, result], filter: newFilter)); + emit( + DocumentsState( + isLoaded: true, value: [...state.value, result], filter: newFilter), + ); } /// diff --git a/lib/features/documents/model/document.model.dart b/lib/features/documents/model/document.model.dart index 894b9fe2..b0732d57 100644 --- a/lib/features/documents/model/document.model.dart +++ b/lib/features/documents/model/document.model.dart @@ -5,18 +5,18 @@ import 'package:paperless_mobile/core/type/types.dart'; class DocumentModel extends Equatable { static const idKey = 'id'; - static const titleKey = "title"; - static const contentKey = "content"; - static const archivedFileNameKey = "archived_file_name"; - static const asnKey = "archive_serial_number"; - static const createdKey = "created"; - static const modifiedKey = "modified"; - static const addedKey = "added"; - static const correspondentKey = "correspondent"; + static const titleKey = 'title'; + static const contentKey = 'content'; + static const archivedFileNameKey = 'archived_file_name'; + static const asnKey = 'archive_serial_number'; + static const createdKey = 'created'; + static const modifiedKey = 'modified'; + static const addedKey = 'added'; + static const correspondentKey = 'correspondent'; static const originalFileNameKey = 'original_file_name'; - static const documentTypeKey = "document_type"; - static const tagsKey = "tags"; - static const storagePathKey = "storage_path"; + static const documentTypeKey = 'document_type'; + static const tagsKey = 'tags'; + static const storagePathKey = 'storage_path'; final int id; final String title; @@ -121,7 +121,7 @@ class DocumentModel extends Equatable { List get props => [ id, title, - content, + content.hashCode, tags, documentType, storagePath, diff --git a/lib/features/documents/model/query_parameters/tags_query.dart b/lib/features/documents/model/query_parameters/tags_query.dart index 0bb91ebf..687d0b0c 100644 --- a/lib/features/documents/model/query_parameters/tags_query.dart +++ b/lib/features/documents/model/query_parameters/tags_query.dart @@ -18,6 +18,7 @@ class OnlyNotAssignedTagsQuery extends TagsQuery { class AnyAssignedTagsQuery extends TagsQuery { final Iterable tagIds; + const AnyAssignedTagsQuery({ this.tagIds = const [], }); diff --git a/lib/features/documents/view/pages/documents_page.dart b/lib/features/documents/view/pages/documents_page.dart index 500c5feb..e120d209 100644 --- a/lib/features/documents/view/pages/documents_page.dart +++ b/lib/features/documents/view/pages/documents_page.dart @@ -37,26 +37,21 @@ class DocumentsPage extends StatefulWidget { } class _DocumentsPageState extends State { - final PagingController _pagingController = - PagingController( + final _pagingController = PagingController( firstPageKey: 1, ); - final PanelController _filterPanelController = PanelController(); + final _filterPanelController = PanelController(); @override void initState() { super.initState(); - _initDocuments(); - _pagingController.addPageRequestListener(_loadNewPage); - } - - Future _initDocuments() async { try { BlocProvider.of(context).load(); } on ErrorMessage catch (error, stackTrace) { showErrorMessage(context, error, stackTrace); } + _pagingController.addPageRequestListener(_loadNewPage); } @override @@ -120,7 +115,10 @@ class _DocumentsPageState extends State { return Scaffold( drawer: BlocProvider.value( value: BlocProvider.of(context), - child: const InfoDrawer(), + child: InfoDrawer( + afterInboxClosed: () => + BlocProvider.of(context).reload(), + ), ), resizeToAvoidBottomInset: true, body: SlidingUpPanel( diff --git a/lib/features/home/view/widget/info_drawer.dart b/lib/features/home/view/widget/info_drawer.dart index 6ec99294..66cf6fd0 100644 --- a/lib/features/home/view/widget/info_drawer.dart +++ b/lib/features/home/view/widget/info_drawer.dart @@ -1,33 +1,30 @@ -import 'package:badges/badges.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:paperless_mobile/core/model/paperless_statistics_state.dart'; -import 'package:paperless_mobile/features/inbox/bloc/inbox_cubit.dart'; -import 'package:paperless_mobile/features/labels/bloc/global_state_bloc_provider.dart'; import 'package:paperless_mobile/core/bloc/paperless_server_information_cubit.dart'; import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:paperless_mobile/core/model/paperless_server_information.dart'; -import 'package:paperless_mobile/core/model/paperless_statistics.dart'; -import 'package:paperless_mobile/core/service/paperless_statistics_service.dart'; -import 'package:paperless_mobile/features/documents/repository/document_repository.dart'; -import 'package:paperless_mobile/features/inbox/view/pages/inbox_page.dart'; -import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart'; import 'package:paperless_mobile/di_initializer.dart'; +import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; +import 'package:paperless_mobile/features/inbox/bloc/inbox_cubit.dart'; +import 'package:paperless_mobile/features/inbox/view/pages/inbox_page.dart'; +import 'package:paperless_mobile/features/labels/bloc/global_state_bloc_provider.dart'; import 'package:paperless_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart'; import 'package:paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart'; -import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; -import 'package:paperless_mobile/features/settings/view/settings_page.dart'; +import 'package:paperless_mobile/features/labels/tags/bloc/tags_cubit.dart'; import 'package:paperless_mobile/features/login/bloc/authentication_cubit.dart'; import 'package:paperless_mobile/features/scan/bloc/document_scanner_cubit.dart'; -import 'package:paperless_mobile/features/labels/tags/bloc/tags_cubit.dart'; +import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart'; +import 'package:paperless_mobile/features/settings/view/settings_page.dart'; import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/util.dart'; import 'package:url_launcher/link.dart'; import 'package:url_launcher/url_launcher_string.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; class InfoDrawer extends StatelessWidget { - const InfoDrawer({Key? key}) : super(key: key); + final VoidCallback? afterInboxClosed; + + const InfoDrawer({Key? key, this.afterInboxClosed}) : super(key: key); @override Widget build(BuildContext context) { return ClipRRect( @@ -52,7 +49,7 @@ class InfoDrawer extends StatelessWidget { Row( children: [ Image.asset( - "assets/logos/paperless_logo_white.png", + 'assets/logos/paperless_logo_white.png', height: 32, width: 32, color: Theme.of(context).colorScheme.onPrimaryContainer, @@ -124,7 +121,7 @@ class InfoDrawer extends StatelessWidget { leading: const Icon(Icons.inbox), onTap: () => _onOpenInbox(context), ), - Divider(), + const Divider(), ListTile( leading: const Icon(Icons.settings), title: Text( @@ -145,27 +142,27 @@ class InfoDrawer extends StatelessWidget { title: Text(S.of(context).appDrawerReportBugLabel), onTap: () { launchUrlString( - "https://github.com/astubenbord/paperless-mobile/issues/new"); + 'https://github.com/astubenbord/paperless-mobile/issues/new'); }, ), const Divider(), AboutListTile( icon: const Icon(Icons.info), applicationIcon: const ImageIcon( - AssetImage("assets/logos/paperless_logo_green.png")), - applicationName: "Paperless Mobile", + AssetImage('assets/logos/paperless_logo_green.png')), + applicationName: 'Paperless Mobile', applicationVersion: - kPackageInfo.version + "+" + kPackageInfo.buildNumber, + kPackageInfo.version + '+' + kPackageInfo.buildNumber, aboutBoxChildren: [ Text( '${S.of(context).aboutDialogDevelopedByText} Anton Stubenbord'), Link( uri: Uri.parse( - "https://github.com/astubenbord/paperless-mobile"), + 'https://github.com/astubenbord/paperless-mobile'), builder: (context, followLink) => GestureDetector( onTap: followLink, child: Text( - "https://github.com/astubenbord/paperless-mobile", + 'https://github.com/astubenbord/paperless-mobile', style: TextStyle( color: Theme.of(context).colorScheme.tertiary), ), @@ -173,7 +170,7 @@ class InfoDrawer extends StatelessWidget { ), const SizedBox(height: 16), Text( - "Credits", + 'Credits', style: Theme.of(context).textTheme.titleMedium, ), _buildOnboardingImageCredits(), @@ -204,36 +201,38 @@ class InfoDrawer extends StatelessWidget { ); } - Future _onOpenInbox(BuildContext context) { - return Navigator.of(context).push( + Future _onOpenInbox(BuildContext context) async { + await Navigator.of(context).push( MaterialPageRoute( builder: (_) => GlobalStateBlocProvider( additionalProviders: [ BlocProvider.value( - value: getIt()..initialize(), + value: getIt()..loadInbox(), ), ], child: const InboxPage(), ), + maintainState: false, ), ); + afterInboxClosed?.call(); } Link _buildOnboardingImageCredits() { return Link( uri: Uri.parse( - "https://www.freepik.com/free-vector/business-team-working-cogwheel-mechanism-together_8270974.htm#query=setting&position=4&from_view=author"), + 'https://www.freepik.com/free-vector/business-team-working-cogwheel-mechanism-together_8270974.htm#query=setting&position=4&from_view=author'), builder: (context, followLink) => Wrap( children: [ - const Text("Onboarding images by "), + const Text('Onboarding images by '), GestureDetector( onTap: followLink, child: Text( - "pch.vector", + 'pch.vector', style: TextStyle(color: Theme.of(context).colorScheme.tertiary), ), ), - const Text(" on Freepik.") + const Text(' on Freepik.') ], ), ); diff --git a/lib/features/inbox/bloc/inbox_cubit.dart b/lib/features/inbox/bloc/inbox_cubit.dart index 4079e778..9f7a18ee 100644 --- a/lib/features/inbox/bloc/inbox_cubit.dart +++ b/lib/features/inbox/bloc/inbox_cubit.dart @@ -21,9 +21,18 @@ class InboxCubit extends Cubit { /// /// Fetches inbox tag ids and loads the inbox items (documents). /// - Future initialize() async { + Future loadInbox() async { final inboxTags = await _labelRepository.getTags().then( - (value) => value.where((t) => t.isInboxTag ?? false).map((t) => t.id!)); + (tags) => tags.where((t) => t.isInboxTag ?? false).map((t) => t.id!), + ); + if (inboxTags.isEmpty) { + // no inbox tags = no inbox items. + return emit(const InboxState( + isLoaded: true, + inboxItems: [], + inboxTags: [], + )); + } final inboxDocuments = await _documentRepository .find(DocumentFilter( tags: AnyAssignedTagsQuery(tagIds: inboxTags), @@ -38,33 +47,11 @@ class InboxCubit extends Cubit { emit(newState); } - Future reloadInbox() async { - if (!state.isLoaded) { - throw "State has not yet loaded. Ensure the state is loaded when calling this method!"; - } - final inboxDocuments = await _documentRepository - .find(DocumentFilter( - tags: AnyAssignedTagsQuery(tagIds: state.inboxTags), - sortField: SortField.added, - )) - .then((psr) => psr.results); - emit( - InboxState( - isLoaded: true, - inboxItems: inboxDocuments, - inboxTags: state.inboxTags, - ), - ); - } - /// /// Updates the document with all inbox tags removed and removes the document /// from the currently loaded inbox documents. /// Future> remove(DocumentModel document) async { - if (!state.isLoaded) { - throw "State has not loaded yet. Ensure the state is loaded when calling this method!"; - } final tagsToRemove = document.tags.toSet().intersection(state.inboxTags.toSet()); diff --git a/lib/features/inbox/view/pages/inbox_page.dart b/lib/features/inbox/view/pages/inbox_page.dart index 716b6e2e..b9bedcb5 100644 --- a/lib/features/inbox/view/pages/inbox_page.dart +++ b/lib/features/inbox/view/pages/inbox_page.dart @@ -1,15 +1,19 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:intl/date_symbol_data_local.dart'; +import 'package:intl/intl.dart'; import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:paperless_mobile/core/widgets/documents_list_loading_widget.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/documents/model/document.model.dart'; import 'package:paperless_mobile/features/inbox/bloc/inbox_cubit.dart'; import 'package:paperless_mobile/features/inbox/bloc/state/inbox_state.dart'; -import 'package:paperless_mobile/features/inbox/view/widgets/document_inbox_item.dart'; +import 'package:paperless_mobile/features/inbox/view/widgets/inbox_item.dart'; +import 'package:paperless_mobile/features/inbox/view/widgets/inbox_empty_widget.dart'; import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/util.dart'; +import 'package:collection/collection.dart'; +import 'package:paperless_mobile/extensions/dart_extensions.dart'; class InboxPage extends StatefulWidget { const InboxPage({super.key}); @@ -30,7 +34,6 @@ class _InboxPageState extends State { @override Widget build(BuildContext context) { - //TODO: Group by date (today, yseterday, etc.) return Scaffold( appBar: AppBar( title: Text(S.of(context).bottomNavInboxPageLabel), @@ -39,7 +42,7 @@ class _InboxPageState extends State { onPressed: () => Navigator.pop(context), ), bottom: PreferredSize( - preferredSize: Size.fromHeight(14), + preferredSize: const Size.fromHeight(14), child: BlocBuilder( builder: (context, state) { return Align( @@ -49,7 +52,7 @@ class _InboxPageState extends State { child: ColoredBox( color: Theme.of(context).colorScheme.secondaryContainer, child: Text( - '${state.inboxItems.length} unseen', + '${state.inboxItems.length} ${S.of(context).inboxPageUnseenText}', textAlign: TextAlign.start, style: Theme.of(context).textTheme.caption, ).padded(const EdgeInsets.symmetric(horizontal: 4.0)), @@ -62,8 +65,11 @@ class _InboxPageState extends State { ), floatingActionButton: BlocBuilder( builder: (context, state) { + if (!state.isLoaded || state.inboxItems.isEmpty) { + return const SizedBox.shrink(); + } return FloatingActionButton.extended( - label: Text("Mark all as seen"), + label: Text(S.of(context).inboxPageMarkAllAsSeenLabel), icon: const Icon(Icons.done_all), onPressed: state.isLoaded && state.inboxItems.isNotEmpty ? () => _onMarkAllAsSeen( @@ -81,51 +87,68 @@ class _InboxPageState extends State { } if (state.inboxItems.isEmpty) { - return RefreshIndicator( - key: _emptyStateRefreshIndicatorKey, - onRefresh: () => - BlocProvider.of(context).reloadInbox(), - child: Center( - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text('You do not have unseen documents.'), - TextButton( - onPressed: () => - _emptyStateRefreshIndicatorKey.currentState?.show(), - child: Text('Refresh'), - ), - ], - ), - ), + return InboxEmptyWidget( + emptyStateRefreshIndicatorKey: _emptyStateRefreshIndicatorKey, ); } + + // Build a list of slivers alternating between SliverToBoxAdapter + // (group header) and a SliverList (inbox items). + final List slivers = _groupByDate(state.inboxItems) + .entries + .map( + (entry) => [ + SliverToBoxAdapter( + child: Align( + alignment: Alignment.centerLeft, + child: ClipRRect( + borderRadius: BorderRadius.circular(32.0), + child: Text( + entry.key, + style: Theme.of(context).textTheme.caption, + textAlign: TextAlign.center, + ).padded(), + ), + ).padded(const EdgeInsets.only(top: 8.0)), + ), + SliverList( + delegate: SliverChildBuilderDelegate( + childCount: entry.value.length, + (context, index) => _buildListItem( + context, + entry.value[index], + ), + ), + ), + ], + ) + .flattened + .toList(); + return RefreshIndicator( - onRefresh: () => BlocProvider.of(context).reloadInbox(), + onRefresh: () => BlocProvider.of(context).loadInbox(), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - Text( - 'Hint: Swipe left to mark a document as seen. This will remove all inbox tags from the document.', //TODO: INTL - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.caption, - ).padded( - const EdgeInsets.only( - top: 4.0, - left: 8.0, - right: 8.0, - bottom: 8.0, - ), - ), Expanded( - child: ListView.builder( - itemCount: state.inboxItems.length, - itemBuilder: (context, index) { - final doc = state.inboxItems.elementAt(index); - return _buildListItem(context, doc); - }, + child: CustomScrollView( + slivers: [ + SliverToBoxAdapter( + child: Text( + S.of(context).inboxPageUsageHintText, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.caption, + ).padded( + const EdgeInsets.only( + top: 8.0, + left: 8.0, + right: 8.0, + bottom: 8.0, + ), + ), + ), + ...slivers + ], ), ), ], @@ -147,7 +170,7 @@ class _InboxPageState extends State { color: Theme.of(context).colorScheme.primary, ).padded(), Text( - 'Mark as seen', //TODO: INTL + S.of(context).inboxPageMarkAsSeenText, style: TextStyle( color: Theme.of(context).colorScheme.primary, ), @@ -156,7 +179,7 @@ class _InboxPageState extends State { ).padded(), confirmDismiss: (_) => _onItemDismissed(doc), key: UniqueKey(), - child: DocumentInboxItem(document: doc), + child: InboxItem(document: doc), ); } @@ -167,9 +190,11 @@ class _InboxPageState extends State { final isActionConfirmed = await showDialog( context: context, builder: (context) => AlertDialog( - title: Text('Confirm action'), + title: Text(S + .of(context) + .inboxPageMarkAllAsSeenConfirmationDialogTitleText), content: Text( - 'Are you sure you want to mark all documents as seen? This will perform a bulk edit operation removing all inbox tags from the documents.\nThis action is not reversible! Are you sure you want to continue?', + S.of(context).inboxPageMarkAllAsSeenConfirmationDialogText, ), actions: [ TextButton( @@ -178,7 +203,10 @@ class _InboxPageState extends State { ), TextButton( onPressed: () => Navigator.of(context).pop(true), - child: Text(S.of(context).genericActionOkLabel), + child: Text( + S.of(context).genericActionOkLabel, + style: TextStyle(color: Theme.of(context).colorScheme.error), + ), ), ], ), @@ -195,9 +223,9 @@ class _InboxPageState extends State { await BlocProvider.of(context).remove(doc); showSnackBar( context, - 'Document removed from inbox.', //TODO: INTL + S.of(context).inboxPageDocumentRemovedMessageText, action: SnackBarAction( - label: 'UNDO', //TODO: INTL + label: S.of(context).inboxPageUndoRemoveText, onPressed: () => _onUndoMarkAsSeen(doc, removedTags), ), ); @@ -225,4 +253,21 @@ class _InboxPageState extends State { showErrorMessage(context, error, stackTrace); } } + + Map> _groupByDate( + Iterable documents, + ) { + return groupBy( + documents, + (doc) { + if (doc.added.isToday) { + return S.of(context).inboxPageTodayText; + } + if (doc.added.isYesterday) { + return S.of(context).inboxPageYesterdayText; + } + return DateFormat.yMMMMd().format(doc.added); + }, + ); + } } diff --git a/lib/features/inbox/view/widgets/inbox_empty_widget.dart b/lib/features/inbox/view/widgets/inbox_empty_widget.dart new file mode 100644 index 00000000..485927c6 --- /dev/null +++ b/lib/features/inbox/view/widgets/inbox_empty_widget.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:paperless_mobile/features/inbox/bloc/inbox_cubit.dart'; + +class InboxEmptyWidget extends StatelessWidget { + const InboxEmptyWidget({ + Key? key, + required GlobalKey emptyStateRefreshIndicatorKey, + }) : _emptyStateRefreshIndicatorKey = emptyStateRefreshIndicatorKey, + super(key: key); + + final GlobalKey _emptyStateRefreshIndicatorKey; + + @override + Widget build(BuildContext context) { + return RefreshIndicator( + key: _emptyStateRefreshIndicatorKey, + onRefresh: () => BlocProvider.of(context).loadInbox(), + child: Center( + child: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('You do not have unseen documents.'), + TextButton( + onPressed: () => + _emptyStateRefreshIndicatorKey.currentState?.show(), + child: Text('Refresh'), + ), + ], + ), + ), + ); + } +} diff --git a/lib/features/inbox/view/widgets/document_inbox_item.dart b/lib/features/inbox/view/widgets/inbox_item.dart similarity index 96% rename from lib/features/inbox/view/widgets/document_inbox_item.dart rename to lib/features/inbox/view/widgets/inbox_item.dart index 4cdd3612..bc0901c9 100644 --- a/lib/features/inbox/view/widgets/document_inbox_item.dart +++ b/lib/features/inbox/view/widgets/inbox_item.dart @@ -11,14 +11,16 @@ import 'package:paperless_mobile/features/documents/view/widgets/document_previe import 'package:paperless_mobile/features/labels/bloc/global_state_bloc_provider.dart'; import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_widget.dart'; -class DocumentInboxItem extends StatelessWidget { +class InboxItem extends StatelessWidget { + static const _a4AspectRatio = 1 / 1.4142; + final DocumentModel document; - const DocumentInboxItem({ + const InboxItem({ super.key, required this.document, }); - static const _a4AspectRatio = 1 / 1.4142; + @override Widget build(BuildContext context) { return ListTile( diff --git a/lib/features/labels/view/pages/edit_label_page.dart b/lib/features/labels/view/pages/edit_label_page.dart index 7fac4f1e..366d386e 100644 --- a/lib/features/labels/view/pages/edit_label_page.dart +++ b/lib/features/labels/view/pages/edit_label_page.dart @@ -50,7 +50,7 @@ class _EditLabelPageState extends State> { ], ), floatingActionButton: FloatingActionButton.extended( - icon: const Icon(Icons.add), + icon: const Icon(Icons.update), label: Text(S.of(context).genericActionUpdateLabel), onPressed: _onSubmit, ), diff --git a/lib/l10n/intl_de.arb b/lib/l10n/intl_de.arb index a7c93849..80b9f17f 100644 --- a/lib/l10n/intl_de.arb +++ b/lib/l10n/intl_de.arb @@ -1,201 +1,419 @@ { "@@locale": "de", - "documentTitlePropertyLabel": "Titel", - "documentCreatedPropertyLabel": "Ausgestellt am", - "documentAddedPropertyLabel": "Hinzugefügt am", - "documentModifiedPropertyLabel": "Geändert am", - "documentDocumentTypePropertyLabel": "Dokumenttyp", - "documentCorrespondentPropertyLabel": "Korrespondent", - "documentStoragePathPropertyLabel": "Speicherpfad", - "documentTagsPropertyLabel": "Tags", - "documentArchiveSerialNumberPropertyLongLabel": "Archiv-Seriennummer", - "documentArchiveSerialNumberPropertyShortLabel": "ASN", + "aboutDialogDevelopedByText": "Entwickelt von", + "@aboutDialogDevelopedByText": {}, + "addCorrespondentPageTitle": "Neuer Korrespondent", + "@addCorrespondentPageTitle": {}, + "addDocumentTypePageTitle": "Neuer Dokumenttyp", + "@addDocumentTypePageTitle": {}, + "addStoragePathPageTitle": "Neuer Speicherpfad", + "@addStoragePathPageTitle": {}, + "addTagPageTitle": "Neuer Tag", + "@addTagPageTitle": {}, + "appDrawerAboutInfoLoadingText": "Lade Anwendungsinformationen...", + "@appDrawerAboutInfoLoadingText": {}, + "appDrawerAboutLabel": "Über diese App", + "@appDrawerAboutLabel": {}, + "appDrawerHeaderLoggedInAsText": "Eingeloggt als ", + "@appDrawerHeaderLoggedInAsText": {}, + "appDrawerLogoutLabel": "Verbindung trennen", + "@appDrawerLogoutLabel": {}, + "appDrawerReportBugLabel": "Einen Fehler melden", + "@appDrawerReportBugLabel": {}, + "appDrawerSettingsLabel": "Einstellungen", + "@appDrawerSettingsLabel": {}, + "appSettingsBiometricAuthenticationDescriptionText": "Authentifizierung beim Start der Anwendung", + "@appSettingsBiometricAuthenticationDescriptionText": {}, + "appSettingsBiometricAuthenticationLabel": "Biometrische Authentifizierung aktivieren", + "@appSettingsBiometricAuthenticationLabel": {}, + "appSettingsDisableBiometricAuthenticationReasonText": "Authentifizieren, um die biometrische Authentifizierung zu deaktivieren.", + "@appSettingsDisableBiometricAuthenticationReasonText": {}, + "appSettingsEnableBiometricAuthenticationReasonText": "Authentifizieren, um die biometrische Authentifizierung zu aktivieren.", + "@appSettingsEnableBiometricAuthenticationReasonText": {}, "appTitleText": "Paperless Mobile", + "@appTitleText": {}, "bottomNavDocumentsPageLabel": "Dokumente", - "bottomNavScannerPageLabel": "Scanner", + "@bottomNavDocumentsPageLabel": {}, + "bottomNavInboxPageLabel": "Posteingang", + "@bottomNavInboxPageLabel": {}, "bottomNavLabelsPageLabel": "Kennzeichnungen", - "documentsPageTitle": "Dokumente", - "documentsFilterPageTitle": "Dokumente Filtern", + "@bottomNavLabelsPageLabel": {}, + "bottomNavScannerPageLabel": "Scanner", + "@bottomNavScannerPageLabel": {}, + "correspondentFormFieldSearchHintText": "Beginne zu tippen...", + "@correspondentFormFieldSearchHintText": {}, + "deleteViewDialogContentText": "Möchtest Du diese Ansicht wirklich löschen?", + "@deleteViewDialogContentText": {}, + "deleteViewDialogTitleText": "Lösche Ansicht ", + "@deleteViewDialogTitleText": {}, + "documentAddedPropertyLabel": "Hinzugefügt am", + "@documentAddedPropertyLabel": {}, + "documentArchiveSerialNumberPropertyLongLabel": "Archiv-Seriennummer", + "@documentArchiveSerialNumberPropertyLongLabel": {}, + "documentArchiveSerialNumberPropertyShortLabel": "ASN", + "@documentArchiveSerialNumberPropertyShortLabel": {}, + "documentCorrespondentPropertyLabel": "Korrespondent", + "@documentCorrespondentPropertyLabel": {}, + "documentCreatedPropertyLabel": "Ausgestellt am", + "@documentCreatedPropertyLabel": {}, + "documentDeleteSuccessMessage": "Das Dokument wurde erfolgreich gelöscht.", + "@documentDeleteSuccessMessage": {}, + "documentDetailsPageAssignAsnButtonLabel": "Zuweisen", + "@documentDetailsPageAssignAsnButtonLabel": {}, + "documentDetailsPageSimilarDocumentsLabel": "Similar Documents", + "@documentDetailsPageSimilarDocumentsLabel": {}, + "documentDetailsPageTabContentLabel": "Inhalt", + "@documentDetailsPageTabContentLabel": {}, + "documentDetailsPageTabMetaDataLabel": "Metadaten", + "@documentDetailsPageTabMetaDataLabel": {}, + "documentDetailsPageTabOverviewLabel": "Übersicht", + "@documentDetailsPageTabOverviewLabel": {}, + "documentDocumentTypePropertyLabel": "Dokumenttyp", + "@documentDocumentTypePropertyLabel": {}, + "documentEditPageTitle": "Dokument Bearbeiten", + "@documentEditPageTitle": {}, + "documentMetaDataChecksumLabel": "MD5-Prüfsumme Original", + "@documentMetaDataChecksumLabel": {}, + "documentMetaDataMediaFilenamePropertyLabel": "Media-Dateiname", + "@documentMetaDataMediaFilenamePropertyLabel": {}, + "documentMetaDataOriginalFileSizeLabel": "Dateigröße Original", + "@documentMetaDataOriginalFileSizeLabel": {}, + "documentMetaDataOriginalMimeTypeLabel": "MIME-Typ Original", + "@documentMetaDataOriginalMimeTypeLabel": {}, + "documentModifiedPropertyLabel": "Geändert am", + "@documentModifiedPropertyLabel": {}, + "documentPreviewPageTitle": "Vorschau", + "@documentPreviewPageTitle": {}, + "documentScannerPageAddScanButtonLabel": "Scanne ein Dokument", + "@documentScannerPageAddScanButtonLabel": {}, + "documentScannerPageEmptyStateText": "Es wurden noch keine Dokumente gescannt.", + "@documentScannerPageEmptyStateText": {}, + "documentScannerPageOrText": "oder", + "@documentScannerPageOrText": {}, + "documentScannerPageResetButtonTooltipText": "Alle scans löschen", + "@documentScannerPageResetButtonTooltipText": {}, + "documentScannerPageTitle": "Scanner", + "@documentScannerPageTitle": {}, + "documentScannerPageUploadButtonTooltip": "Dokument hochladen", + "@documentScannerPageUploadButtonTooltip": {}, + "documentScannerPageUploadFromThisDeviceButtonLabel": "Lade ein Dokument von diesem Gerät hoch", + "@documentScannerPageUploadFromThisDeviceButtonLabel": {}, "documentsFilterPageAdvancedLabel": "Erweitert", - "documentsFilterPageDateRangeLastSevenDaysLabel": "Letzte 7 Tage", + "@documentsFilterPageAdvancedLabel": {}, + "documentsFilterPageApplyFilterLabel": "Anwenden", + "@documentsFilterPageApplyFilterLabel": {}, + "documentsFilterPageDateRangeFieldEndLabel": "Bis", + "@documentsFilterPageDateRangeFieldEndLabel": {}, + "documentsFilterPageDateRangeFieldStartLabel": "Von", + "@documentsFilterPageDateRangeFieldStartLabel": {}, "documentsFilterPageDateRangeLastMonthLabel": "Letzter Monat", + "@documentsFilterPageDateRangeLastMonthLabel": {}, + "documentsFilterPageDateRangeLastSevenDaysLabel": "Letzte 7 Tage", + "@documentsFilterPageDateRangeLastSevenDaysLabel": {}, "documentsFilterPageDateRangeLastThreeMonthsLabel": "Letzten 3 Monate", + "@documentsFilterPageDateRangeLastThreeMonthsLabel": {}, "documentsFilterPageDateRangeLastYearLabel": "Letztes Jahr", - "documentsFilterPageApplyFilterLabel": "Anwenden", - "documentsFilterPageResetFilterLabel": "Zurücksetzen", - "documentsFilterPageQueryOptionsTitleLabel": "Titel", - "documentsFilterPageQueryOptionsTitleAndContentLabel": "Titel & Inhalt", - "documentsFilterPageQueryOptionsExtendedLabel": "Erweitert", + "@documentsFilterPageDateRangeLastYearLabel": {}, "documentsFilterPageQueryOptionsAsnLabel": "ASN", - "documentsFilterPageDateRangeFieldStartLabel": "Von", - "documentsFilterPageDateRangeFieldEndLabel": "Bis", - "genericActionOkLabel": "Ok", - "genericActionCancelLabel": "Abbrechen", - "genericActionDeleteLabel": "Löschen", - "genericActionEditLabel": "Bearbeiten", - "genericActionSaveLabel": "Speichern", - "genericActionSelectText": "Auswählen", - "genericActionCreateLabel": "Erstellen", - "genericActionUploadLabel": "Hochladen", - "genericActionUpdateLabel": "Aktualisieren", - "appDrawerSettingsLabel": "Einstellungen", - "appDrawerAboutLabel": "Über diese App", - "appDrawerAboutInfoLoadingText": "Lade Anwendungsinformationen...", - "appDrawerReportBugLabel": "Einen Fehler melden", - "appDrawerLogoutLabel": "Verbindung trennen", - "loginPageLoginButtonLabel": "Verbinden", - "loginPageTitle": "Mit Paperless verbinden", - "loginPageAdvancedLabel": "Erweiterte Einstellungen", - "loginPageServerUrlValidatorMessageText": "Server-Addresse darf nicht leer sein.", - "loginPageServerUrlFieldLabel": "Server-Adresse", - "loginPageUsernameValidatorMessageText": "Nutzername darf nicht leer sein.", - "loginPageUsernameLabel": "Nutzername", - "loginPagePasswordValidatorMessageText": "Passwort darf nicht leer sein.", - "loginPagePasswordFieldLabel": "Passwort", - "loginPageClientCertificatePassphraseLabel": "Passphrase", - "loginPageIncorrectOrMissingCertificatePassphraseErrorMessageText": "Falsche oder fehlende Zertifikatspassphrase.", - "documentDetailsPageTabOverviewLabel": "Übersicht", - "documentDetailsPageTabContentLabel": "Inhalt", - "documentDetailsPageTabMetaDataLabel": "Metadaten", - "documentsPageEmptyStateOopsText": "Ups.", + "@documentsFilterPageQueryOptionsAsnLabel": {}, + "documentsFilterPageQueryOptionsExtendedLabel": "Erweitert", + "@documentsFilterPageQueryOptionsExtendedLabel": {}, + "documentsFilterPageQueryOptionsTitleAndContentLabel": "Titel & Inhalt", + "@documentsFilterPageQueryOptionsTitleAndContentLabel": {}, + "documentsFilterPageQueryOptionsTitleLabel": "Titel", + "@documentsFilterPageQueryOptionsTitleLabel": {}, + "documentsFilterPageResetFilterLabel": "Zurücksetzen", + "@documentsFilterPageResetFilterLabel": {}, + "documentsFilterPageSearchLabel": "Suche", + "@documentsFilterPageSearchLabel": {}, + "documentsFilterPageTitle": "Dokumente Filtern", + "@documentsFilterPageTitle": {}, + "documentsPageBulkDeleteSuccessfulText": "Das massenhafte Löschen der Dokumente war erfolgreich.", + "@documentsPageBulkDeleteSuccessfulText": {}, "documentsPageEmptyStateNothingHereText": "Es scheint nichts hier zu sein...", - "errorMessageUnknonwnError": "Ein unbekannter Fehler ist aufgetreten.", + "@documentsPageEmptyStateNothingHereText": {}, + "documentsPageEmptyStateOopsText": "Ups.", + "@documentsPageEmptyStateOopsText": {}, + "documentsPageOrderByLabel": "Sortiere nach", + "@documentsPageOrderByLabel": {}, + "documentsPageSelectionBulkDeleteDialogContinueText": "Diese Aktion ist unwiderruflich. Möchten Sie trotzdem fortfahren?", + "@documentsPageSelectionBulkDeleteDialogContinueText": {}, + "documentsPageSelectionBulkDeleteDialogTitle": "Löschen bestätigen", + "@documentsPageSelectionBulkDeleteDialogTitle": {}, + "documentsPageSelectionBulkDeleteDialogWarningTextMany": "Sind Sie sicher, dass sie folgende Dokumente löschen wollen?", + "@documentsPageSelectionBulkDeleteDialogWarningTextMany": {}, + "documentsPageSelectionBulkDeleteDialogWarningTextOne": "Sind Sie sicher, dass sie folgendes Dokument löschen wollen?", + "@documentsPageSelectionBulkDeleteDialogWarningTextOne": {}, + "documentsPageTitle": "Dokumente", + "@documentsPageTitle": {}, + "documentsSelectedText": "ausgewählt", + "@documentsSelectedText": {}, + "documentStoragePathPropertyLabel": "Speicherpfad", + "@documentStoragePathPropertyLabel": {}, + "documentsUploadPageTitle": "Dokument vorbereiten", + "@documentsUploadPageTitle": {}, + "documentTagsPropertyLabel": "Tags", + "@documentTagsPropertyLabel": {}, + "documentTitlePropertyLabel": "Titel", + "@documentTitlePropertyLabel": {}, + "documentTypeFormFieldSearchHintText": "Beginne zu tippen...", + "@documentTypeFormFieldSearchHintText": {}, + "documentUpdateSuccessMessage": "Dokument erfolgreich aktualisiert.", + "@documentUpdateSuccessMessage": {}, + "documentUploadFileNameLabel": "Dateiname", + "@documentUploadFileNameLabel": {}, + "documentUploadPageSynchronizeTitleAndFilenameLabel": "Synchronisiere Titel und Dateiname", + "@documentUploadPageSynchronizeTitleAndFilenameLabel": {}, + "documentUploadProcessingSuccessfulReloadActionText": "Neu laden", + "@documentUploadProcessingSuccessfulReloadActionText": {}, + "documentUploadProcessingSuccessfulText": "Das Dokument wurde erfolgreich verarbeitet.", + "@documentUploadProcessingSuccessfulText": {}, + "documentUploadSuccessText": "Das Dokument wurde erfolgreich hochgeladen. Verarbeite...", + "@documentUploadSuccessText": {}, + "editLabelPageConfirmDeletionDialogTitle": "Löschen bestätigen", + "@editLabelPageConfirmDeletionDialogTitle": {}, + "editLabelPageDeletionDialogText": "Dieser Kennzeichner wird von Dokumenten referenziert. Durch das Löschen dieses Kennzeichners werden alle Referenzen entfernt. Fortfahren?", + "@editLabelPageDeletionDialogText": {}, "errorMessageAuthenticationFailed": "Authentifizierung fehlgeschlagen, bitte versuche es erneut.", - "errorMessageNotAuthenticated": "User is not authenticated.", - "errorMessageDocumentUploadFailed": "Dokument konnte nicht hochgeladen werden, bitte versuche es erneut.", - "errorMessageDocumentUpdateFailed": "Dokument konnte nicht aktualisiert werden, bitte versuche es erneut.", + "@errorMessageAuthenticationFailed": {}, + "errorMessageAutocompleteQueryError": "Beim automatischen Vervollständigen ist ein Fehler aufgetreten.", + "@errorMessageAutocompleteQueryError": {}, + "errorMessageBiometricAuthenticationFailed": "Biometrische Authentifizierung fehlgeschlagen.", + "@errorMessageBiometricAuthenticationFailed": {}, + "errorMessageBiotmetricsNotSupported": "Biometrische Authentifizierung wird von diesem Gerät nicht unterstützt.", + "@errorMessageBiotmetricsNotSupported": {}, + "errorMessageBulkActionFailed": "Es ist ein Fehler beim massenhaften bearbeiten der Dokumente aufgetreten.", + "@errorMessageBulkActionFailed": {}, + "errorMessageCorrespondentCreateFailed": "Korrespondent konnte nicht erstellt werden, bitte versuche es erneut.", + "@errorMessageCorrespondentCreateFailed": {}, + "errorMessageCorrespondentLoadFailed": "Korrespondenten konnten nicht geladen werden.", + "@errorMessageCorrespondentLoadFailed": {}, + "errorMessageCreateSavedViewError": "Gespeicherte Ansicht konnte nicht erstellt werden, bitte versuche es erneut.", + "@errorMessageCreateSavedViewError": {}, + "errorMessageDeleteSavedViewError": "Gespeicherte Ansicht konnte nicht geklöscht werden, bitte versuche es erneut.", + "@errorMessageDeleteSavedViewError": {}, + "errorMessageDeviceOffline": "Daten konnten nicht geladen werden: Eine Verbindung zum Internet konnte nicht hergestellt werden.", + "@errorMessageDeviceOffline": {}, + "errorMessageDocumentAsnQueryFailed": "Archiv-Seriennummer konnte nicht zugewiesen werden.", + "@errorMessageDocumentAsnQueryFailed": {}, "errorMessageDocumentDeleteFailed": "Dokument konnte nicht gelöscht werden, bitte versuche es erneut.", + "@errorMessageDocumentDeleteFailed": {}, + "errorMessageDocumentLoadFailed": "Dokumente konnten nicht geladen werden, bitte versuche es erneut.", + "@errorMessageDocumentLoadFailed": {}, "errorMessageDocumentPreviewFailed": "Vorschau konnte nicht geladen werden.", - "errorMessageDocumentAsnQueryFailed": "Archiv-Seriennummer konnte nicht zugewiesen werden.", - "errorMessageTagCreateFailed": "Tag konnte nicht erstellt werden, bitte versuche es erneut.", - "errorMessageTagLoadFailed": "Tags konnten nicht geladen werden.", + "@errorMessageDocumentPreviewFailed": {}, "errorMessageDocumentTypeCreateFailed": "Dokumenttyp konnte nicht erstellt werden, bitte versuche es erneut.", + "@errorMessageDocumentTypeCreateFailed": {}, "errorMessageDocumentTypeLoadFailed": "Dokumenttypen konnten nicht geladen werden, bitte versuche es erneut.", - "errorMessageCorrespondentCreateFailed": "Korrespondent konnte nicht erstellt werden, bitte versuche es erneut.", - "errorMessageCorrespondentLoadFailed": "Korrespondenten konnten nicht geladen werden.", - "errorMessageScanRemoveFailed": "Beim Löschen der Aufnahmen ist ein Fehler aufgetreten.", + "@errorMessageDocumentTypeLoadFailed": {}, + "errorMessageDocumentUpdateFailed": "Dokument konnte nicht aktualisiert werden, bitte versuche es erneut.", + "@errorMessageDocumentUpdateFailed": {}, + "errorMessageDocumentUploadFailed": "Dokument konnte nicht hochgeladen werden, bitte versuche es erneut.", + "@errorMessageDocumentUploadFailed": {}, "errorMessageInvalidClientCertificateConfiguration": "Ungültiges Zertifikat oder fehlende Passphrase, bitte versuche es erneut.", - "errorMessageDocumentLoadFailed": "Dokumente konnten nicht geladen werden, bitte versuche es erneut.", - "documentsPageSelectionBulkDeleteDialogTitle": "Löschen bestätigen", - "documentsPageSelectionBulkDeleteDialogWarningTextOne": "Sind Sie sicher, dass sie folgendes Dokument löschen wollen?", - "documentsPageSelectionBulkDeleteDialogWarningTextMany": "Sind Sie sicher, dass sie folgende Dokumente löschen wollen?", - "documentsPageSelectionBulkDeleteDialogContinueText": "Diese Aktion ist unwiderruflich. Möchten Sie trotzdem fortfahren?", - "documentPreviewPageTitle": "Vorschau", - "appSettingsBiometricAuthenticationLabel": "Biometrische Authentifizierung aktivieren", - "appSettingsEnableBiometricAuthenticationReasonText": "Authentifizieren, um die biometrische Authentifizierung zu aktivieren.", - "appSettingsDisableBiometricAuthenticationReasonText": "Authentifizieren, um die biometrische Authentifizierung zu deaktivieren.", - "errorMessageBulkActionFailed": "Es ist ein Fehler beim massenhaften bearbeiten der Dokumente aufgetreten.", - "errorMessageBiotmetricsNotSupported": "Biometrische Authentifizierung wird von diesem Gerät nicht unterstützt.", - "errorMessageBiometricAuthenticationFailed": "Biometrische Authentifizierung fehlgeschlagen.", - "errorMessageDeviceOffline": "Daten konnten nicht geladen werden: Eine Verbindung zum Internet konnte nicht hergestellt werden.", + "@errorMessageInvalidClientCertificateConfiguration": {}, + "errorMessageLoadSavedViewsError": "Gespeicherte Ansichten konnten nicht geladen werden.", + "@errorMessageLoadSavedViewsError": {}, + "errorMessageMissingClientCertificate": "Ein Client Zerfitikat wurde erwartet, aber nicht gesendet. Bitte konfiguriere ein gültiges Zertifikat.", + "@errorMessageMissingClientCertificate": {}, + "errorMessageNotAuthenticated": "User is not authenticated.", + "@errorMessageNotAuthenticated": {}, + "errorMessageRequestTimedOut": "Bei der Anfrage an den Server kam es zu einer Zeitüberschreitung.", + "@errorMessageRequestTimedOut": {}, + "errorMessageScanRemoveFailed": "Beim Löschen der Aufnahmen ist ein Fehler aufgetreten.", + "@errorMessageScanRemoveFailed": {}, "errorMessageServerUnreachable": "Es konnte keine Verbindung zu Deinem Paperless Server hergestellt werden, ist die Instanz in Betrieb?", - "aboutDialogDevelopedByText": "Entwickelt von", - "documentsPageBulkDeleteSuccessfulText": "Das massenhafte Löschen der Dokumente war erfolgreich.", - "documentDeleteSuccessMessage": "Das Dokument wurde erfolgreich gelöscht.", - "documentsSelectedText": "ausgewählt", + "@errorMessageServerUnreachable": {}, + "errorMessageSimilarQueryError": "Ähnliche Dokumente konnten nicht geladen werden.", + "@errorMessageSimilarQueryError": {}, + "errorMessageStoragePathCreateFailed": "Speicherpfad konnte nicht erstellt werden, bitte versuche es erneut.", + "@errorMessageStoragePathCreateFailed": {}, + "errorMessageStoragePathLoadFailed": "Speicherpfade konnten nicht geladen werden.", + "@errorMessageStoragePathLoadFailed": {}, + "errorMessageTagCreateFailed": "Tag konnte nicht erstellt werden, bitte versuche es erneut.", + "@errorMessageTagCreateFailed": {}, + "errorMessageTagLoadFailed": "Tags konnten nicht geladen werden.", + "@errorMessageTagLoadFailed": {}, + "errorMessageUnknonwnError": "Ein unbekannter Fehler ist aufgetreten.", + "@errorMessageUnknonwnError": {}, + "errorMessageUnsupportedFileFormat": "Das Dateiformat wird nicht unterstützt.", + "@errorMessageUnsupportedFileFormat": {}, + "errorReportLabel": "MELDEN", + "@errorReportLabel": {}, + "genericActionCancelLabel": "Abbrechen", + "@genericActionCancelLabel": {}, + "genericActionCreateLabel": "Erstellen", + "@genericActionCreateLabel": {}, + "genericActionDeleteLabel": "Löschen", + "@genericActionDeleteLabel": {}, + "genericActionEditLabel": "Bearbeiten", + "@genericActionEditLabel": {}, + "genericActionOkLabel": "Ok", + "@genericActionOkLabel": {}, + "genericActionSaveLabel": "Speichern", + "@genericActionSaveLabel": {}, + "genericActionSelectText": "Auswählen", + "@genericActionSelectText": {}, + "genericActionUpdateLabel": "Aktualisieren", + "@genericActionUpdateLabel": {}, + "genericActionUploadLabel": "Hochladen", + "@genericActionUploadLabel": {}, + "genericMessageOfflineText": "Du bist offline. Überprüfe deine Verbindung.", + "@genericMessageOfflineText": {}, + "inboxPageDocumentRemovedMessageText": "Dokument aus Posteingang entfernt.", + "@inboxPageDocumentRemovedMessageText": {}, + "inboxPageMarkAllAsSeenConfirmationDialogText": "Sind Sie sicher, dass Sie alle Dokumente als gesehen markieren möchten? Dadurch wird eine Massenbearbeitung durchgeführt, bei der alle Posteingangs-Tags von den Dokumenten entfernt werden.\nDiese Aktion kann nicht rückgängig gemacht werden! Möchten Sie trotzdem fortfahren?", + "@inboxPageMarkAllAsSeenConfirmationDialogText": {}, + "inboxPageMarkAllAsSeenConfirmationDialogTitleText": "Alle als gesehen markieren?", + "@inboxPageMarkAllAsSeenConfirmationDialogTitleText": {}, + "inboxPageMarkAllAsSeenLabel": "Alle als gesehen markieren", + "@inboxPageMarkAllAsSeenLabel": {}, + "inboxPageMarkAsSeenText": "Als gesehen markieren", + "@inboxPageMarkAsSeenText": {}, + "inboxPageTodayText": "Heute", + "@inboxPageTodayText": {}, + "inboxPageUndoRemoveText": "UNDO", + "@inboxPageUndoRemoveText": {}, + "inboxPageUnseenText": "ungesehen", + "@inboxPageUnseenText": {}, + "inboxPageUsageHintText": "Tipp: Wische nach links um ein Dokument als gesehen zu markieren und alle Posteingangs-Tags von diesem Dokument zu entfernen.", + "@inboxPageUsageHintText": {}, + "inboxPageYesterdayText": "Gestern", + "@inboxPageYesterdayText": {}, + "labelAnyAssignedText": "Beliebig zugewiesen", + "@labelAnyAssignedText": {}, + "labelFormFieldNoItemsFoundText": "Keine Treffer gefunden!", + "@labelFormFieldNoItemsFoundText": {}, + "labelIsInsensivitePropertyLabel": "Groß-/Kleinschreibung irrelevant", + "@labelIsInsensivitePropertyLabel": {}, + "labelMatchingAlgorithmPropertyLabel": "Zuweisungsalgorithmus", + "@labelMatchingAlgorithmPropertyLabel": {}, + "labelMatchPropertyLabel": "Zuweisungsmuster", + "@labelMatchPropertyLabel": {}, + "labelNamePropertyLabel": "Name", + "@labelNamePropertyLabel": {}, + "labelNotAssignedText": "Nicht zugewiesen", + "@labelNotAssignedText": {}, + "labelsPageCorrespondentEmptyStateAddNewLabel": "Erstelle neuen Korrespondenten", + "@labelsPageCorrespondentEmptyStateAddNewLabel": {}, + "labelsPageCorrespondentEmptyStateDescriptionText": "Es wurden noch keine Korrespondenten angelegt.", + "@labelsPageCorrespondentEmptyStateDescriptionText": {}, "labelsPageCorrespondentsTitleText": "Korrespondenten", + "@labelsPageCorrespondentsTitleText": {}, + "labelsPageDocumentTypeEmptyStateAddNewLabel": "Erstelle neuen Dokumenttypen", + "@labelsPageDocumentTypeEmptyStateAddNewLabel": {}, + "labelsPageDocumentTypeEmptyStateDescriptionText": "Es wurden noch keine Dokumenttypen angelegt.", + "@labelsPageDocumentTypeEmptyStateDescriptionText": {}, "labelsPageDocumentTypesTitleText": "Dokumenttypen", + "@labelsPageDocumentTypesTitleText": {}, + "labelsPageStoragePathEmptyStateAddNewLabel": "Erstelle neuen Speicherpfad", + "@labelsPageStoragePathEmptyStateAddNewLabel": {}, + "labelsPageStoragePathEmptyStateDescriptionText": "Es wurden noch keine Speicherpfade angelegt.", + "@labelsPageStoragePathEmptyStateDescriptionText": {}, + "labelsPageStoragePathTitleText": "Speicherpfade", + "@labelsPageStoragePathTitleText": {}, + "labelsPageTagsEmptyStateAddNewLabel": "Erstelle neuen Tag", + "@labelsPageTagsEmptyStateAddNewLabel": {}, + "labelsPageTagsEmptyStateDescriptionText": "Es wurden noch keine Tags angelegt.", + "@labelsPageTagsEmptyStateDescriptionText": {}, "labelsPageTagsTitleText": "Tags", - "tagColorPropertyLabel": "Farbe", - "tagInboxTagPropertyLabel": "Posteingangs-Tag", - "documentScannerPageEmptyStateText": "Es wurden noch keine Dokumente gescannt.", - "documentScannerPageTitle": "Scanner", - "documentScannerPageResetButtonTooltipText": "Alle scans löschen", - "documentScannerPageUploadButtonTooltip": "Dokument hochladen", - "documentScannerPageAddScanButtonLabel": "Scanne ein Dokument", - "documentScannerPageOrText": "oder", - "documentScannerPageUploadFromThisDeviceButtonLabel": "Lade ein Dokument von diesem Gerät hoch", - "addTagPageTitle": "Neuer Tag", - "addCorrespondentPageTitle": "Neuer Korrespondent", - "addDocumentTypePageTitle": "Neuer Dokumenttyp", - "labelNamePropertyLabel": "Name", - "labelMatchPropertyLabel": "Zuweisungsmuster", - "labelMatchingAlgorithmPropertyLabel": "Zuweisungsalgorithmus", - "labelIsInsensivitePropertyLabel": "Groß-/Kleinschreibung irrelevant", + "@labelsPageTagsTitleText": {}, "linkedDocumentsPageTitle": "Referenzierte Dokumente", - "documentsUploadPageTitle": "Dokument vorbereiten", - "documentUploadFileNameLabel": "Dateiname", - "documentUploadSuccessText": "Das Dokument wurde erfolgreich hochgeladen. Verarbeite...", - "documentUploadProcessingSuccessfulText": "Das Dokument wurde erfolgreich verarbeitet.", - "documentUploadProcessingSuccessfulReloadActionText": "Neu laden", - "labelNotAssignedText": "Nicht zugewiesen", - "correspondentFormFieldSearchHintText": "Beginne zu tippen...", - "documentTypeFormFieldSearchHintText": "Beginne zu tippen...", - "tagFormFieldSearchHintText": "Beginne zu tippen...", - "documentsPageOrderByLabel": "Sortiere nach", - "documentDetailsPageAssignAsnButtonLabel": "Zuweisen", - "documentMetaDataMediaFilenamePropertyLabel": "Media-Dateiname", - "documentMetaDataChecksumLabel": "MD5-Prüfsumme Original", - "documentMetaDataOriginalFileSizeLabel": "Dateigröße Original", - "documentMetaDataOriginalMimeTypeLabel": "MIME-Typ Original", - "loginPageClientCertificateSettingLabel": "Client Zertifikat", + "@linkedDocumentsPageTitle": {}, + "loginPageAdvancedLabel": "Erweiterte Einstellungen", + "@loginPageAdvancedLabel": {}, + "loginPageClientCertificatePassphraseLabel": "Passphrase", + "@loginPageClientCertificatePassphraseLabel": {}, "loginPageClientCertificateSettingDescriptionText": "Konfiguriere Mutual TLS Authentifizierung", + "@loginPageClientCertificateSettingDescriptionText": {}, "loginPageClientCertificateSettingInvalidFileFormatValidationText": "Ungültiges Zertifikatsformat, nur .pfx ist erlaubt.", + "@loginPageClientCertificateSettingInvalidFileFormatValidationText": {}, + "loginPageClientCertificateSettingLabel": "Client Zertifikat", + "@loginPageClientCertificateSettingLabel": {}, "loginPageClientCertificateSettingSelectFileText": "Datei auswählen...", - "uploadPageAutomaticallInferredFieldsHintText": "Wenn Werte für diese Felder angegeben werden, wird Paperless nicht automatisch einen Wert zuweisen. Wenn diese Felder automatisch von Paperless erkannt werden sollen, sollten die Felder leer bleiben.", - "settingsPageLanguageSettingLabel": "Sprache", - "settingsPageApplicationSettingsLabel": "Anwendung", - "settingsPageSecuritySettingsLabel": "Sicherheit", - "settingsPageApplicationSettingsDescriptionText": "Sprache und Aussehen", - "settingsPageSecuritySettingsDescriptionText": "Biometrische Authentifizierung", - "settingsPageAppearanceSettingTitle": "Aussehen", - "settingsPageAppearanceSettingSystemThemeLabel": "Benutze Sytemeinstellung", - "settingsPageAppearanceSettingLightThemeLabel": "Heller Modus", - "settingsPageAppearanceSettingDarkThemeLabel": "Dunkler Modus", - "appSettingsBiometricAuthenticationDescriptionText": "Authentifizierung beim Start der Anwendung", - "settingsThemeModeSystemLabel": "System", - "settingsThemeModeLightLabel": "Hell", - "settingsThemeModeDarkLabel": "Dunkel", - "genericMessageOfflineText": "Du bist offline. Überprüfe deine Verbindung.", - "documentDetailsPageSimilarDocumentsLabel": "Similar Documents", + "@loginPageClientCertificateSettingSelectFileText": {}, + "loginPageIncorrectOrMissingCertificatePassphraseErrorMessageText": "Falsche oder fehlende Zertifikatspassphrase.", + "@loginPageIncorrectOrMissingCertificatePassphraseErrorMessageText": {}, + "loginPageLoginButtonLabel": "Verbinden", + "@loginPageLoginButtonLabel": {}, + "loginPagePasswordFieldLabel": "Passwort", + "@loginPagePasswordFieldLabel": {}, + "loginPagePasswordValidatorMessageText": "Passwort darf nicht leer sein.", + "@loginPagePasswordValidatorMessageText": {}, + "loginPageServerUrlFieldLabel": "Server-Adresse", + "@loginPageServerUrlFieldLabel": {}, + "loginPageServerUrlValidatorMessageText": "Server-Addresse darf nicht leer sein.", + "@loginPageServerUrlValidatorMessageText": {}, + "loginPageTitle": "Mit Paperless verbinden", + "@loginPageTitle": {}, + "loginPageUsernameLabel": "Nutzername", + "@loginPageUsernameLabel": {}, + "loginPageUsernameValidatorMessageText": "Nutzername darf nicht leer sein.", + "@loginPageUsernameValidatorMessageText": {}, "offlineWidgetText": "Es konte keine Verbindung zum Internet hergestellt werden.", - "labelsPageStoragePathTitleText": "Speicherpfade", - "addStoragePathPageTitle": "Neuer Speicherpfad", + "@offlineWidgetText": {}, + "onboardingDoneButtonLabel": "Fertig", + "@onboardingDoneButtonLabel": {}, + "onboardingNextButtonLabel": "Weiter", + "@onboardingNextButtonLabel": {}, + "referencedDocumentsReadOnlyHintText": "Dies ist eine schreibgeschützte Ansicht! Dokumente können nicht bearbeitet oder entfernt werden. Es werden maximal 100 referenzierte Dokumente geladen.", + "@referencedDocumentsReadOnlyHintText": {}, "savedViewCreateNewLabel": "Neue Ansicht", + "@savedViewCreateNewLabel": {}, + "savedViewCreateTooltipText": "Erstellt eine neue Ansicht basierend auf den aktuellen Filterkriterien.", + "@savedViewCreateTooltipText": {}, "savedViewNameLabel": "Name", - "savedViewShowOnDashboardLabel": "Auf Startseite zeigen", + "@savedViewNameLabel": {}, + "savedViewsEmptyStateText": "Lege Ansichten an, um Dokumente schneller zu finden.", + "@savedViewsEmptyStateText": {}, "savedViewShowInSidebarLabel": "In Seitenleiste zeigen", + "@savedViewShowInSidebarLabel": {}, + "savedViewShowOnDashboardLabel": "Auf Startseite zeigen", + "@savedViewShowOnDashboardLabel": {}, "savedViewsLabel": "Gespeicherte Ansichten", - "savedViewsEmptyStateText": "Lege Ansichten an, um Dokumente schneller zu finden.", - "savedViewCreateTooltipText": "Erstellt eine neue Ansicht basierend auf den aktuellen Filterkriterien.", - "documentsFilterPageSearchLabel": "Suche", - "documentEditPageTitle": "Dokument Bearbeiten", + "@savedViewsLabel": {}, + "serverInformationPaperlessVersionText": "Paperless Server-Version", + "@serverInformationPaperlessVersionText": {}, + "settingsPageAppearanceSettingDarkThemeLabel": "Dunkler Modus", + "@settingsPageAppearanceSettingDarkThemeLabel": {}, + "settingsPageAppearanceSettingLightThemeLabel": "Heller Modus", + "@settingsPageAppearanceSettingLightThemeLabel": {}, + "settingsPageAppearanceSettingSystemThemeLabel": "Benutze Sytemeinstellung", + "@settingsPageAppearanceSettingSystemThemeLabel": {}, + "settingsPageAppearanceSettingTitle": "Aussehen", + "@settingsPageAppearanceSettingTitle": {}, + "settingsPageApplicationSettingsDescriptionText": "Sprache und Aussehen", + "@settingsPageApplicationSettingsDescriptionText": {}, + "settingsPageApplicationSettingsLabel": "Anwendung", + "@settingsPageApplicationSettingsLabel": {}, + "settingsPageLanguageSettingLabel": "Sprache", + "@settingsPageLanguageSettingLabel": {}, + "settingsPageSecuritySettingsDescriptionText": "Biometrische Authentifizierung", + "@settingsPageSecuritySettingsDescriptionText": {}, + "settingsPageSecuritySettingsLabel": "Sicherheit", + "@settingsPageSecuritySettingsLabel": {}, + "settingsPageStorageSettingsDescriptionText": "Dateien und Speicherplatz verwalten", + "@settingsPageStorageSettingsDescriptionText": {}, + "settingsPageStorageSettingsLabel": "Speicher", + "@settingsPageStorageSettingsLabel": {}, + "settingsThemeModeDarkLabel": "Dunkel", + "@settingsThemeModeDarkLabel": {}, + "settingsThemeModeLightLabel": "Hell", + "@settingsThemeModeLightLabel": {}, + "settingsThemeModeSystemLabel": "System", + "@settingsThemeModeSystemLabel": {}, "storagePathParameterDayLabel": "Tag", - "storagePathParameterYearLabel": "Jahr", + "@storagePathParameterDayLabel": {}, "storagePathParameterMonthLabel": "Monat", - "errorMessageSimilarQueryError": "Ähnliche Dokumente konnten nicht geladen werden.", - "errorMessageAutocompleteQueryError": "Beim automatischen Vervollständigen ist ein Fehler aufgetreten.", - "errorMessageStoragePathLoadFailed": "Speicherpfade konnten nicht geladen werden.", - "errorMessageStoragePathCreateFailed": "Speicherpfad konnte nicht erstellt werden, bitte versuche es erneut.", - "errorMessageLoadSavedViewsError": "Gespeicherte Ansichten konnten nicht geladen werden.", - "errorMessageCreateSavedViewError": "Gespeicherte Ansicht konnte nicht erstellt werden, bitte versuche es erneut.", - "errorMessageDeleteSavedViewError": "Gespeicherte Ansicht konnte nicht geklöscht werden, bitte versuche es erneut.", - "errorMessageRequestTimedOut": "Bei der Anfrage an den Server kam es zu einer Zeitüberschreitung.", - "errorMessageUnsupportedFileFormat": "Das Dateiformat wird nicht unterstützt.", - "labelFormFieldNoItemsFoundText": "Keine Treffer gefunden!", - "onboardingDoneButtonLabel": "Fertig", - "onboardingNextButtonLabel": "Weiter", - "labelsPageCorrespondentEmptyStateAddNewLabel": "Erstelle neuen Korrespondenten", - "labelsPageCorrespondentEmptyStateDescriptionText": "Es wurden noch keine Korrespondenten angelegt.", - "labelsPageDocumentTypeEmptyStateAddNewLabel": "Erstelle neuen Dokumenttypen", - "labelsPageDocumentTypeEmptyStateDescriptionText": "Es wurden noch keine Dokumenttypen angelegt.", - "labelsPageTagsEmptyStateAddNewLabel": "Erstelle neuen Tag", - "labelsPageTagsEmptyStateDescriptionText": "Es wurden noch keine Tags angelegt.", - "labelsPageStoragePathEmptyStateAddNewLabel": "Erstelle neuen Speicherpfad", - "labelsPageStoragePathEmptyStateDescriptionText": "Es wurden noch keine Speicherpfade angelegt.", - "referencedDocumentsReadOnlyHintText": "Dies ist eine schreibgeschützte Ansicht! Dokumente können nicht bearbeitet oder entfernt werden. Es werden maximal 100 referenzierte Dokumente geladen.", - "editLabelPageConfirmDeletionDialogTitle": "Löschen bestätigen", - "editLabelPageDeletionDialogText": "Dieser Kennzeichner wird von Dokumenten referenziert. Durch das Löschen dieses Kennzeichners werden alle Referenzen entfernt. Fortfahren?", - "settingsPageStorageSettingsLabel": "Speicher", - "settingsPageStorageSettingsDescriptionText": "Dateien und Speicherplatz verwalten", - "documentUpdateSuccessMessage": "Dokument erfolgreich aktualisiert.", - "errorMessageMissingClientCertificate": "Ein Client Zerfitikat wurde erwartet, aber nicht gesendet. Bitte konfiguriere ein gültiges Zertifikat.", - "serverInformationPaperlessVersionText": "Paperless Server-Version", - "errorReportLabel": "MELDEN", - "appDrawerHeaderLoggedInAsText": "Eingeloggt als ", - "labelAnyAssignedText": "Beliebig zugewiesen", - "deleteViewDialogContentText": "Möchtest Du diese Ansicht wirklich löschen?", - "deleteViewDialogTitleText": "Lösche Ansicht ", - "documentUploadPageSynchronizeTitleAndFilenameLabel": "Synchronisiere Titel und Dateiname", - "bottomNavInboxPageLabel": "Posteingang" + "@storagePathParameterMonthLabel": {}, + "storagePathParameterYearLabel": "Jahr", + "@storagePathParameterYearLabel": {}, + "tagColorPropertyLabel": "Farbe", + "@tagColorPropertyLabel": {}, + "tagFormFieldSearchHintText": "Beginne zu tippen...", + "@tagFormFieldSearchHintText": {}, + "tagInboxTagPropertyLabel": "Posteingangs-Tag", + "@tagInboxTagPropertyLabel": {}, + "uploadPageAutomaticallInferredFieldsHintText": "Wenn Werte für diese Felder angegeben werden, wird Paperless nicht automatisch einen Wert zuweisen. Wenn diese Felder automatisch von Paperless erkannt werden sollen, sollten die Felder leer bleiben.", + "@uploadPageAutomaticallInferredFieldsHintText": {} } \ No newline at end of file diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index dfd91b21..ce3e64e3 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -1,202 +1,419 @@ { - "@@locale": "en", - "documentTitlePropertyLabel": "Title", - "documentCreatedPropertyLabel": "Created At", - "documentAddedPropertyLabel": "Added At", - "documentModifiedPropertyLabel": "Modified At", - "documentDocumentTypePropertyLabel": "Document Type", - "documentCorrespondentPropertyLabel": "Correspondent", - "documentStoragePathPropertyLabel": "Storage Path", - "documentTagsPropertyLabel": "Tags", - "documentArchiveSerialNumberPropertyLongLabel": "Archive Serial Number", - "documentArchiveSerialNumberPropertyShortLabel": "ASN", - "appTitleText": "Paperless Mobile", - "bottomNavDocumentsPageLabel": "Documents", - "bottomNavScannerPageLabel": "Scanner", - "bottomNavLabelsPageLabel": "Labels", - "documentsPageTitle": "Documents", - "documentsFilterPageTitle": "Filter Documents", - "documentsFilterPageAdvancedLabel": "Advanced", - "documentsFilterPageDateRangeLastSevenDaysLabel": "Last 7 Days", - "documentsFilterPageDateRangeLastMonthLabel": "Last Month", - "documentsFilterPageDateRangeLastThreeMonthsLabel": "Last 3 Months", - "documentsFilterPageDateRangeLastYearLabel": "Last Year", - "documentsFilterPageApplyFilterLabel": "Apply", - "documentsFilterPageResetFilterLabel": "Reset", - "documentsFilterPageQueryOptionsTitleLabel": "Title", - "documentsFilterPageQueryOptionsTitleAndContentLabel": "Title & Content", - "documentsFilterPageQueryOptionsExtendedLabel": "Extended", - "documentsFilterPageQueryOptionsAsnLabel": "ASN", - "documentsFilterPageDateRangeFieldStartLabel": "From", - "documentsFilterPageDateRangeFieldEndLabel": "To", - "genericActionOkLabel": "Ok", - "genericActionCancelLabel": "Cancel", - "genericActionSelectText": "Select", - "genericActionDeleteLabel": "Delete", - "genericActionEditLabel": "Edit", - "genericActionSaveLabel": "Save", - "genericActionCreateLabel": "Create", - "genericActionUploadLabel": "Upload", - "genericActionUpdateLabel": "Update", - "appDrawerSettingsLabel": "Settings", - "appDrawerAboutLabel": "About this app", - "appDrawerAboutInfoLoadingText": "Retrieving application information...", - "appDrawerReportBugLabel": "Report a Bug", - "appDrawerLogoutLabel": "Disconnect", - "loginPageLoginButtonLabel": "Connect", - "loginPageTitle": "Connect to Paperless", - "loginPageAdvancedLabel": "Advanced Settings", - "loginPageServerUrlValidatorMessageText": "Server address must not be empty.", - "loginPageServerUrlFieldLabel": "Server Address", - "loginPageUsernameValidatorMessageText": "Username must not be empty.", - "loginPageUsernameLabel": "Username", - "loginPagePasswordValidatorMessageText": "Password must not be empty.", - "loginPagePasswordFieldLabel": "Password", - "loginPageClientCertificatePassphraseLabel": "Passphrase", - "loginPageIncorrectOrMissingCertificatePassphraseErrorMessageText": "Incorrect or missing certificate passphrase.", - "documentDetailsPageTabOverviewLabel": "Overview", - "documentDetailsPageTabContentLabel": "Content", - "documentDetailsPageTabMetaDataLabel": "Meta Data", - "documentsPageEmptyStateOopsText": "Oops.", - "documentsPageEmptyStateNothingHereText": "There seems to be nothing here...", - "errorMessageUnknonwnError": "An unknown error occurred.", - "errorMessageAuthenticationFailed": "Authentication failed, please try again.", - "errorMessageNotAuthenticated": "User is not authenticated.", - "errorMessageDocumentUploadFailed": "Could not upload document, please try again.", - "errorMessageDocumentUpdateFailed": "Could not update document, please try again.", - "errorMessageDocumentDeleteFailed": "Could not delete document, please try again.", - "errorMessageDocumentPreviewFailed": "Could not load document preview.", - "errorMessageDocumentAsnQueryFailed": "Could not assign archive serial number.", - "errorMessageTagCreateFailed": "Could not create tag, please try again.", - "errorMessageTagLoadFailed": "Could not load tags.", - "errorMessageDocumentTypeCreateFailed": "Could not create document, please try again.", - "errorMessageDocumentTypeLoadFailed": "Could not load document types, please try again.", - "errorMessageCorrespondentCreateFailed": "Could not create correspondent, please try again.", - "errorMessageCorrespondentLoadFailed": "Could not load correspondents.", - "errorMessageScanRemoveFailed": "An error occurred removing the scans.", - "errorMessageInvalidClientCertificateConfiguration": "Invalid certificate or missing passphrase, please try again", - "errorMessageDocumentLoadFailed": "Could not load documents, please try again.", - "documentsPageSelectionBulkDeleteDialogTitle": "Confirm deletion", - "documentsPageSelectionBulkDeleteDialogWarningTextOne": "Are you sure you want to delete the following document?", - "documentsPageSelectionBulkDeleteDialogWarningTextMany": "Are you sure you want to delete the following documents?", - "documentsPageSelectionBulkDeleteDialogContinueText": "This action is irreversible. Do you wish to proceed anyway?", - "documentPreviewPageTitle": "Preview", - "appSettingsEnableBiometricAuthenticationReasonText": "Authenticate to enable biometric authentication", - "appSettingsDisableBiometricAuthenticationReasonText": "Authenticate to disable biometric authentication", - "errorMessageBulkActionFailed": "Could not bulk edit documents.", - "errorMessageBiotmetricsNotSupported": "Biometric authentication not supported on this device.", - "errorMessageBiometricAuthenticationFailed": "Biometric authentication failed.", - "errorMessageDeviceOffline": "Could not fetch data: You are not connected to the internet.", - "errorMessageServerUnreachable": "Could not reach your Paperless server, is it up and running?", - "aboutDialogDevelopedByText": "Developed by", - "documentsPageBulkDeleteSuccessfulText": "Documents successfully deleted.", - "documentDeleteSuccessMessage": "Document successfully deleted.", - "documentsSelectedText": "selected", - "labelsPageCorrespondentsTitleText": "Correspondents", - "labelsPageDocumentTypesTitleText": "Document Types", - "labelsPageTagsTitleText": "Tags", - "tagColorPropertyLabel": "Color", - "tagInboxTagPropertyLabel": "Inbox-Tag", - "documentScannerPageEmptyStateText": "No documents scanned yet.", - "documentScannerPageTitle": "Scan", - "documentScannerPageResetButtonTooltipText": "Delete all scans", - "documentScannerPageUploadButtonTooltip": "Upload to Paperless", - "documentScannerPageAddScanButtonLabel": "Scan a document", - "documentScannerPageOrText": "or", - "documentScannerPageUploadFromThisDeviceButtonLabel": "Upload a document from this device", - "addTagPageTitle": "New Tag", - "addCorrespondentPageTitle": "New Correspondent", - "addDocumentTypePageTitle": "New Document Type", - "labelNamePropertyLabel": "Name", - "labelMatchPropertyLabel": "Match", - "labelMatchingAlgorithmPropertyLabel": "Matching Algorithm", - "labelIsInsensivitePropertyLabel": "Case Irrelevant", - "linkedDocumentsPageTitle": "Linked Documents", - "documentsUploadPageTitle": "Prepare document", - "documentUploadFileNameLabel": "File Name", - "documentUploadSuccessText": "Document successfully uploaded, processing...", - "documentUploadProcessingSuccessfulText": "Document successfully processed.", - "documentUploadProcessingSuccessfulReloadActionText": "Reload", - "labelNotAssignedText": "Not assigned", - "correspondentFormFieldSearchHintText": "Start typing...", - "documentTypeFormFieldSearchHintText": "Start typing...", - "tagFormFieldSearchHintText": "Filter tags...", - "documentsPageOrderByLabel": "Order By", - "documentDetailsPageAssignAsnButtonLabel": "Assign", - "documentMetaDataMediaFilenamePropertyLabel": "Media Filename", - "documentMetaDataChecksumLabel": "Original MD5-Checksum", - "documentMetaDataOriginalFileSizeLabel": "Original File Size", - "documentMetaDataOriginalMimeTypeLabel": "Original MIME-Type", - "loginPageClientCertificateSettingLabel": "Client Certificate", - "loginPageClientCertificateSettingDescriptionText": "Configure Mutual TLS Authentication", - "loginPageClientCertificateSettingInvalidFileFormatValidationText": "Invalid certificate format, only .pfx is allowed", - "loginPageClientCertificateSettingSelectFileText": "Select file...", - "uploadPageAutomaticallInferredFieldsHintText": "If you specify values for these fields, your paperless instance will not automatically derive a value. If you want these values to be automatically populated by your server, leave the fields blank.", - "settingsPageLanguageSettingLabel": "Language", - "settingsPageApplicationSettingsLabel": "Application", - "settingsPageSecuritySettingsLabel": "Security", - "appSettingsBiometricAuthenticationLabel": "Biometric authentication", - "settingsPageApplicationSettingsDescriptionText": "Language and visual appearance", - "settingsPageSecuritySettingsDescriptionText": "Biometric authentication", - "settingsPageAppearanceSettingTitle": "Appearance", - "settingsPageAppearanceSettingDescriptionText": "Choose your light or dark theme preference", - "settingsPageAppearanceSettingSystemThemeLabel": "Use system theme", - "settingsPageAppearanceSettingLightThemeLabel": "Light Theme", - "settingsPageAppearanceSettingDarkThemeLabel": "Dark Theme", - "appSettingsBiometricAuthenticationDescriptionText": "Authenticate on app start", - "settingsThemeModeSystemLabel": "System", - "settingsThemeModeLightLabel": "Light", - "settingsThemeModeDarkLabel": "Dark", - "genericMessageOfflineText": "You're offline. Check your connection.", - "documentDetailsPageSimilarDocumentsLabel": "Similar Documents", - "offlineWidgetText": "An internet connection could not be established.", - "labelsPageStoragePathTitleText": "Storage Paths", - "addStoragePathPageTitle": "New Storage Path", - "savedViewCreateNewLabel": "New View", - "savedViewNameLabel": "Name", - "savedViewShowOnDashboardLabel": "Show on dashboard", - "savedViewShowInSidebarLabel": "Show in sidebar", - "savedViewsLabel": "Saved Views", - "savedViewsEmptyStateText": "Create views to quickly filter your documents.", - "savedViewCreateTooltipText": "Creates a new view based on the current filter criteria.", - "documentsFilterPageSearchLabel": "Search", - "documentEditPageTitle": "Edit Document", - "storagePathParameterDayLabel": "day", - "storagePathParameterYearLabel": "year", - "storagePathParameterMonthLabel": "month", - "errorMessageSimilarQueryError": "Could not load similar documents.", - "errorMessageAutocompleteQueryError": "An error ocurred while trying to autocomplete your query.", - "errorMessageStoragePathLoadFailed": "Could not load storage paths.", - "errorMessageStoragePathCreateFailed": "Could not create storage path, please try again.", - "errorMessageLoadSavedViewsError": "Could not load saved views.", - "errorMessageCreateSavedViewError": "Could not create saved view, please try again.", - "errorMessageDeleteSavedViewError": "Could not delete saved view, please try again", - "errorMessageRequestTimedOut": "The request to the server timed out.", - "errorMessageUnsupportedFileFormat": "This file format is not supported.", - "labelFormFieldNoItemsFoundText": "No items found!", - "onboardingDoneButtonLabel": "Done", - "onboardingNextButtonLabel": "Next", - "labelsPageCorrespondentEmptyStateAddNewLabel": "Add new correspondent", - "labelsPageCorrespondentEmptyStateDescriptionText": "You don't seem to have any correspondents set up.", - "labelsPageDocumentTypeEmptyStateAddNewLabel": "Add new document type", - "labelsPageDocumentTypeEmptyStateDescriptionText": "You don't seem to have any document types set up.", - "labelsPageTagsEmptyStateAddNewLabel": "Add new tag", - "labelsPageTagsEmptyStateDescriptionText": "You don't seem to have any tags set up.", - "labelsPageStoragePathEmptyStateAddNewLabel": "Add new storage path", - "labelsPageStoragePathEmptyStateDescriptionText": "You don't seem to have any storage paths set up.", - "referencedDocumentsReadOnlyHintText": "This is a read-only view! You cannot edit or remove documents. A maximum of 100 referenced documents will be loaded.", - "editLabelPageConfirmDeletionDialogTitle": "Confirm deletion", - "editLabelPageDeletionDialogText": "This label contains references to other documents. By deleting this label, all references will be removed. Continue?", - "settingsPageStorageSettingsLabel": "Storage", - "settingsPageStorageSettingsDescriptionText": "Manage files and storage space", - "documentUpdateSuccessMessage": "Document successfully updated.", - "errorMessageMissingClientCertificate": "A client certificate was expected but not sent. Please provide a valid client certificate.", - "serverInformationPaperlessVersionText": "Paperless server version", - "errorReportLabel": "REPORT", - "appDrawerHeaderLoggedInAsText": "Logged in as ", - "labelAnyAssignedText": "Any assigned", - "deleteViewDialogContentText": "Do you really want to delete this view?", - "deleteViewDialogTitleText": "Delete view ", - "documentUploadPageSynchronizeTitleAndFilenameLabel": "Synchronize title and filename", - "bottomNavInboxPageLabel": "Inbox" -} \ No newline at end of file + "@@locale": "en", + "aboutDialogDevelopedByText": "Developed by", + "@aboutDialogDevelopedByText": {}, + "addCorrespondentPageTitle": "New Correspondent", + "@addCorrespondentPageTitle": {}, + "addDocumentTypePageTitle": "New Document Type", + "@addDocumentTypePageTitle": {}, + "addStoragePathPageTitle": "New Storage Path", + "@addStoragePathPageTitle": {}, + "addTagPageTitle": "New Tag", + "@addTagPageTitle": {}, + "appDrawerAboutInfoLoadingText": "Retrieving application information...", + "@appDrawerAboutInfoLoadingText": {}, + "appDrawerAboutLabel": "About this app", + "@appDrawerAboutLabel": {}, + "appDrawerHeaderLoggedInAsText": "Logged in as ", + "@appDrawerHeaderLoggedInAsText": {}, + "appDrawerLogoutLabel": "Disconnect", + "@appDrawerLogoutLabel": {}, + "appDrawerReportBugLabel": "Report a Bug", + "@appDrawerReportBugLabel": {}, + "appDrawerSettingsLabel": "Settings", + "@appDrawerSettingsLabel": {}, + "appSettingsBiometricAuthenticationDescriptionText": "Authenticate on app start", + "@appSettingsBiometricAuthenticationDescriptionText": {}, + "appSettingsBiometricAuthenticationLabel": "Biometric authentication", + "@appSettingsBiometricAuthenticationLabel": {}, + "appSettingsDisableBiometricAuthenticationReasonText": "Authenticate to disable biometric authentication", + "@appSettingsDisableBiometricAuthenticationReasonText": {}, + "appSettingsEnableBiometricAuthenticationReasonText": "Authenticate to enable biometric authentication", + "@appSettingsEnableBiometricAuthenticationReasonText": {}, + "appTitleText": "Paperless Mobile", + "@appTitleText": {}, + "bottomNavDocumentsPageLabel": "Documents", + "@bottomNavDocumentsPageLabel": {}, + "bottomNavInboxPageLabel": "Inbox", + "@bottomNavInboxPageLabel": {}, + "bottomNavLabelsPageLabel": "Labels", + "@bottomNavLabelsPageLabel": {}, + "bottomNavScannerPageLabel": "Scanner", + "@bottomNavScannerPageLabel": {}, + "correspondentFormFieldSearchHintText": "Start typing...", + "@correspondentFormFieldSearchHintText": {}, + "deleteViewDialogContentText": "Do you really want to delete this view?", + "@deleteViewDialogContentText": {}, + "deleteViewDialogTitleText": "Delete view ", + "@deleteViewDialogTitleText": {}, + "documentAddedPropertyLabel": "Added At", + "@documentAddedPropertyLabel": {}, + "documentArchiveSerialNumberPropertyLongLabel": "Archive Serial Number", + "@documentArchiveSerialNumberPropertyLongLabel": {}, + "documentArchiveSerialNumberPropertyShortLabel": "ASN", + "@documentArchiveSerialNumberPropertyShortLabel": {}, + "documentCorrespondentPropertyLabel": "Correspondent", + "@documentCorrespondentPropertyLabel": {}, + "documentCreatedPropertyLabel": "Created At", + "@documentCreatedPropertyLabel": {}, + "documentDeleteSuccessMessage": "Document successfully deleted.", + "@documentDeleteSuccessMessage": {}, + "documentDetailsPageAssignAsnButtonLabel": "Assign", + "@documentDetailsPageAssignAsnButtonLabel": {}, + "documentDetailsPageSimilarDocumentsLabel": "Similar Documents", + "@documentDetailsPageSimilarDocumentsLabel": {}, + "documentDetailsPageTabContentLabel": "Content", + "@documentDetailsPageTabContentLabel": {}, + "documentDetailsPageTabMetaDataLabel": "Meta Data", + "@documentDetailsPageTabMetaDataLabel": {}, + "documentDetailsPageTabOverviewLabel": "Overview", + "@documentDetailsPageTabOverviewLabel": {}, + "documentDocumentTypePropertyLabel": "Document Type", + "@documentDocumentTypePropertyLabel": {}, + "documentEditPageTitle": "Edit Document", + "@documentEditPageTitle": {}, + "documentMetaDataChecksumLabel": "Original MD5-Checksum", + "@documentMetaDataChecksumLabel": {}, + "documentMetaDataMediaFilenamePropertyLabel": "Media Filename", + "@documentMetaDataMediaFilenamePropertyLabel": {}, + "documentMetaDataOriginalFileSizeLabel": "Original File Size", + "@documentMetaDataOriginalFileSizeLabel": {}, + "documentMetaDataOriginalMimeTypeLabel": "Original MIME-Type", + "@documentMetaDataOriginalMimeTypeLabel": {}, + "documentModifiedPropertyLabel": "Modified At", + "@documentModifiedPropertyLabel": {}, + "documentPreviewPageTitle": "Preview", + "@documentPreviewPageTitle": {}, + "documentScannerPageAddScanButtonLabel": "Scan a document", + "@documentScannerPageAddScanButtonLabel": {}, + "documentScannerPageEmptyStateText": "No documents scanned yet.", + "@documentScannerPageEmptyStateText": {}, + "documentScannerPageOrText": "or", + "@documentScannerPageOrText": {}, + "documentScannerPageResetButtonTooltipText": "Delete all scans", + "@documentScannerPageResetButtonTooltipText": {}, + "documentScannerPageTitle": "Scan", + "@documentScannerPageTitle": {}, + "documentScannerPageUploadButtonTooltip": "Upload to Paperless", + "@documentScannerPageUploadButtonTooltip": {}, + "documentScannerPageUploadFromThisDeviceButtonLabel": "Upload a document from this device", + "@documentScannerPageUploadFromThisDeviceButtonLabel": {}, + "documentsFilterPageAdvancedLabel": "Advanced", + "@documentsFilterPageAdvancedLabel": {}, + "documentsFilterPageApplyFilterLabel": "Apply", + "@documentsFilterPageApplyFilterLabel": {}, + "documentsFilterPageDateRangeFieldEndLabel": "To", + "@documentsFilterPageDateRangeFieldEndLabel": {}, + "documentsFilterPageDateRangeFieldStartLabel": "From", + "@documentsFilterPageDateRangeFieldStartLabel": {}, + "documentsFilterPageDateRangeLastMonthLabel": "Last Month", + "@documentsFilterPageDateRangeLastMonthLabel": {}, + "documentsFilterPageDateRangeLastSevenDaysLabel": "Last 7 Days", + "@documentsFilterPageDateRangeLastSevenDaysLabel": {}, + "documentsFilterPageDateRangeLastThreeMonthsLabel": "Last 3 Months", + "@documentsFilterPageDateRangeLastThreeMonthsLabel": {}, + "documentsFilterPageDateRangeLastYearLabel": "Last Year", + "@documentsFilterPageDateRangeLastYearLabel": {}, + "documentsFilterPageQueryOptionsAsnLabel": "ASN", + "@documentsFilterPageQueryOptionsAsnLabel": {}, + "documentsFilterPageQueryOptionsExtendedLabel": "Extended", + "@documentsFilterPageQueryOptionsExtendedLabel": {}, + "documentsFilterPageQueryOptionsTitleAndContentLabel": "Title & Content", + "@documentsFilterPageQueryOptionsTitleAndContentLabel": {}, + "documentsFilterPageQueryOptionsTitleLabel": "Title", + "@documentsFilterPageQueryOptionsTitleLabel": {}, + "documentsFilterPageResetFilterLabel": "Reset", + "@documentsFilterPageResetFilterLabel": {}, + "documentsFilterPageSearchLabel": "Search", + "@documentsFilterPageSearchLabel": {}, + "documentsFilterPageTitle": "Filter Documents", + "@documentsFilterPageTitle": {}, + "documentsPageBulkDeleteSuccessfulText": "Documents successfully deleted.", + "@documentsPageBulkDeleteSuccessfulText": {}, + "documentsPageEmptyStateNothingHereText": "There seems to be nothing here...", + "@documentsPageEmptyStateNothingHereText": {}, + "documentsPageEmptyStateOopsText": "Oops.", + "@documentsPageEmptyStateOopsText": {}, + "documentsPageOrderByLabel": "Order By", + "@documentsPageOrderByLabel": {}, + "documentsPageSelectionBulkDeleteDialogContinueText": "This action is irreversible. Do you wish to proceed anyway?", + "@documentsPageSelectionBulkDeleteDialogContinueText": {}, + "documentsPageSelectionBulkDeleteDialogTitle": "Confirm deletion", + "@documentsPageSelectionBulkDeleteDialogTitle": {}, + "documentsPageSelectionBulkDeleteDialogWarningTextMany": "Are you sure you want to delete the following documents?", + "@documentsPageSelectionBulkDeleteDialogWarningTextMany": {}, + "documentsPageSelectionBulkDeleteDialogWarningTextOne": "Are you sure you want to delete the following document?", + "@documentsPageSelectionBulkDeleteDialogWarningTextOne": {}, + "documentsPageTitle": "Documents", + "@documentsPageTitle": {}, + "documentsSelectedText": "selected", + "@documentsSelectedText": {}, + "documentStoragePathPropertyLabel": "Storage Path", + "@documentStoragePathPropertyLabel": {}, + "documentsUploadPageTitle": "Prepare document", + "@documentsUploadPageTitle": {}, + "documentTagsPropertyLabel": "Tags", + "@documentTagsPropertyLabel": {}, + "documentTitlePropertyLabel": "Title", + "@documentTitlePropertyLabel": {}, + "documentTypeFormFieldSearchHintText": "Start typing...", + "@documentTypeFormFieldSearchHintText": {}, + "documentUpdateSuccessMessage": "Document successfully updated.", + "@documentUpdateSuccessMessage": {}, + "documentUploadFileNameLabel": "File Name", + "@documentUploadFileNameLabel": {}, + "documentUploadPageSynchronizeTitleAndFilenameLabel": "Synchronize title and filename", + "@documentUploadPageSynchronizeTitleAndFilenameLabel": {}, + "documentUploadProcessingSuccessfulReloadActionText": "Reload", + "@documentUploadProcessingSuccessfulReloadActionText": {}, + "documentUploadProcessingSuccessfulText": "Document successfully processed.", + "@documentUploadProcessingSuccessfulText": {}, + "documentUploadSuccessText": "Document successfully uploaded, processing...", + "@documentUploadSuccessText": {}, + "editLabelPageConfirmDeletionDialogTitle": "Confirm deletion", + "@editLabelPageConfirmDeletionDialogTitle": {}, + "editLabelPageDeletionDialogText": "This label contains references to other documents. By deleting this label, all references will be removed. Continue?", + "@editLabelPageDeletionDialogText": {}, + "errorMessageAuthenticationFailed": "Authentication failed, please try again.", + "@errorMessageAuthenticationFailed": {}, + "errorMessageAutocompleteQueryError": "An error ocurred while trying to autocomplete your query.", + "@errorMessageAutocompleteQueryError": {}, + "errorMessageBiometricAuthenticationFailed": "Biometric authentication failed.", + "@errorMessageBiometricAuthenticationFailed": {}, + "errorMessageBiotmetricsNotSupported": "Biometric authentication not supported on this device.", + "@errorMessageBiotmetricsNotSupported": {}, + "errorMessageBulkActionFailed": "Could not bulk edit documents.", + "@errorMessageBulkActionFailed": {}, + "errorMessageCorrespondentCreateFailed": "Could not create correspondent, please try again.", + "@errorMessageCorrespondentCreateFailed": {}, + "errorMessageCorrespondentLoadFailed": "Could not load correspondents.", + "@errorMessageCorrespondentLoadFailed": {}, + "errorMessageCreateSavedViewError": "Could not create saved view, please try again.", + "@errorMessageCreateSavedViewError": {}, + "errorMessageDeleteSavedViewError": "Could not delete saved view, please try again", + "@errorMessageDeleteSavedViewError": {}, + "errorMessageDeviceOffline": "Could not fetch data: You are not connected to the internet.", + "@errorMessageDeviceOffline": {}, + "errorMessageDocumentAsnQueryFailed": "Could not assign archive serial number.", + "@errorMessageDocumentAsnQueryFailed": {}, + "errorMessageDocumentDeleteFailed": "Could not delete document, please try again.", + "@errorMessageDocumentDeleteFailed": {}, + "errorMessageDocumentLoadFailed": "Could not load documents, please try again.", + "@errorMessageDocumentLoadFailed": {}, + "errorMessageDocumentPreviewFailed": "Could not load document preview.", + "@errorMessageDocumentPreviewFailed": {}, + "errorMessageDocumentTypeCreateFailed": "Could not create document, please try again.", + "@errorMessageDocumentTypeCreateFailed": {}, + "errorMessageDocumentTypeLoadFailed": "Could not load document types, please try again.", + "@errorMessageDocumentTypeLoadFailed": {}, + "errorMessageDocumentUpdateFailed": "Could not update document, please try again.", + "@errorMessageDocumentUpdateFailed": {}, + "errorMessageDocumentUploadFailed": "Could not upload document, please try again.", + "@errorMessageDocumentUploadFailed": {}, + "errorMessageInvalidClientCertificateConfiguration": "Invalid certificate or missing passphrase, please try again", + "@errorMessageInvalidClientCertificateConfiguration": {}, + "errorMessageLoadSavedViewsError": "Could not load saved views.", + "@errorMessageLoadSavedViewsError": {}, + "errorMessageMissingClientCertificate": "A client certificate was expected but not sent. Please provide a valid client certificate.", + "@errorMessageMissingClientCertificate": {}, + "errorMessageNotAuthenticated": "User is not authenticated.", + "@errorMessageNotAuthenticated": {}, + "errorMessageRequestTimedOut": "The request to the server timed out.", + "@errorMessageRequestTimedOut": {}, + "errorMessageScanRemoveFailed": "An error occurred removing the scans.", + "@errorMessageScanRemoveFailed": {}, + "errorMessageServerUnreachable": "Could not reach your Paperless server, is it up and running?", + "@errorMessageServerUnreachable": {}, + "errorMessageSimilarQueryError": "Could not load similar documents.", + "@errorMessageSimilarQueryError": {}, + "errorMessageStoragePathCreateFailed": "Could not create storage path, please try again.", + "@errorMessageStoragePathCreateFailed": {}, + "errorMessageStoragePathLoadFailed": "Could not load storage paths.", + "@errorMessageStoragePathLoadFailed": {}, + "errorMessageTagCreateFailed": "Could not create tag, please try again.", + "@errorMessageTagCreateFailed": {}, + "errorMessageTagLoadFailed": "Could not load tags.", + "@errorMessageTagLoadFailed": {}, + "errorMessageUnknonwnError": "An unknown error occurred.", + "@errorMessageUnknonwnError": {}, + "errorMessageUnsupportedFileFormat": "This file format is not supported.", + "@errorMessageUnsupportedFileFormat": {}, + "errorReportLabel": "REPORT", + "@errorReportLabel": {}, + "genericActionCancelLabel": "Cancel", + "@genericActionCancelLabel": {}, + "genericActionCreateLabel": "Create", + "@genericActionCreateLabel": {}, + "genericActionDeleteLabel": "Delete", + "@genericActionDeleteLabel": {}, + "genericActionEditLabel": "Edit", + "@genericActionEditLabel": {}, + "genericActionOkLabel": "Ok", + "@genericActionOkLabel": {}, + "genericActionSaveLabel": "Save", + "@genericActionSaveLabel": {}, + "genericActionSelectText": "Select", + "@genericActionSelectText": {}, + "genericActionUpdateLabel": "Update", + "@genericActionUpdateLabel": {}, + "genericActionUploadLabel": "Upload", + "@genericActionUploadLabel": {}, + "genericMessageOfflineText": "You're offline. Check your connection.", + "@genericMessageOfflineText": {}, + "inboxPageDocumentRemovedMessageText": "Document removed from inbox.", + "@inboxPageDocumentRemovedMessageText": {}, + "inboxPageMarkAllAsSeenConfirmationDialogText": "Are you sure you want to mark all documents as seen? This will perform a bulk edit operation removing all inbox tags from the documents.\nThis action is not reversible! Are you sure you want to continue?", + "@inboxPageMarkAllAsSeenConfirmationDialogText": {}, + "inboxPageMarkAllAsSeenConfirmationDialogTitleText": "Mark all as seen?", + "@inboxPageMarkAllAsSeenConfirmationDialogTitleText": {}, + "inboxPageMarkAllAsSeenLabel": "Mark all as seen", + "@inboxPageMarkAllAsSeenLabel": {}, + "inboxPageMarkAsSeenText": "Mark as seen", + "@inboxPageMarkAsSeenText": {}, + "inboxPageTodayText": "Today", + "@inboxPageTodayText": {}, + "inboxPageUndoRemoveText": "UNDO", + "@inboxPageUndoRemoveText": {}, + "inboxPageUnseenText": "unseen", + "@inboxPageUnseenText": {}, + "inboxPageUsageHintText": "Hint: Swipe left to mark a document as seen and remove all inbox tags from the document.", + "@inboxPageUsageHintText": {}, + "inboxPageYesterdayText": "Yesterday", + "@inboxPageYesterdayText": {}, + "labelAnyAssignedText": "Any assigned", + "@labelAnyAssignedText": {}, + "labelFormFieldNoItemsFoundText": "No items found!", + "@labelFormFieldNoItemsFoundText": {}, + "labelIsInsensivitePropertyLabel": "Case Irrelevant", + "@labelIsInsensivitePropertyLabel": {}, + "labelMatchingAlgorithmPropertyLabel": "Matching Algorithm", + "@labelMatchingAlgorithmPropertyLabel": {}, + "labelMatchPropertyLabel": "Match", + "@labelMatchPropertyLabel": {}, + "labelNamePropertyLabel": "Name", + "@labelNamePropertyLabel": {}, + "labelNotAssignedText": "Not assigned", + "@labelNotAssignedText": {}, + "labelsPageCorrespondentEmptyStateAddNewLabel": "Add new correspondent", + "@labelsPageCorrespondentEmptyStateAddNewLabel": {}, + "labelsPageCorrespondentEmptyStateDescriptionText": "You don't seem to have any correspondents set up.", + "@labelsPageCorrespondentEmptyStateDescriptionText": {}, + "labelsPageCorrespondentsTitleText": "Correspondents", + "@labelsPageCorrespondentsTitleText": {}, + "labelsPageDocumentTypeEmptyStateAddNewLabel": "Add new document type", + "@labelsPageDocumentTypeEmptyStateAddNewLabel": {}, + "labelsPageDocumentTypeEmptyStateDescriptionText": "You don't seem to have any document types set up.", + "@labelsPageDocumentTypeEmptyStateDescriptionText": {}, + "labelsPageDocumentTypesTitleText": "Document Types", + "@labelsPageDocumentTypesTitleText": {}, + "labelsPageStoragePathEmptyStateAddNewLabel": "Add new storage path", + "@labelsPageStoragePathEmptyStateAddNewLabel": {}, + "labelsPageStoragePathEmptyStateDescriptionText": "You don't seem to have any storage paths set up.", + "@labelsPageStoragePathEmptyStateDescriptionText": {}, + "labelsPageStoragePathTitleText": "Storage Paths", + "@labelsPageStoragePathTitleText": {}, + "labelsPageTagsEmptyStateAddNewLabel": "Add new tag", + "@labelsPageTagsEmptyStateAddNewLabel": {}, + "labelsPageTagsEmptyStateDescriptionText": "You don't seem to have any tags set up.", + "@labelsPageTagsEmptyStateDescriptionText": {}, + "labelsPageTagsTitleText": "Tags", + "@labelsPageTagsTitleText": {}, + "linkedDocumentsPageTitle": "Linked Documents", + "@linkedDocumentsPageTitle": {}, + "loginPageAdvancedLabel": "Advanced Settings", + "@loginPageAdvancedLabel": {}, + "loginPageClientCertificatePassphraseLabel": "Passphrase", + "@loginPageClientCertificatePassphraseLabel": {}, + "loginPageClientCertificateSettingDescriptionText": "Configure Mutual TLS Authentication", + "@loginPageClientCertificateSettingDescriptionText": {}, + "loginPageClientCertificateSettingInvalidFileFormatValidationText": "Invalid certificate format, only .pfx is allowed", + "@loginPageClientCertificateSettingInvalidFileFormatValidationText": {}, + "loginPageClientCertificateSettingLabel": "Client Certificate", + "@loginPageClientCertificateSettingLabel": {}, + "loginPageClientCertificateSettingSelectFileText": "Select file...", + "@loginPageClientCertificateSettingSelectFileText": {}, + "loginPageIncorrectOrMissingCertificatePassphraseErrorMessageText": "Incorrect or missing certificate passphrase.", + "@loginPageIncorrectOrMissingCertificatePassphraseErrorMessageText": {}, + "loginPageLoginButtonLabel": "Connect", + "@loginPageLoginButtonLabel": {}, + "loginPagePasswordFieldLabel": "Password", + "@loginPagePasswordFieldLabel": {}, + "loginPagePasswordValidatorMessageText": "Password must not be empty.", + "@loginPagePasswordValidatorMessageText": {}, + "loginPageServerUrlFieldLabel": "Server Address", + "@loginPageServerUrlFieldLabel": {}, + "loginPageServerUrlValidatorMessageText": "Server address must not be empty.", + "@loginPageServerUrlValidatorMessageText": {}, + "loginPageTitle": "Connect to Paperless", + "@loginPageTitle": {}, + "loginPageUsernameLabel": "Username", + "@loginPageUsernameLabel": {}, + "loginPageUsernameValidatorMessageText": "Username must not be empty.", + "@loginPageUsernameValidatorMessageText": {}, + "offlineWidgetText": "An internet connection could not be established.", + "@offlineWidgetText": {}, + "onboardingDoneButtonLabel": "Done", + "@onboardingDoneButtonLabel": {}, + "onboardingNextButtonLabel": "Next", + "@onboardingNextButtonLabel": {}, + "referencedDocumentsReadOnlyHintText": "This is a read-only view! You cannot edit or remove documents. A maximum of 100 referenced documents will be loaded.", + "@referencedDocumentsReadOnlyHintText": {}, + "savedViewCreateNewLabel": "New View", + "@savedViewCreateNewLabel": {}, + "savedViewCreateTooltipText": "Creates a new view based on the current filter criteria.", + "@savedViewCreateTooltipText": {}, + "savedViewNameLabel": "Name", + "@savedViewNameLabel": {}, + "savedViewsEmptyStateText": "Create views to quickly filter your documents.", + "@savedViewsEmptyStateText": {}, + "savedViewShowInSidebarLabel": "Show in sidebar", + "@savedViewShowInSidebarLabel": {}, + "savedViewShowOnDashboardLabel": "Show on dashboard", + "@savedViewShowOnDashboardLabel": {}, + "savedViewsLabel": "Saved Views", + "@savedViewsLabel": {}, + "serverInformationPaperlessVersionText": "Paperless server version", + "@serverInformationPaperlessVersionText": {}, + "settingsPageAppearanceSettingDarkThemeLabel": "Dark Theme", + "@settingsPageAppearanceSettingDarkThemeLabel": {}, + "settingsPageAppearanceSettingLightThemeLabel": "Light Theme", + "@settingsPageAppearanceSettingLightThemeLabel": {}, + "settingsPageAppearanceSettingSystemThemeLabel": "Use system theme", + "@settingsPageAppearanceSettingSystemThemeLabel": {}, + "settingsPageAppearanceSettingTitle": "Appearance", + "@settingsPageAppearanceSettingTitle": {}, + "settingsPageApplicationSettingsDescriptionText": "Language and visual appearance", + "@settingsPageApplicationSettingsDescriptionText": {}, + "settingsPageApplicationSettingsLabel": "Application", + "@settingsPageApplicationSettingsLabel": {}, + "settingsPageLanguageSettingLabel": "Language", + "@settingsPageLanguageSettingLabel": {}, + "settingsPageSecuritySettingsDescriptionText": "Biometric authentication", + "@settingsPageSecuritySettingsDescriptionText": {}, + "settingsPageSecuritySettingsLabel": "Security", + "@settingsPageSecuritySettingsLabel": {}, + "settingsPageStorageSettingsDescriptionText": "Manage files and storage space", + "@settingsPageStorageSettingsDescriptionText": {}, + "settingsPageStorageSettingsLabel": "Storage", + "@settingsPageStorageSettingsLabel": {}, + "settingsThemeModeDarkLabel": "Dark", + "@settingsThemeModeDarkLabel": {}, + "settingsThemeModeLightLabel": "Light", + "@settingsThemeModeLightLabel": {}, + "settingsThemeModeSystemLabel": "System", + "@settingsThemeModeSystemLabel": {}, + "storagePathParameterDayLabel": "day", + "@storagePathParameterDayLabel": {}, + "storagePathParameterMonthLabel": "month", + "@storagePathParameterMonthLabel": {}, + "storagePathParameterYearLabel": "year", + "@storagePathParameterYearLabel": {}, + "tagColorPropertyLabel": "Color", + "@tagColorPropertyLabel": {}, + "tagFormFieldSearchHintText": "Filter tags...", + "@tagFormFieldSearchHintText": {}, + "tagInboxTagPropertyLabel": "Inbox-Tag", + "@tagInboxTagPropertyLabel": {}, + "uploadPageAutomaticallInferredFieldsHintText": "If you specify values for these fields, your paperless instance will not automatically derive a value. If you want these values to be automatically populated by your server, leave the fields blank.", + "@uploadPageAutomaticallInferredFieldsHintText": {} + } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 00e05afd..e46c2b54 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -11,6 +11,7 @@ import 'package:form_builder_validators/form_builder_validators.dart'; import 'package:intl/intl.dart'; import 'package:intl/intl_standalone.dart'; import 'package:package_info_plus/package_info_plus.dart'; +import 'package:paperless_mobile/core/bloc/bloc_changes_observer.dart'; import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart'; import 'package:paperless_mobile/features/labels/bloc/global_state_bloc_provider.dart'; import 'package:paperless_mobile/core/bloc/paperless_server_information_cubit.dart'; @@ -35,6 +36,7 @@ import 'package:paperless_mobile/util.dart'; import 'package:receive_sharing_intent/receive_sharing_intent.dart'; void main() async { + Bloc.observer = BlocChangesObserver(); final widgetsBinding = WidgetsFlutterBinding.ensureInitialized(); FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding); Intl.systemLocale = await findSystemLocale(); diff --git a/lib/util.dart b/lib/util.dart index dee43e67..0adda711 100644 --- a/lib/util.dart +++ b/lib/util.dart @@ -102,25 +102,6 @@ String? formatDateNullable(DateTime? date) { return dateFormat.format(date); } -Future writeToFile(Uint8List data) async { - Directory tempDir = await getTemporaryDirectory(); - String tempPath = tempDir.path; - var filePath = - tempPath + '/file_01.tmp'; // file_01.tmp is dump file, can be anything - return (await File(filePath).writeAsBytes(data)).path; -} - -void setKeyNullable(Map data, String key, dynamic value) { - if (value != null) { - data[key] = value is String ? value : json.encode(value); - } -} - -String formatLocalDate(BuildContext context, DateTime dateTime) { - final tag = Localizations.maybeLocaleOf(context)?.toLanguageTag(); - return DateFormat.yMMMd(tag).format(dateTime); -} - String extractFilenameFromPath(String path) { return path.split(RegExp('[./]')).reversed.skip(1).first; } diff --git a/pubspec.lock b/pubspec.lock index aeb2c31b..0b05d1c4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -43,13 +43,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.9.0" - badges: - dependency: "direct main" - description: - name: badges - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.3" barcode: dependency: transitive description: @@ -450,7 +443,7 @@ packages: source: hosted version: "3.3.0" flutter_chips_input: - dependency: "direct main" + dependency: transitive description: name: flutter_chips_input url: "https://pub.dartlang.org" diff --git a/pubspec.yaml b/pubspec.yaml index d020f8b4..e1916795 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.1.0+5 +version: 1.2.0+6 environment: sdk: ">=2.17.0 <3.0.0" @@ -64,11 +64,9 @@ dependencies: ref: main form_builder_validators: ^8.3.0 infinite_scroll_pagination: ^3.2.0 - flutter_chips_input: ^2.0.0 sliding_up_panel: ^2.0.0+1 package_info_plus: ^1.4.3+1 font_awesome_flutter: ^10.1.0 - badges: ^2.0.3 local_auth: ^2.1.2 connectivity_plus: ^2.3.9 @@ -138,6 +136,7 @@ flutter: # see https://flutter.dev/custom-fonts/#from-packages flutter_intl: enabled: true + main_locale: en localizely: project_id: 84b4144d-a628-4ba6-a8d0-4f9917444057