diff --git a/android/app/build.gradle b/android/app/build.gradle index 20e446a..b41fb77 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -72,6 +72,10 @@ android { release { signingConfig signingConfigs.release } + + debug { + applicationIdSuffix ".debug" + } } } diff --git a/lib/core/config/hive/custom_adapters/theme_mode_adapter.dart b/lib/core/database/hive/custom_adapters/theme_mode_adapter.dart similarity index 93% rename from lib/core/config/hive/custom_adapters/theme_mode_adapter.dart rename to lib/core/database/hive/custom_adapters/theme_mode_adapter.dart index 204ad18..d708426 100644 --- a/lib/core/config/hive/custom_adapters/theme_mode_adapter.dart +++ b/lib/core/database/hive/custom_adapters/theme_mode_adapter.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:hive_flutter/adapters.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; class ThemeModeAdapter extends TypeAdapter { @override diff --git a/lib/core/config/hive/hive_config.dart b/lib/core/database/hive/hive_config.dart similarity index 96% rename from lib/core/config/hive/hive_config.dart rename to lib/core/database/hive/hive_config.dart index 64f5a31..38eb172 100644 --- a/lib/core/config/hive/hive_config.dart +++ b/lib/core/database/hive/hive_config.dart @@ -1,6 +1,6 @@ import 'package:hive_flutter/adapters.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/config/hive/custom_adapters/theme_mode_adapter.dart'; +import 'package:paperless_mobile/core/database/hive/custom_adapters/theme_mode_adapter.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart'; import 'package:paperless_mobile/core/database/tables/user_credentials.dart'; diff --git a/lib/core/config/hive/hive_extensions.dart b/lib/core/database/hive/hive_extensions.dart similarity index 96% rename from lib/core/config/hive/hive_extensions.dart rename to lib/core/database/hive/hive_extensions.dart index c519dcd..6288eac 100644 --- a/lib/core/config/hive/hive_extensions.dart +++ b/lib/core/database/hive/hive_extensions.dart @@ -4,7 +4,7 @@ import 'dart:typed_data'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:hive_flutter/adapters.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart'; diff --git a/lib/core/database/tables/global_settings.dart b/lib/core/database/tables/global_settings.dart index fdcccbc..fbaf73b 100644 --- a/lib/core/database/tables/global_settings.dart +++ b/lib/core/database/tables/global_settings.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/features/settings/model/color_scheme_option.dart'; import 'package:paperless_mobile/features/settings/model/file_download_type.dart'; diff --git a/lib/core/database/tables/local_user_account.dart b/lib/core/database/tables/local_user_account.dart index d54d890..4b5e98d 100644 --- a/lib/core/database/tables/local_user_account.dart +++ b/lib/core/database/tables/local_user_account.dart @@ -1,6 +1,6 @@ import 'package:hive_flutter/adapters.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/local_user_settings.dart'; part 'local_user_account.g.dart'; diff --git a/lib/core/database/tables/local_user_app_state.dart b/lib/core/database/tables/local_user_app_state.dart index 49812e2..89f5360 100644 --- a/lib/core/database/tables/local_user_app_state.dart +++ b/lib/core/database/tables/local_user_app_state.dart @@ -1,6 +1,6 @@ import 'package:hive_flutter/adapters.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; import 'package:paperless_mobile/features/settings/model/view_type.dart'; diff --git a/lib/core/database/tables/local_user_settings.dart b/lib/core/database/tables/local_user_settings.dart index 4398e85..f495072 100644 --- a/lib/core/database/tables/local_user_settings.dart +++ b/lib/core/database/tables/local_user_settings.dart @@ -1,5 +1,5 @@ import 'package:hive/hive.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; part 'local_user_settings.g.dart'; diff --git a/lib/core/database/tables/user_credentials.dart b/lib/core/database/tables/user_credentials.dart index bd8ac77..61c95cd 100644 --- a/lib/core/database/tables/user_credentials.dart +++ b/lib/core/database/tables/user_credentials.dart @@ -1,5 +1,5 @@ import 'package:hive/hive.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/features/login/model/client_certificate.dart'; part 'user_credentials.g.dart'; diff --git a/lib/extensions/dart_extensions.dart b/lib/core/extensions/dart_extensions.dart similarity index 100% rename from lib/extensions/dart_extensions.dart rename to lib/core/extensions/dart_extensions.dart diff --git a/lib/core/extensions/document_iterable_extensions.dart b/lib/core/extensions/document_iterable_extensions.dart new file mode 100644 index 0000000..0bb9718 --- /dev/null +++ b/lib/core/extensions/document_iterable_extensions.dart @@ -0,0 +1,18 @@ +import 'package:collection/collection.dart'; +import 'package:paperless_api/paperless_api.dart'; + +extension DocumentModelIterableExtension on Iterable { + Iterable get ids => map((e) => e.id); + + Iterable withDocumentreplaced(DocumentModel document) { + return map((e) => e.id == document.id ? document : e); + } + + bool containsDocument(DocumentModel document) { + return ids.contains(document.id); + } + + Iterable withDocumentRemoved(DocumentModel document) { + return whereNot((element) => element.id == document.id); + } +} diff --git a/lib/extensions/flutter_extensions.dart b/lib/core/extensions/flutter_extensions.dart similarity index 100% rename from lib/extensions/flutter_extensions.dart rename to lib/core/extensions/flutter_extensions.dart diff --git a/lib/core/service/file_service.dart b/lib/core/service/file_service.dart index 83d0ebe..2dfa6a3 100644 --- a/lib/core/service/file_service.dart +++ b/lib/core/service/file_service.dart @@ -1,8 +1,8 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; -import 'package:paperless_mobile/core/logging/data/logger.dart'; -import 'package:paperless_mobile/core/logging/utils/redaction_utils.dart'; +import 'package:paperless_mobile/features/logging/data/logger.dart'; +import 'package:paperless_mobile/features/logging/utils/redaction_utils.dart'; import 'package:paperless_mobile/helpers/format_helpers.dart'; import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; @@ -231,9 +231,9 @@ class FileService { type: StorageDirectory.downloads, ); directory = await downloadsDir!.first.create(recursive: true); - return; } _downloadsDirectory = directory; + return; } else if (Platform.isIOS) { final appDir = await getApplicationDocumentsDirectory(); final dir = Directory('${appDir.path}/downloads'); diff --git a/lib/core/service/github_issue_service.dart b/lib/core/service/github_issue_service.dart index 7244704..853aab3 100644 --- a/lib/core/service/github_issue_service.dart +++ b/lib/core/service/github_issue_service.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.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'; -import 'package:paperless_mobile/extensions/dart_extensions.dart'; +import 'package:paperless_mobile/core/extensions/dart_extensions.dart'; class GithubIssueService { static void openCreateGithubIssue({ diff --git a/lib/core/widgets/error_report_page.dart b/lib/core/widgets/error_report_page.dart index ab0326b..34d344b 100644 --- a/lib/core/widgets/error_report_page.dart +++ b/lib/core/widgets/error_report_page.dart @@ -3,7 +3,7 @@ import 'package:flutter/services.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/dialog_utils/dialog_cancel_button.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; class ErrorReportPage extends StatefulWidget { final StackTrace? stackTrace; diff --git a/lib/core/widgets/form_builder_fields/extended_date_range_form_field/extended_date_range_dialog.dart b/lib/core/widgets/form_builder_fields/extended_date_range_form_field/extended_date_range_dialog.dart index aac24e4..f051cfa 100644 --- a/lib/core/widgets/form_builder_fields/extended_date_range_form_field/extended_date_range_dialog.dart +++ b/lib/core/widgets/form_builder_fields/extended_date_range_form_field/extended_date_range_dialog.dart @@ -3,7 +3,7 @@ import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:intl/intl.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/widgets/form_builder_fields/extended_date_range_form_field/form_builder_relative_date_range_field.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; class ExtendedDateRangeDialog extends StatefulWidget { diff --git a/lib/core/widgets/form_builder_fields/form_builder_localized_date_picker.dart b/lib/core/widgets/form_builder_fields/form_builder_localized_date_picker.dart new file mode 100644 index 0000000..369db47 --- /dev/null +++ b/lib/core/widgets/form_builder_fields/form_builder_localized_date_picker.dart @@ -0,0 +1,285 @@ +import 'dart:collection'; +import 'dart:math'; + +import 'package:collection/collection.dart'; +import 'package:extended_masked_text/extended_masked_text.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:intl/intl.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; +import 'package:synchronized/extension.dart'; + +final class NeighbourAwareDateInputSegmentControls + with LinkedListEntry { + final FocusNode node; + final TextEditingController controller; + final int position; + final String format; + final DateTime? initialDate; + + NeighbourAwareDateInputSegmentControls({ + required this.node, + required this.controller, + required this.format, + this.initialDate, + required this.position, + }); +} + +class FormBuilderLocalizedDatePicker extends StatefulWidget { + final String name; + final String labelText; + final Widget? prefixIcon; + final DateTime? initialValue; + final DateTime firstDate; + final DateTime lastDate; + final Locale locale; + + const FormBuilderLocalizedDatePicker({ + super.key, + required this.name, + this.initialValue, + required this.firstDate, + required this.lastDate, + required this.locale, + required this.labelText, + this.prefixIcon, + }); + + @override + State createState() => + _FormBuilderLocalizedDatePickerState(); +} + +class _FormBuilderLocalizedDatePickerState + extends State { + late final String _separator; + late final String _format; + + final _textFieldControls = + LinkedList(); + + @override + void initState() { + super.initState(); + final format = + DateFormat.yMd(widget.locale.toString()).format(DateTime(1000, 11, 22)); + _separator = format.replaceAll(RegExp(r'\d'), '').characters.first; + _format = format + .replaceAll("1000", "yyyy") + .replaceAll("11", "MM") + .replaceAll("22", "dd"); + + final components = _format.split(_separator); + for (int i = 0; i < components.length; i++) { + final formatString = components[i]; + final initialText = widget.initialValue != null + ? DateFormat(formatString).format(widget.initialValue!) + : null; + final item = NeighbourAwareDateInputSegmentControls( + node: FocusNode(debugLabel: formatString), + controller: TextEditingController(text: initialText), + format: formatString, + position: i, + ); + item.controller.addListener(() { + if (item.controller.text.length == item.format.length) { + // _textFieldControls.elementAt(i).next?.node.requestFocus(); + // _textFieldControls.elementAt(i).next?.controller.selection = + // const TextSelection.collapsed(offset: 0); + // return; + } + }); + item.node.addListener(() { + if (item.node.hasFocus) { + item.controller.selection = const TextSelection.collapsed(offset: 0); + } + }); + _textFieldControls.add(item); + } + } + + @override + Widget build(BuildContext context) { + return RawKeyboardListener( + focusNode: FocusNode(), + onKey: (value) { + if (value.logicalKey == LogicalKeyboardKey.backspace && + value is RawKeyDownEvent) { + final currentFocus = _textFieldControls + .where((element) => element.node.hasFocus) + .firstOrNull; + if (currentFocus == null) { + return; + } + if (currentFocus.controller.text.isEmpty) { + currentFocus.previous?.node.requestFocus(); + final endOffset = currentFocus.previous?.controller.text.length; + currentFocus.previous?.controller.selection = + TextSelection.collapsed(offset: endOffset ?? 0); + } + } + }, + child: FormBuilderField( + name: widget.name, + initialValue: widget.initialValue, + validator: (value) { + if (value?.isBefore(widget.firstDate) ?? false) { + return "Date must be before " + + DateFormat.yMd(widget.locale.toString()) + .format(widget.firstDate); + } + if (value?.isAfter(widget.lastDate) ?? false) { + return "Date must be after " + + DateFormat.yMd(widget.locale.toString()) + .format(widget.lastDate); + } + return null; + }, + builder: (field) { + return SizedBox( + height: 56, + child: InputDecorator( + textAlignVertical: TextAlignVertical.bottom, + decoration: InputDecoration( + labelText: widget.labelText, + prefixIcon: widget.prefixIcon, + suffixIcon: Row( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + icon: const Icon(Icons.calendar_month_outlined), + onPressed: () async { + final selectedDate = await showDatePicker( + context: context, + initialDate: widget.initialValue ?? DateTime.now(), + firstDate: widget.firstDate, + lastDate: widget.lastDate, + initialEntryMode: DatePickerEntryMode.calendarOnly, + ); + if (selectedDate != null) { + _updateInputsWithDate(selectedDate); + field.didChange(selectedDate); + FocusScope.of(context).unfocus(); + } + }, + ), + IconButton( + onPressed: () { + field.didChange(null); + for (var c in _textFieldControls) { + c.controller.clear(); + } + _textFieldControls.first.node.requestFocus(); + }, + icon: const Icon(Icons.clear), + ), + ], + ).paddedOnly(right: 4), + ), + child: Row( + children: [ + for (var s in _textFieldControls) ...[ + SizedBox( + width: switch (s.format) { + == "dd" => 32, + == "MM" => 32, + == "yyyy" => 48, + _ => 0, + }, + child: _buildDateSegmentInput(s, context, field), + ), + if (s.position < 2) Text(_separator).paddedOnly(right: 4), + ], + ], + ), + ), + ); + }, + ), + ); + } + + void _updateInputsWithDate(DateTime date) { + final components = _format.split(_separator); + for (int i = 0; i < components.length; i++) { + final formatString = components[i]; + final value = DateFormat(formatString).format(date); + _textFieldControls.elementAt(i).controller.text = value; + } + } + + Widget _buildDateSegmentInput( + NeighbourAwareDateInputSegmentControls controls, + BuildContext context, + FormFieldState field, + ) { + return TextFormField( + onFieldSubmitted: (value) { + _textFieldControls + .elementAt(controls.position) + .next + ?.node + .requestFocus(); + }, + // onTap: () { + // controls.controller.clear(); + // }, + canRequestFocus: true, + keyboardType: TextInputType.datetime, + textInputAction: TextInputAction.done, + controller: controls.controller, + focusNode: _textFieldControls.elementAt(controls.position).node, + maxLength: controls.format.length, + maxLengthEnforcement: MaxLengthEnforcement.truncateAfterCompositionEnds, + enableInteractiveSelection: false, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ReplacingTextFormatter(), + ], + decoration: InputDecoration( + isDense: true, + contentPadding: EdgeInsets.zero, + counterText: '', + hintText: controls.format, + border: Theme.of(context).inputDecorationTheme.border?.copyWith( + borderSide: const BorderSide( + width: 0, + style: BorderStyle.none, + ), + ), + ), + ); + } +} + +class ReplacingTextFormatter extends TextInputFormatter { + @override + TextEditingValue formatEditUpdate( + TextEditingValue oldValue, + TextEditingValue newValue, + ) { + final oldOffset = oldValue.selection.baseOffset; + final newOffset = newValue.selection.baseOffset; + final replacement = newValue.text.substring(oldOffset, newOffset); + print( + "DBG: Received ${oldValue.text} -> ${newValue.text}. New char = $replacement"); + if (oldOffset < newOffset) { + final oldText = oldValue.text; + final newText = oldText.replaceRange( + oldOffset, + newOffset, + newValue.text.substring(oldOffset, newOffset), + ); + print("DBG: Replacing $oldText -> $newText"); + return newValue.copyWith( + text: newText, + selection: TextSelection.collapsed(offset: newOffset), + ); + } + + return newValue; + } +} diff --git a/lib/core/widgets/form_fields/fullscreen_selection_form.dart b/lib/core/widgets/form_fields/fullscreen_selection_form.dart index b4d0297..514d75f 100644 --- a/lib/core/widgets/form_fields/fullscreen_selection_form.dart +++ b/lib/core/widgets/form_fields/fullscreen_selection_form.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; class FullscreenSelectionForm extends StatefulWidget { diff --git a/lib/core/widgets/hint_card.dart b/lib/core/widgets/hint_card.dart index c041436..3f3583e 100644 --- a/lib/core/widgets/hint_card.dart +++ b/lib/core/widgets/hint_card.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; class HintCard extends StatelessWidget { diff --git a/lib/core/widgets/paperless_logo.dart b/lib/core/widgets/paperless_logo.dart deleted file mode 100644 index e3bfb56..0000000 --- a/lib/core/widgets/paperless_logo.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:paperless_mobile/generated/assets.gen.dart'; - -class PaperlessLogo extends StatelessWidget { - static const _paperlessGreen = Color(0xFF18541F); - final double? height; - final double? width; - final Color _color; - - const PaperlessLogo.white({ - super.key, - this.height, - this.width, - }) : _color = Colors.white; - - const PaperlessLogo.green({super.key, this.height, this.width}) - : _color = _paperlessGreen; - - const PaperlessLogo.black({super.key, this.height, this.width}) - : _color = Colors.black; - - const PaperlessLogo.colored(Color color, {super.key, this.height, this.width}) - : _color = color; - - @override - Widget build(BuildContext context) { - return Container( - constraints: BoxConstraints( - maxHeight: height ?? Theme.of(context).iconTheme.size ?? 32, - maxWidth: width ?? Theme.of(context).iconTheme.size ?? 32, - ), - padding: const EdgeInsets.only(right: 8), - child: Assets.logos.paperlessLogoWhiteSvg.svg( - colorFilter: ColorFilter.mode( - _color, - BlendMode.srcIn, - ), - )); - } -} diff --git a/lib/features/app_drawer/view/app_drawer.dart b/lib/features/app_drawer/view/app_drawer.dart index f569109..e679bdd 100644 --- a/lib/features/app_drawer/view/app_drawer.dart +++ b/lib/features/app_drawer/view/app_drawer.dart @@ -4,9 +4,8 @@ import 'package:flutter_animate/flutter_animate.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:paperless_mobile/constants.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; -import 'package:paperless_mobile/core/logging/view/app_logs_page.dart'; -import 'package:paperless_mobile/core/widgets/paperless_logo.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/features/logging/view/app_logs_page.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart'; import 'package:paperless_mobile/features/saved_view/cubit/saved_view_cubit.dart'; import 'package:paperless_mobile/features/sharing/cubit/receive_share_cubit.dart'; @@ -38,10 +37,10 @@ class AppDrawer extends StatelessWidget { children: [ Row( children: [ - const PaperlessLogo.green( - width: 32, - height: 32, - ), + const $AssetsLogosGen() + .paperlessLogoGreenSvg + .svg(width: 32, height: 32), + SizedBox(width: 8), Text( "Paperless Mobile", style: Theme.of(context).textTheme.titleMedium, diff --git a/lib/features/changelogs/view/changelog_dialog.dart b/lib/features/changelogs/view/changelog_dialog.dart index 8aa6fec..7ebfa9e 100644 --- a/lib/features/changelogs/view/changelog_dialog.dart +++ b/lib/features/changelogs/view/changelog_dialog.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:go_router/go_router.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; import 'package:paperless_mobile/theme.dart'; diff --git a/lib/features/document_bulk_action/view/widgets/fullscreen_bulk_edit_label_page.dart b/lib/features/document_bulk_action/view/widgets/fullscreen_bulk_edit_label_page.dart index 33dee5e..cf26f5f 100644 --- a/lib/features/document_bulk_action/view/widgets/fullscreen_bulk_edit_label_page.dart +++ b/lib/features/document_bulk_action/view/widgets/fullscreen_bulk_edit_label_page.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/widgets/form_fields/fullscreen_selection_form.dart'; -import 'package:paperless_mobile/extensions/dart_extensions.dart'; +import 'package:paperless_mobile/core/extensions/dart_extensions.dart'; import 'package:paperless_mobile/features/document_bulk_action/view/widgets/confirm_bulk_modify_label_dialog.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; diff --git a/lib/features/document_bulk_action/view/widgets/fullscreen_bulk_edit_tags_widget.dart b/lib/features/document_bulk_action/view/widgets/fullscreen_bulk_edit_tags_widget.dart index dbeb107..52dc103 100644 --- a/lib/features/document_bulk_action/view/widgets/fullscreen_bulk_edit_tags_widget.dart +++ b/lib/features/document_bulk_action/view/widgets/fullscreen_bulk_edit_tags_widget.dart @@ -4,7 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/widgets/form_fields/fullscreen_selection_form.dart'; -import 'package:paperless_mobile/extensions/dart_extensions.dart'; +import 'package:paperless_mobile/core/extensions/dart_extensions.dart'; import 'package:paperless_mobile/features/document_bulk_action/cubit/document_bulk_action_cubit.dart'; import 'package:paperless_mobile/features/document_bulk_action/view/widgets/confirm_bulk_modify_tags_dialog.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; diff --git a/lib/features/document_details/cubit/document_details_cubit.dart b/lib/features/document_details/cubit/document_details_cubit.dart index f28ff2b..eae2199 100644 --- a/lib/features/document_details/cubit/document_details_cubit.dart +++ b/lib/features/document_details/cubit/document_details_cubit.dart @@ -6,7 +6,7 @@ import 'package:flutter/material.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:open_filex/open_filex.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/logging/data/logger.dart'; +import 'package:paperless_mobile/features/logging/data/logger.dart'; import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart'; import 'package:paperless_mobile/core/repository/label_repository.dart'; import 'package:paperless_mobile/core/service/file_service.dart'; @@ -30,10 +30,12 @@ class DocumentDetailsCubit extends Cubit { this._notifier, this._notificationService, { required DocumentModel initialDocument, - }) : super(DocumentDetailsState( - document: initialDocument, - )) { - _notifier.addListener(this, onUpdated: replace); + }) : super(DocumentDetailsState(document: initialDocument)) { + _notifier.addListener(this, onUpdated: (document) { + if (document.id == state.document.id) { + replace(document); + } + }); _labelRepository.addListener( this, onChanged: (labels) => emit( @@ -127,7 +129,7 @@ class DocumentDetailsCubit extends Cubit { if (!await File(targetPath).exists()) { await File(targetPath).create(); } else { - await _notificationService.notifyFileDownload( + await _notificationService.notifyDocumentDownload( document: state.document, filename: p.basename(targetPath), filePath: targetPath, @@ -151,7 +153,7 @@ class DocumentDetailsCubit extends Cubit { targetPath, original: downloadOriginal, onProgressChanged: (progress) { - _notificationService.notifyFileDownload( + _notificationService.notifyDocumentDownload( document: state.document, filename: p.basename(targetPath), filePath: targetPath, @@ -162,7 +164,7 @@ class DocumentDetailsCubit extends Cubit { ); }, ); - await _notificationService.notifyFileDownload( + await _notificationService.notifyDocumentDownload( document: state.document, filename: p.basename(targetPath), filePath: targetPath, 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 57460c1..9225d8c 100644 --- a/lib/features/document_details/view/pages/document_details_page.dart +++ b/lib/features/document_details/view/pages/document_details_page.dart @@ -9,7 +9,7 @@ import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/translation/error_code_localization_mapper.dart'; import 'package:paperless_mobile/core/widgets/material/colored_tab_bar.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart'; import 'package:paperless_mobile/features/document_details/view/widgets/document_content_widget.dart'; import 'package:paperless_mobile/features/document_details/view/widgets/document_download_button.dart'; diff --git a/lib/features/document_details/view/widgets/archive_serial_number_field.dart b/lib/features/document_details/view/widgets/archive_serial_number_field.dart index ba2f6e2..3aeaef7 100644 --- a/lib/features/document_details/view/widgets/archive_serial_number_field.dart +++ b/lib/features/document_details/view/widgets/archive_serial_number_field.dart @@ -4,7 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; import 'package:paperless_mobile/helpers/message_helpers.dart'; diff --git a/lib/features/document_details/view/widgets/document_content_widget.dart b/lib/features/document_details/view/widgets/document_content_widget.dart index 6516658..a73dec3 100644 --- a/lib/features/document_details/view/widgets/document_content_widget.dart +++ b/lib/features/document_details/view/widgets/document_content_widget.dart @@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/widgets/highlighted_text.dart'; import 'package:paperless_mobile/core/widgets/shimmer_placeholder.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; diff --git a/lib/features/document_details/view/widgets/document_download_button.dart b/lib/features/document_details/view/widgets/document_download_button.dart index 5f66073..abbf996 100644 --- a/lib/features/document_details/view/widgets/document_download_button.dart +++ b/lib/features/document_details/view/widgets/document_download_button.dart @@ -3,9 +3,9 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart'; import 'package:paperless_mobile/features/document_details/view/dialogs/select_file_type_dialog.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; diff --git a/lib/features/document_details/view/widgets/document_meta_data_widget.dart b/lib/features/document_details/view/widgets/document_meta_data_widget.dart index 3c45a44..0d003ff 100644 --- a/lib/features/document_details/view/widgets/document_meta_data_widget.dart +++ b/lib/features/document_details/view/widgets/document_meta_data_widget.dart @@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:intl/intl.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart'; import 'package:paperless_mobile/features/document_details/view/widgets/archive_serial_number_field.dart'; import 'package:paperless_mobile/features/document_details/view/widgets/details_item.dart'; diff --git a/lib/features/document_details/view/widgets/document_overview_widget.dart b/lib/features/document_details/view/widgets/document_overview_widget.dart index 369cdf2..d15d0c8 100644 --- a/lib/features/document_details/view/widgets/document_overview_widget.dart +++ b/lib/features/document_details/view/widgets/document_overview_widget.dart @@ -5,7 +5,7 @@ import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/repository/label_repository.dart'; import 'package:paperless_mobile/core/widgets/highlighted_text.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/document_details/view/widgets/details_item.dart'; import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_widget.dart'; import 'package:paperless_mobile/features/labels/view/widgets/label_text.dart'; diff --git a/lib/features/document_details/view/widgets/document_share_button.dart b/lib/features/document_details/view/widgets/document_share_button.dart index aaeb0c0..9ab0e4d 100644 --- a/lib/features/document_details/view/widgets/document_share_button.dart +++ b/lib/features/document_details/view/widgets/document_share_button.dart @@ -4,9 +4,9 @@ import 'package:flutter/material.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/constants.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart'; import 'package:paperless_mobile/features/document_details/view/dialogs/select_file_type_dialog.dart'; import 'package:paperless_mobile/features/settings/model/file_download_type.dart'; diff --git a/lib/features/document_edit/cubit/document_edit_cubit.dart b/lib/features/document_edit/cubit/document_edit_cubit.dart index 3003264..d6f28d2 100644 --- a/lib/features/document_edit/cubit/document_edit_cubit.dart +++ b/lib/features/document_edit/cubit/document_edit_cubit.dart @@ -22,7 +22,11 @@ class DocumentEditCubit extends Cubit { required DocumentModel document, }) : _initialDocument = document, super(DocumentEditState(document: document)) { - _notifier.addListener(this, onUpdated: replace); + _notifier.addListener(this, onUpdated: (doc) { + if (doc.id == document.id) { + emit(state.copyWith(document: doc)); + } + }); _labelRepository.addListener( this, onChanged: (labels) { @@ -69,10 +73,6 @@ class DocumentEditCubit extends Cubit { emit(state.copyWith(suggestions: suggestions)); } - void replace(DocumentModel document) { - emit(state.copyWith(document: document)); - } - @override Future close() { _notifier.removeListener(this); diff --git a/lib/features/document_edit/view/document_edit_page.dart b/lib/features/document_edit/view/document_edit_page.dart index 2b51c97..b486c87 100644 --- a/lib/features/document_edit/view/document_edit_page.dart +++ b/lib/features/document_edit/view/document_edit_page.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:flutter_typeahead/flutter_typeahead.dart'; @@ -12,8 +11,9 @@ import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/widgets/dialog_utils/dialog_cancel_button.dart'; import 'package:paperless_mobile/core/widgets/dialog_utils/pop_with_unsaved_changes.dart'; +import 'package:paperless_mobile/core/widgets/form_builder_fields/form_builder_localized_date_picker.dart'; import 'package:paperless_mobile/core/workarounds/colored_chip.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/document_edit/cubit/document_edit_cubit.dart'; import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_form_field.dart'; import 'package:paperless_mobile/features/labels/view/widgets/label_form_field.dart'; @@ -21,7 +21,6 @@ import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; import 'package:paperless_mobile/helpers/message_helpers.dart'; import 'package:paperless_mobile/routes/typed/branches/labels_route.dart'; import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart'; -import 'package:paperless_mobile/theme.dart'; class DocumentEditPage extends StatefulWidget { const DocumentEditPage({ @@ -401,6 +400,12 @@ class _DocumentEditPageState extends State { name: fkTitle, decoration: InputDecoration( label: Text(S.of(context)!.title), + suffixIcon: IconButton( + icon: Icon(Icons.clear), + onPressed: () { + _formKey.currentState?.fields[fkTitle]?.didChange(null); + }, + ), ), initialValue: initialTitle, ); @@ -408,6 +413,15 @@ class _DocumentEditPageState extends State { Widget _buildCreatedAtFormField( DateTime? initialCreatedAtDate, FieldSuggestions? filteredSuggestions) { + // return FormBuilderLocalizedDatePicker( + // name: fkCreatedDate, + // initialValue: initialCreatedAtDate, + // labelText: S.of(context)!.createdAt, + // firstDate: DateTime(1970, 1, 1), + // lastDate: DateTime.now(), + // locale: Localizations.localeOf(context), + // prefixIcon: Icon(Icons.calendar_today), + // ); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/lib/features/document_scan/cubit/document_scanner_cubit.dart b/lib/features/document_scan/cubit/document_scanner_cubit.dart index 364ce7f..85b63d7 100644 --- a/lib/features/document_scan/cubit/document_scanner_cubit.dart +++ b/lib/features/document_scan/cubit/document_scanner_cubit.dart @@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/logging/data/logger.dart'; +import 'package:paperless_mobile/features/logging/data/logger.dart'; import 'package:paperless_mobile/core/model/info_message_exception.dart'; import 'package:paperless_mobile/core/service/file_service.dart'; import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart'; diff --git a/lib/features/document_scan/view/scanner_page.dart b/lib/features/document_scan/view/scanner_page.dart index 316c3a2..a0317be 100644 --- a/lib/features/document_scan/view/scanner_page.dart +++ b/lib/features/document_scan/view/scanner_page.dart @@ -10,7 +10,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:hive/hive.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/constants.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; import 'package:paperless_mobile/core/global/constants.dart'; import 'package:paperless_mobile/core/service/file_service.dart'; diff --git a/lib/features/document_search/view/document_search_bar.dart b/lib/features/document_search/view/document_search_bar.dart index bbc3bd5..43b81ef 100644 --- a/lib/features/document_search/view/document_search_bar.dart +++ b/lib/features/document_search/view/document_search_bar.dart @@ -1,7 +1,7 @@ import 'package:animations/animations.dart'; import 'package:flutter/material.dart'; import 'package:hive_flutter/adapters.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart'; import 'package:paperless_mobile/features/document_search/cubit/document_search_cubit.dart'; diff --git a/lib/features/document_search/view/document_search_page.dart b/lib/features/document_search/view/document_search_page.dart index b2067f8..5f8c6bb 100644 --- a/lib/features/document_search/view/document_search_page.dart +++ b/lib/features/document_search/view/document_search_page.dart @@ -4,7 +4,7 @@ import 'dart:math' as math; import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/document_search/cubit/document_search_cubit.dart'; import 'package:paperless_mobile/features/document_search/view/remove_history_entry_dialog.dart'; import 'package:paperless_mobile/features/documents/view/widgets/adaptive_documents_view.dart'; diff --git a/lib/features/document_search/view/sliver_search_bar.dart b/lib/features/document_search/view/sliver_search_bar.dart index 7d83861..2b87c87 100644 --- a/lib/features/document_search/view/sliver_search_bar.dart +++ b/lib/features/document_search/view/sliver_search_bar.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:hive_flutter/adapters.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/features/document_search/view/document_search_bar.dart'; import 'package:paperless_mobile/features/settings/view/manage_accounts_page.dart'; diff --git a/lib/features/document_upload/view/document_upload_preparation_page.dart b/lib/features/document_upload/view/document_upload_preparation_page.dart index bd0d8d5..959d914 100644 --- a/lib/features/document_upload/view/document_upload_preparation_page.dart +++ b/lib/features/document_upload/view/document_upload_preparation_page.dart @@ -9,13 +9,13 @@ import 'package:hive/hive.dart'; import 'package:intl/date_symbol_data_local.dart'; import 'package:intl/intl.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; -import 'package:paperless_mobile/core/logging/data/logger.dart'; +import 'package:paperless_mobile/features/logging/data/logger.dart'; import 'package:paperless_mobile/core/repository/label_repository.dart'; import 'package:paperless_mobile/core/widgets/future_or_builder.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/document_upload/cubit/document_upload_cubit.dart'; import 'package:paperless_mobile/features/edit_label/view/impl/add_correspondent_page.dart'; import 'package:paperless_mobile/features/edit_label/view/impl/add_document_type_page.dart'; diff --git a/lib/features/documents/cubit/documents_cubit.dart b/lib/features/documents/cubit/documents_cubit.dart index de482c9..3cf8716 100644 --- a/lib/features/documents/cubit/documents_cubit.dart +++ b/lib/features/documents/cubit/documents_cubit.dart @@ -5,6 +5,7 @@ import 'package:hydrated_bloc/hydrated_bloc.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart'; +import 'package:paperless_mobile/core/extensions/document_iterable_extensions.dart'; import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart'; import 'package:paperless_mobile/core/repository/label_repository.dart'; import 'package:paperless_mobile/core/service/connectivity_status_service.dart'; @@ -44,18 +45,15 @@ class DocumentsCubit extends Cubit replace(document); emit( state.copyWith( - selection: state.selection - .map((e) => e.id == document.id ? document : e) - .toList(), - ), + selection: + state.selection.withDocumentreplaced(document).toList()), ); }, onDeleted: (document) { remove(document); emit( state.copyWith( - selection: - state.selection.where((e) => e.id != document.id).toList(), + selection: state.selection.withDocumentRemoved(document).toList(), ), ); }, diff --git a/lib/features/documents/view/pages/documents_page.dart b/lib/features/documents/view/pages/documents_page.dart index 0f31032..ce3f8e9 100644 --- a/lib/features/documents/view/pages/documents_page.dart +++ b/lib/features/documents/view/pages/documents_page.dart @@ -6,7 +6,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/app_drawer/view/app_drawer.dart'; import 'package:paperless_mobile/features/document_search/view/sliver_search_bar.dart'; import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart'; diff --git a/lib/features/documents/view/widgets/documents_empty_state.dart b/lib/features/documents/view/widgets/documents_empty_state.dart index 7482265..2937e81 100644 --- a/lib/features/documents/view/widgets/documents_empty_state.dart +++ b/lib/features/documents/view/widgets/documents_empty_state.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/paged_document_view/cubit/paged_documents_state.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; diff --git a/lib/features/documents/view/widgets/items/document_detailed_item.dart b/lib/features/documents/view/widgets/items/document_detailed_item.dart index 7b671b7..b0388bd 100644 --- a/lib/features/documents/view/widgets/items/document_detailed_item.dart +++ b/lib/features/documents/view/widgets/items/document_detailed_item.dart @@ -5,11 +5,11 @@ import 'package:flutter_html/flutter_html.dart'; import 'package:hive_flutter/adapters.dart'; import 'package:intl/intl.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/repository/label_repository.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/documents/view/widgets/document_preview.dart'; import 'package:paperless_mobile/features/documents/view/widgets/items/document_item.dart'; import 'package:paperless_mobile/features/labels/correspondent/view/widgets/correspondent_widget.dart'; diff --git a/lib/features/documents/view/widgets/placeholder/document_grid_loading_widget.dart b/lib/features/documents/view/widgets/placeholder/document_grid_loading_widget.dart index 5fc7aba..f00a0a9 100644 --- a/lib/features/documents/view/widgets/placeholder/document_grid_loading_widget.dart +++ b/lib/features/documents/view/widgets/placeholder/document_grid_loading_widget.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:paperless_mobile/core/widgets/shimmer_placeholder.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/documents/view/widgets/placeholder/tags_placeholder.dart'; import 'package:paperless_mobile/features/documents/view/widgets/placeholder/text_placeholder.dart'; diff --git a/lib/features/documents/view/widgets/placeholder/tags_placeholder.dart b/lib/features/documents/view/widgets/placeholder/tags_placeholder.dart index 22528e1..0b9943d 100644 --- a/lib/features/documents/view/widgets/placeholder/tags_placeholder.dart +++ b/lib/features/documents/view/widgets/placeholder/tags_placeholder.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; class TagsPlaceholder extends StatelessWidget { static const _lengths = [90, 70, 130]; diff --git a/lib/features/documents/view/widgets/saved_views/saved_view_chip.dart b/lib/features/documents/view/widgets/saved_views/saved_view_chip.dart index a842a19..dbeb23b 100644 --- a/lib/features/documents/view/widgets/saved_views/saved_view_chip.dart +++ b/lib/features/documents/view/widgets/saved_views/saved_view_chip.dart @@ -2,7 +2,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/routes/typed/branches/saved_views_route.dart'; import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart'; diff --git a/lib/features/documents/view/widgets/saved_views/saved_views_widget.dart b/lib/features/documents/view/widgets/saved_views/saved_views_widget.dart index 4bb1617..8df1074 100644 --- a/lib/features/documents/view/widgets/saved_views/saved_views_widget.dart +++ b/lib/features/documents/view/widgets/saved_views/saved_views_widget.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/widgets/shimmer_placeholder.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/documents/view/widgets/saved_views/saved_view_chip.dart'; import 'package:paperless_mobile/features/saved_view/cubit/saved_view_cubit.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; diff --git a/lib/features/documents/view/widgets/search/sort_field_selection_bottom_sheet.dart b/lib/features/documents/view/widgets/search/sort_field_selection_bottom_sheet.dart index 0746955..0b8d89c 100644 --- a/lib/features/documents/view/widgets/search/sort_field_selection_bottom_sheet.dart +++ b/lib/features/documents/view/widgets/search/sort_field_selection_bottom_sheet.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/translation/sort_field_localization_mapper.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; class SortFieldSelectionBottomSheet extends StatefulWidget { diff --git a/lib/features/documents/view/widgets/selection/document_selection_sliver_app_bar.dart b/lib/features/documents/view/widgets/selection/document_selection_sliver_app_bar.dart index 6ca80a1..4f5457c 100644 --- a/lib/features/documents/view/widgets/selection/document_selection_sliver_app_bar.dart +++ b/lib/features/documents/view/widgets/selection/document_selection_sliver_app_bar.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/view/widgets/selection/bulk_delete_confirmation_dialog.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; diff --git a/lib/features/edit_label/view/label_form.dart b/lib/features/edit_label/view/label_form.dart index 0ffd4c9..2f62bb4 100644 --- a/lib/features/edit_label/view/label_form.dart +++ b/lib/features/edit_label/view/label_form.dart @@ -5,7 +5,7 @@ import 'package:go_router/go_router.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/translation/matching_algorithm_localization_mapper.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; import 'package:paperless_mobile/helpers/message_helpers.dart'; diff --git a/lib/features/home/view/home_shell_widget.dart b/lib/features/home/view/home_shell_widget.dart index 40bc2f0..0c2ef47 100644 --- a/lib/features/home/view/home_shell_widget.dart +++ b/lib/features/home/view/home_shell_widget.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:hive_flutter/adapters.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; -import 'package:paperless_mobile/core/config/hive/hive_extensions.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_extensions.dart'; import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart'; import 'package:paperless_mobile/core/factory/paperless_api_factory.dart'; import 'package:paperless_mobile/core/repository/label_repository.dart'; diff --git a/lib/features/inbox/cubit/inbox_cubit.dart b/lib/features/inbox/cubit/inbox_cubit.dart index b67f012..68de175 100644 --- a/lib/features/inbox/cubit/inbox_cubit.dart +++ b/lib/features/inbox/cubit/inbox_cubit.dart @@ -3,7 +3,7 @@ import 'dart:async'; import 'package:hydrated_bloc/hydrated_bloc.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/logging/data/logger.dart'; +import 'package:paperless_mobile/features/logging/data/logger.dart'; import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart'; import 'package:paperless_mobile/core/repository/label_repository.dart'; import 'package:paperless_mobile/core/repository/label_repository_state.dart'; diff --git a/lib/features/inbox/view/pages/inbox_page.dart b/lib/features/inbox/view/pages/inbox_page.dart index e04e83e..8dfefd7 100644 --- a/lib/features/inbox/view/pages/inbox_page.dart +++ b/lib/features/inbox/view/pages/inbox_page.dart @@ -9,8 +9,8 @@ import 'package:paperless_mobile/core/service/connectivity_status_service.dart'; import 'package:paperless_mobile/core/widgets/dialog_utils/dialog_cancel_button.dart'; import 'package:paperless_mobile/core/widgets/dialog_utils/dialog_confirm_button.dart'; import 'package:paperless_mobile/core/widgets/hint_card.dart'; -import 'package:paperless_mobile/extensions/dart_extensions.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/dart_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/app_drawer/view/app_drawer.dart'; import 'package:paperless_mobile/features/document_search/view/sliver_search_bar.dart'; import 'package:paperless_mobile/features/inbox/cubit/inbox_cubit.dart'; diff --git a/lib/features/inbox/view/widgets/inbox_item.dart b/lib/features/inbox/view/widgets/inbox_item.dart index ae976f1..aa2ee52 100644 --- a/lib/features/inbox/view/widgets/inbox_item.dart +++ b/lib/features/inbox/view/widgets/inbox_item.dart @@ -5,7 +5,7 @@ import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/widgets/shimmer_placeholder.dart'; import 'package:paperless_mobile/core/workarounds/colored_chip.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/documents/view/widgets/delete_document_confirmation_dialog.dart'; import 'package:paperless_mobile/features/documents/view/widgets/document_preview.dart'; import 'package:paperless_mobile/features/documents/view/widgets/placeholder/tags_placeholder.dart'; diff --git a/lib/features/labels/tags/view/widgets/fullscreen_tags_form.dart b/lib/features/labels/tags/view/widgets/fullscreen_tags_form.dart index 1fee66e..40d0c1c 100644 --- a/lib/features/labels/tags/view/widgets/fullscreen_tags_form.dart +++ b/lib/features/labels/tags/view/widgets/fullscreen_tags_form.dart @@ -1,7 +1,7 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/edit_label/view/impl/add_tag_page.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; import 'package:paperless_mobile/routes/typed/branches/labels_route.dart'; diff --git a/lib/features/labels/tags/view/widgets/tags_form_field.dart b/lib/features/labels/tags/view/widgets/tags_form_field.dart index fc554f7..ba728e0 100644 --- a/lib/features/labels/tags/view/widgets/tags_form_field.dart +++ b/lib/features/labels/tags/view/widgets/tags_form_field.dart @@ -6,7 +6,7 @@ import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/workarounds/colored_chip.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/labels/tags/view/widgets/fullscreen_tags_form.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; diff --git a/lib/features/labels/view/pages/labels_page.dart b/lib/features/labels/view/pages/labels_page.dart index 7f0b71b..1fbcdf3 100644 --- a/lib/features/labels/view/pages/labels_page.dart +++ b/lib/features/labels/view/pages/labels_page.dart @@ -3,11 +3,11 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:hive_flutter/adapters.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/delegate/customizable_sliver_persistent_header_delegate.dart'; -import 'package:paperless_mobile/core/logging/data/logger.dart'; +import 'package:paperless_mobile/features/logging/data/logger.dart'; import 'package:paperless_mobile/core/widgets/material/colored_tab_bar.dart'; import 'package:paperless_mobile/features/app_drawer/view/app_drawer.dart'; import 'package:paperless_mobile/features/document_search/view/sliver_search_bar.dart'; diff --git a/lib/features/labels/view/widgets/fullscreen_label_form.dart b/lib/features/labels/view/widgets/fullscreen_label_form.dart index 7c2d0c8..4ca2da4 100644 --- a/lib/features/labels/view/widgets/fullscreen_label_form.dart +++ b/lib/features/labels/view/widgets/fullscreen_label_form.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; class FullscreenLabelForm extends StatefulWidget { diff --git a/lib/features/labels/view/widgets/label_form_field.dart b/lib/features/labels/view/widgets/label_form_field.dart index d660dcb..f7496e6 100644 --- a/lib/features/labels/view/widgets/label_form_field.dart +++ b/lib/features/labels/view/widgets/label_form_field.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/workarounds/colored_chip.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/labels/view/widgets/fullscreen_label_form.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; diff --git a/lib/features/labels/view/widgets/label_tab_view.dart b/lib/features/labels/view/widgets/label_tab_view.dart index 9d6ce8c..01b3c88 100644 --- a/lib/features/labels/view/widgets/label_tab_view.dart +++ b/lib/features/labels/view/widgets/label_tab_view.dart @@ -5,7 +5,7 @@ import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart'; import 'package:paperless_mobile/core/translation/matching_algorithm_localization_mapper.dart'; import 'package:paperless_mobile/core/widgets/offline_widget.dart'; import 'package:paperless_mobile/features/labels/view/widgets/label_item.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; class LabelTabView extends StatelessWidget { final Map labels; diff --git a/lib/features/landing/view/landing_page.dart b/lib/features/landing/view/landing_page.dart index 08d31b1..4df3007 100644 --- a/lib/features/landing/view/landing_page.dart +++ b/lib/features/landing/view/landing_page.dart @@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/constants.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/app_drawer/view/app_drawer.dart'; import 'package:paperless_mobile/features/document_search/view/sliver_search_bar.dart'; import 'package:paperless_mobile/features/landing/view/widgets/expansion_card.dart'; diff --git a/lib/core/logging/cubit/app_logs_cubit.dart b/lib/features/logging/cubit/app_logs_cubit.dart similarity index 60% rename from lib/core/logging/cubit/app_logs_cubit.dart rename to lib/features/logging/cubit/app_logs_cubit.dart index 7ff127a..6ec2eb1 100644 --- a/lib/core/logging/cubit/app_logs_cubit.dart +++ b/lib/features/logging/cubit/app_logs_cubit.dart @@ -6,9 +6,11 @@ import 'package:collection/collection.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; -import 'package:paperless_mobile/core/logging/models/parsed_log_message.dart'; +import 'package:paperless_mobile/features/logging/models/parsed_log_message.dart'; import 'package:paperless_mobile/core/service/file_service.dart'; +import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart'; import 'package:path/path.dart' as p; +import 'package:permission_handler/permission_handler.dart'; import 'package:rxdart/rxdart.dart'; part 'app_logs_state.dart'; @@ -16,7 +18,11 @@ final _fileNameFormat = DateFormat("yyyy-MM-dd"); class AppLogsCubit extends Cubit { StreamSubscription? _fileChangesSubscription; - AppLogsCubit(DateTime date) : super(AppLogsStateInitial(date: date)); + final LocalNotificationService _localNotificationService; + AppLogsCubit( + DateTime date, + this._localNotificationService, + ) : super(AppLogsStateInitial(date: date)); Future loadLogs(DateTime date) async { if (date == state.date) { @@ -42,24 +48,12 @@ class AppLogsCubit extends Cubit { )); } try { - final logs = await logFile.readAsLines(); - final parsedLogs = - ParsedLogMessage.parse(logs.skip(2000).toList()).reversed.toList(); + _updateLogsFromFile(logFile, date, availableLogs); _fileChangesSubscription = logFile.watch().listen((event) async { if (!isClosed) { - final logs = await logFile.readAsLines(); - emit(AppLogsStateLoaded( - date: date, - logs: parsedLogs, - availableLogs: availableLogs, - )); + _updateLogsFromFile(logFile, date, availableLogs); } }); - emit(AppLogsStateLoaded( - date: date, - logs: parsedLogs, - availableLogs: availableLogs, - )); } catch (e) { emit(AppLogsStateError( error: e, @@ -68,6 +62,17 @@ class AppLogsCubit extends Cubit { } } + void _updateLogsFromFile( + File file, DateTime date, List availableLogs) async { + final logs = await file.readAsLines(); + final parsedLogs = ParsedLogMessage.parse(logs).reversed.toList(); + emit(AppLogsStateLoaded( + date: date, + logs: parsedLogs, + availableLogs: availableLogs, + )); + } + Future clearLogs(DateTime date) async { final logFile = _getLogfile(date); await logFile.writeAsString(''); @@ -86,16 +91,19 @@ class AppLogsCubit extends Cubit { Future saveLogs(DateTime date, String locale) async { var formattedDate = _fileNameFormat.format(date); final filename = 'paperless_mobile_logs_$formattedDate.log'; - final parentDir = await FilePicker.platform.getDirectoryPath( - dialogTitle: "Save log from ${DateFormat.yMd(locale).format(date)}", - initialDirectory: Platform.isAndroid - ? FileService.instance.downloadsDirectory.path - : null, - ); + // final parentDir = await FilePicker.platform.getDirectoryPath( + // dialogTitle: "Save log from ${DateFormat.yMd(locale).format(date)}", + // initialDirectory: Platform.isAndroid + // ? FileService.instance.downloadsDirectory.path + // : null, + // ); + // if (parentDir == null) { + // return; + // } final logFile = _getLogfile(date); - if (parentDir != null) { - await logFile.copy(p.join(parentDir, filename)); - } + final parentDir = FileService.instance.downloadsDirectory; + final downloadedFile = await logFile.copy(p.join(parentDir.path, filename)); + _localNotificationService.notifyFileDownload(filePath: downloadedFile.path); } File _getLogfile(DateTime date) { @@ -104,8 +112,8 @@ class AppLogsCubit extends Cubit { } @override - Future close() { - _fileChangesSubscription?.cancel(); + Future close() async { + await _fileChangesSubscription?.cancel(); return super.close(); } } diff --git a/lib/core/logging/cubit/app_logs_state.dart b/lib/features/logging/cubit/app_logs_state.dart similarity index 100% rename from lib/core/logging/cubit/app_logs_state.dart rename to lib/features/logging/cubit/app_logs_state.dart diff --git a/lib/core/logging/data/formatted_printer.dart b/lib/features/logging/data/formatted_printer.dart similarity index 91% rename from lib/core/logging/data/formatted_printer.dart rename to lib/features/logging/data/formatted_printer.dart index 63d88c2..c2faec9 100644 --- a/lib/core/logging/data/formatted_printer.dart +++ b/lib/features/logging/data/formatted_printer.dart @@ -1,9 +1,10 @@ import 'dart:convert'; import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:logger/logger.dart'; -import 'package:paperless_mobile/core/logging/models/formatted_log_message.dart'; +import 'package:paperless_mobile/features/logging/models/formatted_log_message.dart'; class FormattedPrinter extends LogPrinter { static final _timestampFormat = DateFormat("yyyy-MM-dd HH:mm:ss.SSS"); diff --git a/lib/core/logging/data/logger.dart b/lib/features/logging/data/logger.dart similarity index 96% rename from lib/core/logging/data/logger.dart rename to lib/features/logging/data/logger.dart index e7016be..d254237 100644 --- a/lib/core/logging/data/logger.dart +++ b/lib/features/logging/data/logger.dart @@ -1,5 +1,5 @@ import 'package:logger/logger.dart'; -import 'package:paperless_mobile/core/logging/models/formatted_log_message.dart'; +import 'package:paperless_mobile/features/logging/models/formatted_log_message.dart'; late Logger logger; diff --git a/lib/core/logging/data/mirrored_file_output.dart b/lib/features/logging/data/mirrored_file_output.dart similarity index 82% rename from lib/core/logging/data/mirrored_file_output.dart rename to lib/features/logging/data/mirrored_file_output.dart index 8feff46..01cef24 100644 --- a/lib/core/logging/data/mirrored_file_output.dart +++ b/lib/features/logging/data/mirrored_file_output.dart @@ -9,8 +9,9 @@ import 'package:paperless_mobile/core/service/file_service.dart'; import 'package:path/path.dart' as p; import 'package:synchronized/synchronized.dart'; +typedef f = FileOutput; + class MirroredFileOutput extends LogOutput { - final Completer _initCompleter = Completer(); var lock = Lock(); MirroredFileOutput(); @@ -22,7 +23,6 @@ class MirroredFileOutput extends LogOutput { final logDir = FileService.instance.logDirectory; file = File(p.join(logDir.path, '$today.log')); debugPrint("Logging files to ${file.path}."); - _initCompleter.complete(); try { final oldLogs = await FileService.instance.getAllFiles(logDir); if (oldLogs.length > 10) { @@ -42,12 +42,10 @@ class MirroredFileOutput extends LogOutput { await lock.synchronized(() async { for (var line in event.lines) { debugPrint(line); - if (_initCompleter.isCompleted) { - await file.writeAsString( - "$line${Platform.lineTerminator}", - mode: FileMode.append, - ); - } + await file.writeAsString( + "$line${Platform.lineTerminator}", + mode: FileMode.append, + ); } }); } diff --git a/lib/core/logging/models/formatted_log_message.dart b/lib/features/logging/models/formatted_log_message.dart similarity index 100% rename from lib/core/logging/models/formatted_log_message.dart rename to lib/features/logging/models/formatted_log_message.dart diff --git a/lib/core/logging/models/parsed_log_message.dart b/lib/features/logging/models/parsed_log_message.dart similarity index 98% rename from lib/core/logging/models/parsed_log_message.dart rename to lib/features/logging/models/parsed_log_message.dart index 3c121cc..d63a591 100644 --- a/lib/core/logging/models/parsed_log_message.dart +++ b/lib/features/logging/models/parsed_log_message.dart @@ -40,12 +40,13 @@ class ParsedErrorLogMessage { static bool canConsumeFirstLine(String line) => _errorBeginPattern.hasMatch(line); - static (int consumedLines, ParsedErrorLogMessage result) consume( + static (int consumedLines, ParsedErrorLogMessage? result) consume( List log) { assert(log.isNotEmpty && canConsumeFirstLine(log.first)); String errorText = ""; int currentLine = 1; // Skip first because we know that the first line is ---BEGIN ERROR--- + while (!_errorEndPattern.hasMatch(log[currentLine])) { errorText += log[currentLine] + _newLine; currentLine++; diff --git a/lib/core/logging/utils/redaction_utils.dart b/lib/features/logging/utils/redaction_utils.dart similarity index 100% rename from lib/core/logging/utils/redaction_utils.dart rename to lib/features/logging/utils/redaction_utils.dart diff --git a/lib/core/logging/view/app_logs_page.dart b/lib/features/logging/view/app_logs_page.dart similarity index 95% rename from lib/core/logging/view/app_logs_page.dart rename to lib/features/logging/view/app_logs_page.dart index 0ba82ce..f8fef47 100644 --- a/lib/core/logging/view/app_logs_page.dart +++ b/lib/features/logging/view/app_logs_page.dart @@ -3,10 +3,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:intl/intl.dart'; import 'package:logger/logger.dart'; -import 'package:paperless_mobile/core/logging/cubit/app_logs_cubit.dart'; -import 'package:paperless_mobile/core/logging/models/parsed_log_message.dart'; -import 'package:paperless_mobile/extensions/dart_extensions.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/features/logging/cubit/app_logs_cubit.dart'; +import 'package:paperless_mobile/features/logging/models/parsed_log_message.dart'; +import 'package:paperless_mobile/core/extensions/dart_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; class AppLogsPage extends StatefulWidget { @@ -134,9 +134,8 @@ class _AppLogsPageState extends State { }, ), AppLogsStateError() => Center( - child: Text( - S.of(context)!.couldNotLoadLogfileFrom(formattedDate), - ), + child: + Text(S.of(context)!.couldNotLoadLogfileFrom(formattedDate)), ), _ => _buildLoadingLogs(state.date) }, diff --git a/lib/features/login/cubit/authentication_cubit.dart b/lib/features/login/cubit/authentication_cubit.dart index f59223c..6f3993d 100644 --- a/lib/features/login/cubit/authentication_cubit.dart +++ b/lib/features/login/cubit/authentication_cubit.dart @@ -1,12 +1,11 @@ import 'package:dio/dio.dart'; import 'package:equatable/equatable.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:hive_flutter/adapters.dart'; import 'package:hydrated_bloc/hydrated_bloc.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; -import 'package:paperless_mobile/core/config/hive/hive_extensions.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_extensions.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart'; @@ -14,8 +13,8 @@ import 'package:paperless_mobile/core/database/tables/local_user_settings.dart'; import 'package:paperless_mobile/core/database/tables/user_credentials.dart'; import 'package:paperless_mobile/core/factory/paperless_api_factory.dart'; import 'package:paperless_mobile/core/interceptor/language_header.interceptor.dart'; -import 'package:paperless_mobile/core/logging/data/logger.dart'; -import 'package:paperless_mobile/core/logging/utils/redaction_utils.dart'; +import 'package:paperless_mobile/features/logging/data/logger.dart'; +import 'package:paperless_mobile/features/logging/utils/redaction_utils.dart'; import 'package:paperless_mobile/core/model/info_message_exception.dart'; import 'package:paperless_mobile/core/security/session_manager.dart'; import 'package:paperless_mobile/core/service/connectivity_status_service.dart'; diff --git a/lib/features/login/model/authentication_information.dart b/lib/features/login/model/authentication_information.dart index 1743f1f..b83144e 100644 --- a/lib/features/login/model/authentication_information.dart +++ b/lib/features/login/model/authentication_information.dart @@ -1,5 +1,5 @@ import 'package:hive/hive.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/features/login/model/client_certificate.dart'; part 'authentication_information.g.dart'; diff --git a/lib/features/login/model/client_certificate.dart b/lib/features/login/model/client_certificate.dart index 00c24c8..3dd39b8 100644 --- a/lib/features/login/model/client_certificate.dart +++ b/lib/features/login/model/client_certificate.dart @@ -1,7 +1,7 @@ import 'dart:typed_data'; import 'package:hive_flutter/adapters.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; part 'client_certificate.g.dart'; diff --git a/lib/features/login/view/add_account_page.dart b/lib/features/login/view/add_account_page.dart index e7ab5b6..bf450be 100644 --- a/lib/features/login/view/add_account_page.dart +++ b/lib/features/login/view/add_account_page.dart @@ -7,7 +7,7 @@ import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/exception/server_message_exception.dart'; import 'package:paperless_mobile/core/model/info_message_exception.dart'; import 'package:paperless_mobile/core/service/connectivity_status_service.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/login/model/client_certificate.dart'; import 'package:paperless_mobile/features/login/model/client_certificate_form_model.dart'; import 'package:paperless_mobile/features/login/model/login_form_credentials.dart'; diff --git a/lib/features/login/view/login_page.dart b/lib/features/login/view/login_page.dart index 831be9e..fe92a88 100644 --- a/lib/features/login/view/login_page.dart +++ b/lib/features/login/view/login_page.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:hive_flutter/adapters.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; -import 'package:paperless_mobile/core/config/hive/hive_extensions.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_extensions.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; import 'package:paperless_mobile/core/model/info_message_exception.dart'; import 'package:paperless_mobile/features/app_intro/application_intro_slideshow.dart'; diff --git a/lib/features/login/view/login_to_existing_account_page.dart b/lib/features/login/view/login_to_existing_account_page.dart index 952c213..c4aa7de 100644 --- a/lib/features/login/view/login_to_existing_account_page.dart +++ b/lib/features/login/view/login_to_existing_account_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:hive_flutter/adapters.dart'; -import 'package:paperless_mobile/core/config/hive/hive_extensions.dart'; +import 'package:paperless_mobile/core/database/hive/hive_extensions.dart'; import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart'; import 'package:paperless_mobile/features/users/view/widgets/user_account_list_tile.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; diff --git a/lib/features/login/view/verify_identity_page.dart b/lib/features/login/view/verify_identity_page.dart index 455becc..00ed75c 100644 --- a/lib/features/login/view/verify_identity_page.dart +++ b/lib/features/login/view/verify_identity_page.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart'; diff --git a/lib/features/login/view/widgets/form_fields/client_certificate_form_field.dart b/lib/features/login/view/widgets/form_fields/client_certificate_form_field.dart index b0c3753..b29a2f7 100644 --- a/lib/features/login/view/widgets/form_fields/client_certificate_form_field.dart +++ b/lib/features/login/view/widgets/form_fields/client_certificate_form_field.dart @@ -4,7 +4,7 @@ import 'dart:typed_data'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/login/model/client_certificate_form_model.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; diff --git a/lib/features/login/view/widgets/form_fields/server_address_form_field.dart b/lib/features/login/view/widgets/form_fields/server_address_form_field.dart index cff93d8..207d74c 100644 --- a/lib/features/login/view/widgets/form_fields/server_address_form_field.dart +++ b/lib/features/login/view/widgets/form_fields/server_address_form_field.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:hive_flutter/adapters.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; diff --git a/lib/features/login/view/widgets/form_fields/user_credentials_form_field.dart b/lib/features/login/view/widgets/form_fields/user_credentials_form_field.dart index 397d563..e96d7d6 100644 --- a/lib/features/login/view/widgets/form_fields/user_credentials_form_field.dart +++ b/lib/features/login/view/widgets/form_fields/user_credentials_form_field.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:hive_flutter/adapters.dart'; -import 'package:paperless_mobile/core/config/hive/hive_extensions.dart'; +import 'package:paperless_mobile/core/database/hive/hive_extensions.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/login/model/login_form_credentials.dart'; import 'package:paperless_mobile/features/login/view/widgets/form_fields/obscured_input_text_form_field.dart'; import 'package:paperless_mobile/features/login/view/widgets/form_fields/server_address_form_field.dart'; diff --git a/lib/features/login/view/widgets/login_transition_page.dart b/lib/features/login/view/widgets/login_transition_page.dart index 3976418..5bbcb19 100644 --- a/lib/features/login/view/widgets/login_transition_page.dart +++ b/lib/features/login/view/widgets/login_transition_page.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/theme.dart'; class LoginTransitionPage extends StatelessWidget { diff --git a/lib/features/notifications/converters/notification_tap_response_payload.dart b/lib/features/notifications/converters/notification_tap_response_payload.dart index 93e06ae..9ba69f7 100644 --- a/lib/features/notifications/converters/notification_tap_response_payload.dart +++ b/lib/features/notifications/converters/notification_tap_response_payload.dart @@ -1,7 +1,7 @@ import 'package:json_annotation/json_annotation.dart'; import 'package:paperless_mobile/features/notifications/models/notification_actions.dart'; import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/notification_tap_response_payload.dart'; -import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/open_downloaded_document_payload.dart'; +import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/open_directory_notification_response_payload.dart'; class NotificationTapResponsePayloadConverter implements @@ -11,8 +11,8 @@ class NotificationTapResponsePayloadConverter NotificationTapResponsePayload fromJson(Map json) { final type = NotificationResponseOpenAction.values.byName(json['type']); switch (type) { - case NotificationResponseOpenAction.openDownloadedDocumentPath: - return OpenDownloadedDocumentPayload.fromJson( + case NotificationResponseOpenAction.openDirectory: + return OpenDirectoryNotificationResponsePayload.fromJson( json, ); } diff --git a/lib/features/notifications/models/notification_actions.dart b/lib/features/notifications/models/notification_actions.dart index f7f6662..ce632cd 100644 --- a/lib/features/notifications/models/notification_actions.dart +++ b/lib/features/notifications/models/notification_actions.dart @@ -7,5 +7,5 @@ enum NotificationResponseButtonAction { @JsonEnum() enum NotificationResponseOpenAction { - openDownloadedDocumentPath; + openDirectory; } diff --git a/lib/features/notifications/models/notification_channels.dart b/lib/features/notifications/models/notification_channels.dart index 3b8c431..7e49ec5 100644 --- a/lib/features/notifications/models/notification_channels.dart +++ b/lib/features/notifications/models/notification_channels.dart @@ -1,6 +1,7 @@ enum NotificationChannel { task("task_channel", "Paperless tasks"), - documentDownload("document_download_channel", "Document downloads"); + documentDownload("document_download_channel", "Document downloads"), + fileDownload("file_download_channel", "File downloads"); final String id; final String name; diff --git a/lib/features/notifications/models/notification_payloads/notification_tap/open_directory_notification_response_payload.dart b/lib/features/notifications/models/notification_payloads/notification_tap/open_directory_notification_response_payload.dart new file mode 100644 index 0000000..0640663 --- /dev/null +++ b/lib/features/notifications/models/notification_payloads/notification_tap/open_directory_notification_response_payload.dart @@ -0,0 +1,22 @@ +import 'package:json_annotation/json_annotation.dart'; +import 'package:paperless_mobile/features/notifications/models/notification_actions.dart'; +import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/notification_tap_response_payload.dart'; + +part 'open_directory_notification_response_payload.g.dart'; + +@JsonSerializable() +class OpenDirectoryNotificationResponsePayload + extends NotificationTapResponsePayload { + final String filePath; + OpenDirectoryNotificationResponsePayload({ + required this.filePath, + super.type = NotificationResponseOpenAction.openDirectory, + }); + + factory OpenDirectoryNotificationResponsePayload.fromJson( + Map json) => + _$OpenDirectoryNotificationResponsePayloadFromJson(json); + @override + Map toJson() => + _$OpenDirectoryNotificationResponsePayloadToJson(this); +} diff --git a/lib/features/notifications/models/notification_payloads/notification_tap/open_downloaded_document_payload.dart b/lib/features/notifications/models/notification_payloads/notification_tap/open_downloaded_document_payload.dart deleted file mode 100644 index 6612a13..0000000 --- a/lib/features/notifications/models/notification_payloads/notification_tap/open_downloaded_document_payload.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; -import 'package:paperless_mobile/features/notifications/models/notification_actions.dart'; -import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/notification_tap_response_payload.dart'; - -part 'open_downloaded_document_payload.g.dart'; - -@JsonSerializable() -class OpenDownloadedDocumentPayload extends NotificationTapResponsePayload { - final String filePath; - OpenDownloadedDocumentPayload({ - required this.filePath, - super.type = NotificationResponseOpenAction.openDownloadedDocumentPath, - }); - - factory OpenDownloadedDocumentPayload.fromJson(Map json) => - _$OpenDownloadedDocumentPayloadFromJson(json); - @override - Map toJson() => _$OpenDownloadedDocumentPayloadToJson(this); -} diff --git a/lib/features/notifications/services/local_notification_service.dart b/lib/features/notifications/services/local_notification_service.dart index bfad7fc..f94a2a5 100644 --- a/lib/features/notifications/services/local_notification_service.dart +++ b/lib/features/notifications/services/local_notification_service.dart @@ -6,10 +6,10 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:open_filex/open_filex.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/features/notifications/converters/notification_tap_response_payload.dart'; -import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_action/create_document_success_payload.dart'; -import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/open_downloaded_document_payload.dart'; import 'package:paperless_mobile/features/notifications/models/notification_actions.dart'; import 'package:paperless_mobile/features/notifications/models/notification_channels.dart'; +import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_action/create_document_success_payload.dart'; +import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/open_directory_notification_response_payload.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; class LocalNotificationService { @@ -48,6 +48,31 @@ class LocalNotificationService { } Future notifyFileDownload({ + required String filePath, + }) async { + await _plugin.show( + filePath.hashCode, + filePath, + "File download complete.", + NotificationDetails( + android: AndroidNotificationDetails( + NotificationChannel.fileDownload.id + "_${filePath.hashCode}", + NotificationChannel.fileDownload.name, + importance: Importance.max, + priority: Priority.high, + showProgress: false, + when: DateTime.now().millisecondsSinceEpoch, + category: AndroidNotificationCategory.status, + icon: 'file_download_done', + ), + ), + payload: jsonEncode( + OpenDirectoryNotificationResponsePayload(filePath: filePath) + .toJson()), + ); + } + + Future notifyDocumentDownload({ required DocumentModel document, required String filename, required String filePath, @@ -89,7 +114,7 @@ class LocalNotificationService { ), ), payload: jsonEncode( - OpenDownloadedDocumentPayload( + OpenDirectoryNotificationResponsePayload( filePath: filePath, ).toJson(), ), @@ -139,7 +164,7 @@ class LocalNotificationService { ), ), payload: jsonEncode( - OpenDownloadedDocumentPayload(filePath: filePath).toJson(), + OpenDirectoryNotificationResponsePayload(filePath: filePath).toJson(), ), ); } @@ -281,9 +306,10 @@ class LocalNotificationService { NotificationResponse response, ) { switch (type) { - case NotificationResponseOpenAction.openDownloadedDocumentPath: - final payload = OpenDownloadedDocumentPayload.fromJson( - jsonDecode(response.payload!)); + case NotificationResponseOpenAction.openDirectory: + final payload = OpenDirectoryNotificationResponsePayload.fromJson( + jsonDecode(response.payload!), + ); OpenFilex.open(payload.filePath); break; } diff --git a/lib/features/saved_view_details/cubit/saved_view_preview_cubit.dart b/lib/features/saved_view_details/cubit/saved_view_preview_cubit.dart index 2bd8fcd..e762e45 100644 --- a/lib/features/saved_view_details/cubit/saved_view_preview_cubit.dart +++ b/lib/features/saved_view_details/cubit/saved_view_preview_cubit.dart @@ -1,5 +1,8 @@ import 'package:bloc/bloc.dart'; +import 'package:collection/collection.dart'; import 'package:paperless_api/paperless_api.dart'; +import 'package:paperless_mobile/core/extensions/document_iterable_extensions.dart'; +import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart'; import 'package:paperless_mobile/core/service/connectivity_status_service.dart'; part 'saved_view_preview_state.dart'; @@ -8,11 +11,55 @@ class SavedViewPreviewCubit extends Cubit { final PaperlessDocumentsApi _api; final SavedView view; final ConnectivityStatusService _connectivityStatusService; + final DocumentChangedNotifier _changedNotifier; SavedViewPreviewCubit( this._api, - this._connectivityStatusService, { + this._connectivityStatusService, + this._changedNotifier, { required this.view, - }) : super(const InitialSavedViewPreviewState()); + }) : super(const InitialSavedViewPreviewState()) { + _changedNotifier.addListener( + this, + onDeleted: (document) { + final s = state; + if (s is! LoadedSavedViewPreviewState) { + return; + } + if (!s.documents.containsDocument(document)) { + return; + } + emit( + LoadedSavedViewPreviewState( + documents: s.documents.withDocumentRemoved(document).toList(), + ), + ); + }, + onUpdated: (document) { + final s = state; + if (s is! LoadedSavedViewPreviewState) { + return; + } + if (!s.documents.containsDocument(document)) { + return; + } + + final shouldRemainInFilter = view.toDocumentFilter().matches(document); + if (!shouldRemainInFilter) { + emit( + LoadedSavedViewPreviewState( + documents: s.documents.withDocumentRemoved(document).toList(), + ), + ); + } else { + emit( + LoadedSavedViewPreviewState( + documents: s.documents.withDocumentreplaced(document).toList(), + ), + ); + } + }, + ); + } Future initialize() async { final isConnected = diff --git a/lib/features/saved_view_details/view/saved_view_preview.dart b/lib/features/saved_view_details/view/saved_view_preview.dart index 31c5103..49f5ff9 100644 --- a/lib/features/saved_view_details/view/saved_view_preview.dart +++ b/lib/features/saved_view_details/view/saved_view_preview.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/extensions/flutter_extensions.dart'; +import 'package:paperless_mobile/core/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/view/widgets/items/document_list_item.dart'; import 'package:paperless_mobile/features/landing/view/widgets/expansion_card.dart'; @@ -24,6 +24,7 @@ class SavedViewPreview extends StatelessWidget { Widget build(BuildContext context) { return Provider( create: (context) => SavedViewPreviewCubit( + context.read(), context.read(), context.read(), view: savedView, diff --git a/lib/features/settings/model/color_scheme_option.dart b/lib/features/settings/model/color_scheme_option.dart index d1d1327..c63e745 100644 --- a/lib/features/settings/model/color_scheme_option.dart +++ b/lib/features/settings/model/color_scheme_option.dart @@ -1,5 +1,5 @@ import 'package:hive_flutter/adapters.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; part 'color_scheme_option.g.dart'; diff --git a/lib/features/settings/model/file_download_type.dart b/lib/features/settings/model/file_download_type.dart index 3742539..b475399 100644 --- a/lib/features/settings/model/file_download_type.dart +++ b/lib/features/settings/model/file_download_type.dart @@ -1,5 +1,5 @@ import 'package:hive/hive.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; part 'file_download_type.g.dart'; diff --git a/lib/features/settings/model/view_type.dart b/lib/features/settings/model/view_type.dart index 72b13df..e8ad7d7 100644 --- a/lib/features/settings/model/view_type.dart +++ b/lib/features/settings/model/view_type.dart @@ -1,5 +1,5 @@ import 'package:hive/hive.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; part 'view_type.g.dart'; diff --git a/lib/features/settings/view/manage_accounts_page.dart b/lib/features/settings/view/manage_accounts_page.dart index b06fc66..1c0ac86 100644 --- a/lib/features/settings/view/manage_accounts_page.dart +++ b/lib/features/settings/view/manage_accounts_page.dart @@ -1,7 +1,7 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:hive_flutter/adapters.dart'; -import 'package:paperless_mobile/core/config/hive/hive_extensions.dart'; +import 'package:paperless_mobile/core/database/hive/hive_extensions.dart'; import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart'; import 'package:paperless_mobile/features/settings/view/dialogs/switch_account_dialog.dart'; import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart'; diff --git a/lib/features/settings/view/widgets/global_settings_builder.dart b/lib/features/settings/view/widgets/global_settings_builder.dart index 1df0049..6601738 100644 --- a/lib/features/settings/view/widgets/global_settings_builder.dart +++ b/lib/features/settings/view/widgets/global_settings_builder.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:hive_flutter/adapters.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; class GlobalSettingsBuilder extends StatelessWidget { diff --git a/lib/features/settings/view/widgets/user_settings_builder.dart b/lib/features/settings/view/widgets/user_settings_builder.dart index 2201a58..ca4b3ab 100644 --- a/lib/features/settings/view/widgets/user_settings_builder.dart +++ b/lib/features/settings/view/widgets/user_settings_builder.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:hive_flutter/adapters.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; diff --git a/lib/features/sharing/view/widgets/event_listener_shell.dart b/lib/features/sharing/view/widgets/event_listener_shell.dart index 4dff64e..1566e76 100644 --- a/lib/features/sharing/view/widgets/event_listener_shell.dart +++ b/lib/features/sharing/view/widgets/event_listener_shell.dart @@ -9,8 +9,8 @@ import 'package:fluttertoast/fluttertoast.dart'; import 'package:hive/hive.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; -import 'package:paperless_mobile/core/config/hive/hive_extensions.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_extensions.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart'; import 'package:paperless_mobile/core/service/connectivity_status_service.dart'; diff --git a/lib/main.dart b/lib/main.dart index 16746cf..ce8b75b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -21,7 +21,7 @@ import 'package:package_info_plus/package_info_plus.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/constants.dart'; import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart'; @@ -29,9 +29,9 @@ import 'package:paperless_mobile/core/exception/server_message_exception.dart'; import 'package:paperless_mobile/core/factory/paperless_api_factory.dart'; import 'package:paperless_mobile/core/factory/paperless_api_factory_impl.dart'; import 'package:paperless_mobile/core/interceptor/language_header.interceptor.dart'; -import 'package:paperless_mobile/core/logging/data/formatted_printer.dart'; -import 'package:paperless_mobile/core/logging/data/logger.dart'; -import 'package:paperless_mobile/core/logging/data/mirrored_file_output.dart'; +import 'package:paperless_mobile/features/logging/data/formatted_printer.dart'; +import 'package:paperless_mobile/features/logging/data/logger.dart'; +import 'package:paperless_mobile/features/logging/data/mirrored_file_output.dart'; import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart'; import 'package:paperless_mobile/core/security/session_manager.dart'; import 'package:paperless_mobile/core/service/connectivity_status_service.dart'; @@ -129,6 +129,7 @@ void main() async { output: MirroredFileOutput(), printer: FormattedPrinter(), level: l.Level.trace, + filter: l.ProductionFilter(), ); Paint.enableDithering = true; @@ -236,6 +237,12 @@ void main() async { ), ); }, (error, stackTrace) { + if (error is StateError && + error.message.contains("Cannot emit new states")) { + { + return; + } + } // Catches all unexpected/uncaught errors and prints them to the console. final message = switch (error) { PaperlessApiException e => e.details ?? error.toString(), @@ -332,12 +339,6 @@ class _GoRouterShellState extends State { if (context.canPop()) { context.pop(); } - // LoginRoute( - // $extra: errorState.clientCertificate, - // password: errorState.password, - // serverUrl: errorState.serverUrl, - // username: errorState.username, - // ).go(context); break; } }, diff --git a/lib/routes/typed/shells/authenticated_route.dart b/lib/routes/typed/shells/authenticated_route.dart index b1a2ebc..5ad17f4 100644 --- a/lib/routes/typed/shells/authenticated_route.dart +++ b/lib/routes/typed/shells/authenticated_route.dart @@ -5,7 +5,7 @@ import 'package:flutter/widgets.dart'; import 'package:go_router/go_router.dart'; import 'package:hive_flutter/adapters.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/factory/paperless_api_factory.dart'; diff --git a/lib/routes/typed/shells/scaffold_shell_route.dart b/lib/routes/typed/shells/scaffold_shell_route.dart index abf16bd..c85f9c9 100644 --- a/lib/routes/typed/shells/scaffold_shell_route.dart +++ b/lib/routes/typed/shells/scaffold_shell_route.dart @@ -1,7 +1,7 @@ import 'package:flutter/widgets.dart'; import 'package:go_router/go_router.dart'; import 'package:hive/hive.dart'; -import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/hive/hive_config.dart'; import 'package:paperless_mobile/core/database/tables/global_settings.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/features/home/view/scaffold_with_navigation_bar.dart'; diff --git a/lib/routes/typed/top_level/app_logs_route.dart b/lib/routes/typed/top_level/app_logs_route.dart index dd7c2ae..75121ad 100644 --- a/lib/routes/typed/top_level/app_logs_route.dart +++ b/lib/routes/typed/top_level/app_logs_route.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; -import 'package:paperless_mobile/core/logging/cubit/app_logs_cubit.dart'; -import 'package:paperless_mobile/core/logging/view/app_logs_page.dart'; +import 'package:paperless_mobile/features/logging/cubit/app_logs_cubit.dart'; +import 'package:paperless_mobile/features/logging/view/app_logs_page.dart'; import 'package:paperless_mobile/routes/navigation_keys.dart'; import 'package:paperless_mobile/theme.dart'; @@ -17,8 +17,10 @@ class AppLogsRoute extends GoRouteData { return AnnotatedRegion( value: buildOverlayStyle(Theme.of(context)), child: BlocProvider( - create: (context) => - AppLogsCubit(DateTime.now())..loadLogs(DateTime.now()), + create: (context) => AppLogsCubit( + DateTime.now(), + context.read(), + )..loadLogs(DateTime.now()), child: AppLogsPage(key: state.pageKey), ), ); diff --git a/lib/routes/typed/top_level/login_route.dart b/lib/routes/typed/top_level/login_route.dart index 6e05db5..5da96da 100644 --- a/lib/routes/typed/top_level/login_route.dart +++ b/lib/routes/typed/top_level/login_route.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:hive_flutter/adapters.dart'; -import 'package:paperless_mobile/core/config/hive/hive_extensions.dart'; +import 'package:paperless_mobile/core/database/hive/hive_extensions.dart'; import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart'; import 'package:paperless_mobile/features/login/model/client_certificate.dart'; import 'package:paperless_mobile/features/login/view/login_page.dart'; diff --git a/pubspec.lock b/pubspec.lock index a4f0034..cf28eae 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -394,6 +394,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.5" + extended_masked_text: + dependency: "direct main" + description: + name: extended_masked_text + sha256: dba132fffa2b931e8cdd005e0509dfac359d3f98a175eca18c0ac71605247b6b + url: "https://pub.dev" + source: hosted + version: "2.3.1" fake_async: dependency: transitive description: @@ -1223,18 +1231,18 @@ packages: dependency: "direct main" description: name: permission_handler - sha256: bc56bfe9d3f44c3c612d8d393bd9b174eb796d706759f9b495ac254e4294baa5 + sha256: "284a66179cabdf942f838543e10413246f06424d960c92ba95c84439154fcac8" url: "https://pub.dev" source: hosted - version: "10.4.5" + version: "11.0.1" permission_handler_android: dependency: transitive description: name: permission_handler_android - sha256: "59c6322171c29df93a22d150ad95f3aa19ed86542eaec409ab2691b8f35f9a47" + sha256: ace7d15a3d1a4a0b91c041d01e5405df221edb9de9116525efc773c74e6fc790 url: "https://pub.dev" source: hosted - version: "10.3.6" + version: "11.0.5" permission_handler_apple: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index b8363f6..129123b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,7 +31,7 @@ dependencies: sdk: flutter flutter_localizations: sdk: flutter - permission_handler: ^10.2.0 + permission_handler: ^11.0.1 pdf: ^3.10.2 edge_detection: git: @@ -100,6 +100,7 @@ dependencies: flutter_markdown: ^0.6.18 logger: ^2.0.2+1 synchronized: ^3.1.0 + extended_masked_text: ^2.3.1 # camerawesome: ^2.0.0-dev.1 dependency_overrides: