From bea0ab94be879f3d81643c68de7654e2adfd7360 Mon Sep 17 00:00:00 2001 From: Anton Stubenbord Date: Fri, 28 Apr 2023 20:45:47 +0200 Subject: [PATCH] feat+fix: Add option to set default download/share file type, fix typo in filter to query string, disable unused options in document filter --- lib/core/config/hive/hive_config.dart | 3 + lib/core/database/tables/global_settings.dart | 9 ++ .../widgets/bulk_edit_label_bottom_sheet.dart | 1 + .../view/dialogs/select_file_type_dialog.dart | 73 +++++++++-- .../view/pages/document_details_page.dart | 1 - .../widgets/document_download_button.dart | 44 +++++-- .../view/widgets/document_share_button.dart | 49 +++++-- .../view/document_edit_page.dart | 3 + .../document_upload_preparation_page.dart | 2 + .../widgets/search/document_filter_form.dart | 23 ++-- .../view/widgets/fullscreen_label_form.dart | 32 +++-- .../labels/view/widgets/label_form_field.dart | 3 + .../settings/model/file_download_type.dart | 14 ++ .../view/pages/application_settings_page.dart | 11 +- .../default_download_file_type_setting.dart | 64 +++++++++ .../default_share_file_type_setting.dart | 64 +++++++++ .../view/widgets/radio_settings_dialog.dart | 3 +- lib/main.dart | 8 +- .../query_parameters/id_query_parameter.dart | 5 +- pubspec.lock | 122 +----------------- 20 files changed, 337 insertions(+), 197 deletions(-) create mode 100644 lib/features/settings/model/file_download_type.dart create mode 100644 lib/features/settings/view/widgets/default_download_file_type_setting.dart create mode 100644 lib/features/settings/view/widgets/default_share_file_type_setting.dart diff --git a/lib/core/config/hive/hive_config.dart b/lib/core/config/hive/hive_config.dart index 1c071d5..dc231af 100644 --- a/lib/core/config/hive/hive_config.dart +++ b/lib/core/config/hive/hive_config.dart @@ -9,6 +9,7 @@ import 'package:paperless_mobile/features/login/model/client_certificate.dart'; import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/features/settings/model/color_scheme_option.dart'; import 'package:paperless_mobile/core/database/tables/local_user_settings.dart'; +import 'package:paperless_mobile/features/settings/model/file_download_type.dart'; import 'package:paperless_mobile/features/settings/model/view_type.dart'; class HiveBoxes { @@ -33,6 +34,7 @@ class HiveTypeIds { static const localUserAccount = 7; static const localUserAppState = 8; static const viewType = 9; + static const fileDownloadType = 10; } void registerHiveAdapters() { @@ -47,6 +49,7 @@ void registerHiveAdapters() { Hive.registerAdapter(LocalUserAccountAdapter()); Hive.registerAdapter(LocalUserAppStateAdapter()); Hive.registerAdapter(ViewTypeAdapter()); + Hive.registerAdapter(FileDownloadTypeAdapter()); } extension HiveSingleValueBox on Box { diff --git a/lib/core/database/tables/global_settings.dart b/lib/core/database/tables/global_settings.dart index c0ea054..369e8c5 100644 --- a/lib/core/database/tables/global_settings.dart +++ b/lib/core/database/tables/global_settings.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:hive/hive.dart'; import 'package:paperless_mobile/core/config/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'; part 'global_settings.g.dart'; @@ -22,11 +23,19 @@ class GlobalSettings with HiveObjectMixin { @HiveField(4) String? currentLoggedInUser; + @HiveField(5) + FileDownloadType defaultDownloadType; + + @HiveField(6) + FileDownloadType defaultShareType; + GlobalSettings({ required this.preferredLocaleSubtag, this.preferredThemeMode = ThemeMode.system, this.preferredColorSchemeOption = ColorSchemeOption.classic, this.showOnboarding = true, this.currentLoggedInUser, + this.defaultDownloadType = FileDownloadType.alwaysAsk, + this.defaultShareType = FileDownloadType.alwaysAsk, }); } diff --git a/lib/features/document_bulk_action/view/widgets/bulk_edit_label_bottom_sheet.dart b/lib/features/document_bulk_action/view/widgets/bulk_edit_label_bottom_sheet.dart index e0bf799..77112c4 100644 --- a/lib/features/document_bulk_action/view/widgets/bulk_edit_label_bottom_sheet.dart +++ b/lib/features/document_bulk_action/view/widgets/bulk_edit_label_bottom_sheet.dart @@ -62,6 +62,7 @@ class _BulkEditLabelBottomSheetState extends State createState() => _SelectFileTypeDialogState(); +} + +class _SelectFileTypeDialogState extends State { + bool _rememberSelection = false; + FileDownloadType _downloadType = FileDownloadType.original; @override Widget build(BuildContext context) { - return RadioSettingsDialog( - titleText: S.of(context)!.chooseFiletype, - options: [ - RadioOption( - value: true, - label: S.of(context)!.original, - ), - RadioOption( - value: false, - label: S.of(context)!.archivedPdf, + return AlertDialog( + title: Text(S.of(context)!.chooseFiletype), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + RadioListTile( + value: FileDownloadType.original, + groupValue: _downloadType, + onChanged: (value) { + if (value != null) { + setState(() => _downloadType = value); + } + }, + title: Text(S.of(context)!.original), + ), + RadioListTile( + value: FileDownloadType.archived, + groupValue: _downloadType, + onChanged: (value) { + if (value != null) { + setState(() => _downloadType = value); + } + }, + title: Text(S.of(context)!.archivedPdf), + ), + Divider(), + CheckboxListTile( + controlAffinity: ListTileControlAffinity.leading, + value: _rememberSelection, + onChanged: (value) => setState(() => _rememberSelection = value ?? false), + title: Text( + "Remember my decision", + style: Theme.of(context).textTheme.labelMedium, + ), //TODO: INTL + ), + ], + ), + actions: [ + const DialogCancelButton(), + ElevatedButton( + child: Text(S.of(context)!.select), + onPressed: () { + if (_rememberSelection) { + widget.onRememberSelection(_downloadType); + } + Navigator.of(context).pop(_downloadType == FileDownloadType.original); + }, ), ], - initialValue: false, ); } } 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 5596b29..465e2c1 100644 --- a/lib/features/document_details/view/pages/document_details_page.dart +++ b/lib/features/document_details/view/pages/document_details_page.dart @@ -1,4 +1,3 @@ -import 'package:badges/badges.dart' as b; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:open_filex/open_filex.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 fa80279..217e129 100644 --- a/lib/features/document_details/view/widgets/document_download_button.dart +++ b/lib/features/document_details/view/widgets/document_download_button.dart @@ -1,11 +1,14 @@ 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/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'; +import 'package:paperless_mobile/features/settings/model/file_download_type.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; import 'package:paperless_mobile/helpers/message_helpers.dart'; @@ -50,25 +53,46 @@ class _DocumentDownloadButtonState extends State { Future _onDownload(DocumentModel document) async { try { - final downloadOriginal = await showDialog( - context: context, - builder: (context) => const SelectFileTypeDialog(), - ); - if (downloadOriginal == null) { - // Download was cancelled - return; + final globalSettings = Hive.box(HiveBoxes.globalSettings).getValue()!; + bool original; + + switch (globalSettings.defaultDownloadType) { + case FileDownloadType.original: + original = true; + break; + case FileDownloadType.archived: + original = false; + break; + case FileDownloadType.alwaysAsk: + final isOriginal = await showDialog( + context: context, + builder: (context) => SelectFileTypeDialog( + onRememberSelection: (downloadType) { + globalSettings.defaultDownloadType = downloadType; + globalSettings.save(); + }, + ), + ); + if (isOriginal == null) { + return; + } else { + original = isOriginal; + } + break; } + if (Platform.isAndroid && androidInfo!.version.sdkInt! <= 29) { final isGranted = await askForPermission(Permission.storage); if (!isGranted) { return; - //TODO: Tell user to grant permissions + //TODO: Ask user to grant permissions } } + setState(() => _isDownloadPending = true); await context.read().downloadDocument( - downloadOriginal: downloadOriginal, - locale: context.read().preferredLocaleSubtag, + downloadOriginal: original, + locale: globalSettings.preferredLocaleSubtag, ); // showSnackBar(context, S.of(context)!.documentSuccessfullyDownloaded); } on PaperlessServerException catch (error, stackTrace) { 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 a914a75..addd4f2 100644 --- a/lib/features/document_details/view/widgets/document_share_button.dart +++ b/lib/features/document_details/view/widgets/document_share_button.dart @@ -1,11 +1,15 @@ import 'dart:io'; 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/tables/global_settings.dart'; import 'package:paperless_mobile/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'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; import 'package:paperless_mobile/helpers/message_helpers.dart'; import 'package:paperless_mobile/helpers/permission_helpers.dart'; @@ -39,22 +43,41 @@ class _DocumentShareButtonState extends State { child: CircularProgressIndicator(), ) : const Icon(Icons.share), - onPressed: widget.document != null && widget.enabled - ? () => _onShare(widget.document!) - : null, + onPressed: + widget.document != null && widget.enabled ? () => _onShare(widget.document!) : null, ).paddedOnly(right: 4); } Future _onShare(DocumentModel document) async { try { - final shareOriginal = await showDialog( - context: context, - builder: (context) => const SelectFileTypeDialog(), - ); - if (shareOriginal == null) { - // Download was cancelled - return; + final globalSettings = Hive.box(HiveBoxes.globalSettings).getValue()!; + bool original; + + switch (globalSettings.defaultShareType) { + case FileDownloadType.original: + original = true; + break; + case FileDownloadType.archived: + original = false; + break; + case FileDownloadType.alwaysAsk: + final isOriginal = await showDialog( + context: context, + builder: (context) => SelectFileTypeDialog( + onRememberSelection: (downloadType) { + globalSettings.defaultShareType = downloadType; + globalSettings.save(); + }, + ), + ); + if (isOriginal == null) { + return; + } else { + original = isOriginal; + } + break; } + if (Platform.isAndroid && androidInfo!.version.sdkInt! < 30) { final isGranted = await askForPermission(Permission.storage); if (!isGranted) { @@ -62,9 +85,9 @@ class _DocumentShareButtonState extends State { } } setState(() => _isDownloadPending = true); - await context - .read() - .shareDocument(shareOriginal: shareOriginal); + await context.read().shareDocument( + shareOriginal: original, + ); } on PaperlessServerException catch (error, stackTrace) { showErrorMessage(context, error, stackTrace); } catch (error) { diff --git a/lib/features/document_edit/view/document_edit_page.dart b/lib/features/document_edit/view/document_edit_page.dart index 1bd02d1..f40ca2d 100644 --- a/lib/features/document_edit/view/document_edit_page.dart +++ b/lib/features/document_edit/view/document_edit_page.dart @@ -116,6 +116,7 @@ class _DocumentEditPageState extends State { : const IdQueryParameter.unset(), name: fkCorrespondent, prefixIcon: const Icon(Icons.person_outlined), + allowSelectUnassigned: true, ), if (_filteredSuggestions?.hasSuggestedCorrespondents ?? false) _buildSuggestionsSkeleton( @@ -151,6 +152,7 @@ class _DocumentEditPageState extends State { options: state.documentTypes, name: _DocumentEditPageState.fkDocumentType, prefixIcon: const Icon(Icons.description_outlined), + allowSelectUnassigned: true, ), if (_filteredSuggestions?.hasSuggestedDocumentTypes ?? false) _buildSuggestionsSkeleton( @@ -183,6 +185,7 @@ class _DocumentEditPageState extends State { : const IdQueryParameter.unset(), name: fkStoragePath, prefixIcon: const Icon(Icons.folder_outlined), + allowSelectUnassigned: true, ), ], ).padded(), 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 881fe2b..e1dd0f2 100644 --- a/lib/features/document_upload/view/document_upload_preparation_page.dart +++ b/lib/features/document_upload/view/document_upload_preparation_page.dart @@ -191,6 +191,7 @@ class _DocumentUploadPreparationPageState extends State( @@ -205,6 +206,7 @@ class _DocumentUploadPreparationPageState extends State { } void _checkQueryConstraints() { - final filter = - DocumentFilterForm.assembleFilter(widget.formKey, widget.initialFilter); + final filter = DocumentFilterForm.assembleFilter(widget.formKey, widget.initialFilter); if (filter.forceExtendedQuery) { setState(() => _allowOnlyExtendedQuery = true); - final queryField = - widget.formKey.currentState?.fields[DocumentFilterForm.fkQuery]; + final queryField = widget.formKey.currentState?.fields[DocumentFilterForm.fkQuery]; queryField?.didChange( - (queryField.value as TextQuery?) - ?.copyWith(queryType: QueryType.extended), + (queryField.value as TextQuery?)?.copyWith(queryType: QueryType.extended), ); } else { setState(() => _allowOnlyExtendedQuery = false); @@ -161,6 +155,7 @@ class _DocumentFilterFormState extends State { labelText: S.of(context)!.documentType, initialValue: widget.initialFilter.documentType, prefixIcon: const Icon(Icons.description_outlined), + allowSelectUnassigned: false, ); } @@ -171,6 +166,7 @@ class _DocumentFilterFormState extends State { labelText: S.of(context)!.correspondent, initialValue: widget.initialFilter.correspondent, prefixIcon: const Icon(Icons.person_outline), + allowSelectUnassigned: false, ); } @@ -181,6 +177,7 @@ class _DocumentFilterFormState extends State { labelText: S.of(context)!.storagePath, initialValue: widget.initialFilter.storagePath, prefixIcon: const Icon(Icons.folder_outlined), + allowSelectUnassigned: false, ); } diff --git a/lib/features/labels/view/widgets/fullscreen_label_form.dart b/lib/features/labels/view/widgets/fullscreen_label_form.dart index b7b694d..1509cd2 100644 --- a/lib/features/labels/view/widgets/fullscreen_label_form.dart +++ b/lib/features/labels/view/widgets/fullscreen_label_form.dart @@ -15,6 +15,7 @@ class FullscreenLabelForm extends StatefulWidget { final Widget leadingIcon; final String? addNewLabelText; final bool autofocus; + final bool allowSelectUnassigned; FullscreenLabelForm({ super.key, @@ -27,6 +28,7 @@ class FullscreenLabelForm extends StatefulWidget { required this.leadingIcon, this.addNewLabelText, this.autofocus = true, + this.allowSelectUnassigned = true, }) : assert( !(initialValue?.isOnlyAssigned() ?? false) || showAnyAssignedOption, ), @@ -248,16 +250,26 @@ class _FullscreenLabelFormState extends State S.of(context)!.notAssigned, - anyAssigned: () => S.of(context)!.anyAssigned, - fromId: (id) => widget.options[id]!.name, + return option.whenOrNull( + notAssigned: () => ListTile( + selected: highlight, + selectedTileColor: Theme.of(context).focusColor, + title: Text(S.of(context)!.notAssigned), + onTap: onTap, + ), + anyAssigned: () => ListTile( + selected: highlight, + selectedTileColor: Theme.of(context).focusColor, + title: Text(S.of(context)!.anyAssigned), + onTap: onTap, + ), + fromId: (id) => ListTile( + selected: highlight, + selectedTileColor: Theme.of(context).focusColor, + title: Text(widget.options[id]!.name), + onTap: onTap, + enabled: widget.allowSelectUnassigned ? true : widget.options[id]!.documentCount == 0, + ), )!; // Never null, since we already return on unset before - return ListTile( - selected: highlight, - selectedTileColor: Theme.of(context).focusColor, - title: Text(title), - onTap: onTap, - ); } } diff --git a/lib/features/labels/view/widgets/label_form_field.dart b/lib/features/labels/view/widgets/label_form_field.dart index 66a3252..29a839d 100644 --- a/lib/features/labels/view/widgets/label_form_field.dart +++ b/lib/features/labels/view/widgets/label_form_field.dart @@ -27,6 +27,7 @@ class LabelFormField extends StatelessWidget { final bool showAnyAssignedOption; final List suggestions; final String? addLabelText; + final bool allowSelectUnassigned; const LabelFormField({ Key? key, @@ -42,6 +43,7 @@ class LabelFormField extends StatelessWidget { this.showAnyAssignedOption = true, this.suggestions = const [], this.addLabelText, + required this.allowSelectUnassigned, }) : super(key: key); String _buildText(BuildContext context, IdQueryParameter? value) { @@ -100,6 +102,7 @@ class LabelFormField extends StatelessWidget { ), ), openBuilder: (context, closeForm) => FullscreenLabelForm( + allowSelectUnassigned: allowSelectUnassigned, addNewLabelText: addLabelText, leadingIcon: prefixIcon, onCreateNewLabel: addLabelPageBuilder != null diff --git a/lib/features/settings/model/file_download_type.dart b/lib/features/settings/model/file_download_type.dart new file mode 100644 index 0000000..3742539 --- /dev/null +++ b/lib/features/settings/model/file_download_type.dart @@ -0,0 +1,14 @@ +import 'package:hive/hive.dart'; +import 'package:paperless_mobile/core/config/hive/hive_config.dart'; + +part 'file_download_type.g.dart'; + +@HiveType(typeId: HiveTypeIds.fileDownloadType) +enum FileDownloadType { + @HiveField(1) + original, + @HiveField(2) + archived, + @HiveField(3) + alwaysAsk; +} diff --git a/lib/features/settings/view/pages/application_settings_page.dart b/lib/features/settings/view/pages/application_settings_page.dart index 1cc2220..d55675a 100644 --- a/lib/features/settings/view/pages/application_settings_page.dart +++ b/lib/features/settings/view/pages/application_settings_page.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; import 'package:paperless_mobile/features/settings/view/widgets/color_scheme_option_setting.dart'; +import 'package:paperless_mobile/features/settings/view/widgets/default_download_file_type_setting.dart'; +import 'package:paperless_mobile/features/settings/view/widgets/default_share_file_type_setting.dart'; import 'package:paperless_mobile/features/settings/view/widgets/language_selection_setting.dart'; import 'package:paperless_mobile/features/settings/view/widgets/theme_mode_setting.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; @@ -12,10 +14,10 @@ class ApplicationSettingsPage extends StatelessWidget { return Scaffold( appBar: AppBar( title: Text(S.of(context)!.applicationSettings), - actions: [ + actions: const [ Padding( - padding: const EdgeInsets.all(16.0), - child: const Icon(Icons.public), + padding: EdgeInsets.all(16.0), + child: Icon(Icons.public), ) ], ), @@ -24,6 +26,9 @@ class ApplicationSettingsPage extends StatelessWidget { LanguageSelectionSetting(), ThemeModeSetting(), ColorSchemeOptionSetting(), + Divider(), + DefaultDownloadFileTypeSetting(), + DefaultShareFileTypeSetting(), ], ), ); diff --git a/lib/features/settings/view/widgets/default_download_file_type_setting.dart b/lib/features/settings/view/widgets/default_download_file_type_setting.dart new file mode 100644 index 0000000..9335ab4 --- /dev/null +++ b/lib/features/settings/view/widgets/default_download_file_type_setting.dart @@ -0,0 +1,64 @@ +import 'package:flutter/material.dart'; +import 'package:paperless_mobile/features/settings/model/file_download_type.dart'; +import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart'; +import 'package:paperless_mobile/features/settings/view/widgets/radio_settings_dialog.dart'; +import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; + +class DefaultDownloadFileTypeSetting extends StatelessWidget { + const DefaultDownloadFileTypeSetting({super.key}); + + @override + Widget build(BuildContext context) { + return GlobalSettingsBuilder( + builder: (context, settings) { + return ListTile( + title: Text("Default download file type"), + subtitle: Text( + _downloadFileTypeToString(context, settings.defaultDownloadType), + ), + onTap: () async { + final selectedValue = await showDialog( + context: context, + builder: (context) { + return RadioSettingsDialog( + titleText: "Default download file type", + options: [ + RadioOption( + value: FileDownloadType.alwaysAsk, + label: "Always ask", + ), + RadioOption( + value: FileDownloadType.original, + label: S.of(context)!.original, + ), + RadioOption( + value: FileDownloadType.archived, + label: S.of(context)!.archivedPdf, + ), + ], + initialValue: settings.defaultDownloadType, + ); + }, + ); + if (selectedValue != null) { + settings + ..defaultDownloadType = selectedValue + ..save(); + } + }, + ); + }, + ); + } + + String _downloadFileTypeToString(BuildContext context, FileDownloadType type) { + switch (type) { + case FileDownloadType.original: + return S.of(context)!.original; + case FileDownloadType.archived: + return S.of(context)!.archivedPdf; + case FileDownloadType.alwaysAsk: + return "Always ask"; + } + } +} diff --git a/lib/features/settings/view/widgets/default_share_file_type_setting.dart b/lib/features/settings/view/widgets/default_share_file_type_setting.dart new file mode 100644 index 0000000..21d689f --- /dev/null +++ b/lib/features/settings/view/widgets/default_share_file_type_setting.dart @@ -0,0 +1,64 @@ +import 'package:flutter/material.dart'; +import 'package:paperless_mobile/features/settings/model/file_download_type.dart'; +import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart'; +import 'package:paperless_mobile/features/settings/view/widgets/radio_settings_dialog.dart'; +import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; + +class DefaultShareFileTypeSetting extends StatelessWidget { + const DefaultShareFileTypeSetting({super.key}); + + @override + Widget build(BuildContext context) { + return GlobalSettingsBuilder( + builder: (context, settings) { + return ListTile( + title: Text("Default share file type"), + subtitle: Text( + _downloadFileTypeToString(context, settings.defaultShareType), + ), + onTap: () async { + final selectedValue = await showDialog( + context: context, + builder: (context) { + return RadioSettingsDialog( + titleText: "Default share file type", + options: [ + RadioOption( + value: FileDownloadType.alwaysAsk, + label: "Always ask", + ), + RadioOption( + value: FileDownloadType.original, + label: S.of(context)!.original, + ), + RadioOption( + value: FileDownloadType.archived, + label: S.of(context)!.archivedPdf, + ), + ], + initialValue: settings.defaultShareType, + ); + }, + ); + if (selectedValue != null) { + settings + ..defaultDownloadType = selectedValue + ..save(); + } + }, + ); + }, + ); + } + + String _downloadFileTypeToString(BuildContext context, FileDownloadType type) { + switch (type) { + case FileDownloadType.original: + return S.of(context)!.original; + case FileDownloadType.archived: + return S.of(context)!.archivedPdf; + case FileDownloadType.alwaysAsk: + return "Always ask"; + } + } +} diff --git a/lib/features/settings/view/widgets/radio_settings_dialog.dart b/lib/features/settings/view/widgets/radio_settings_dialog.dart index 350147c..96329bc 100644 --- a/lib/features/settings/view/widgets/radio_settings_dialog.dart +++ b/lib/features/settings/view/widgets/radio_settings_dialog.dart @@ -51,8 +51,7 @@ class _RadioSettingsDialogState extends State> { mainAxisSize: MainAxisSize.min, children: [ if (widget.descriptionText != null) - Text(widget.descriptionText!, - style: Theme.of(context).textTheme.bodySmall), + Text(widget.descriptionText!, style: Theme.of(context).textTheme.bodySmall), ...widget.options.map(_buildOptionListTile), if (widget.footer != null) widget.footer!, ], diff --git a/lib/main.dart b/lib/main.dart index c9c1c26..78efaec 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart' as cm; import 'package:flutter_displaymode/flutter_displaymode.dart'; -import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_native_splash/flutter_native_splash.dart'; import 'package:hive_flutter/adapters.dart'; import 'package:hydrated_bloc/hydrated_bloc.dart'; @@ -18,8 +17,9 @@ 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/bloc/server_information_cubit.dart'; import 'package:paperless_mobile/core/config/hive/hive_config.dart'; +import 'package:paperless_mobile/core/database/tables/global_settings.dart'; +import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart'; import 'package:paperless_mobile/core/interceptor/dio_http_error_interceptor.dart'; import 'package:paperless_mobile/core/interceptor/language_header.interceptor.dart'; @@ -31,20 +31,16 @@ import 'package:paperless_mobile/core/service/connectivity_status_service.dart'; import 'package:paperless_mobile/core/service/dio_file_service.dart'; import 'package:paperless_mobile/core/type/types.dart'; import 'package:paperless_mobile/features/app_intro/application_intro_slideshow.dart'; -import 'package:paperless_mobile/features/home/view/home_page.dart'; import 'package:paperless_mobile/features/home/view/home_route.dart'; import 'package:paperless_mobile/features/home/view/widget/verify_identity_page.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/model/login_form_credentials.dart'; -import 'package:paperless_mobile/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/features/login/services/authentication_service.dart'; import 'package:paperless_mobile/features/login/view/login_page.dart'; import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart'; -import 'package:paperless_mobile/core/database/tables/global_settings.dart'; import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart'; import 'package:paperless_mobile/features/sharing/share_intent_queue.dart'; -import 'package:paperless_mobile/features/tasks/cubit/task_status_cubit.dart'; import 'package:paperless_mobile/generated/l10n/app_localizations.dart'; import 'package:paperless_mobile/helpers/message_helpers.dart'; import 'package:paperless_mobile/routes/document_details_route.dart'; diff --git a/packages/paperless_api/lib/src/models/query_parameters/id_query_parameter.dart b/packages/paperless_api/lib/src/models/query_parameters/id_query_parameter.dart index e18261c..6fae3bf 100644 --- a/packages/paperless_api/lib/src/models/query_parameters/id_query_parameter.dart +++ b/packages/paperless_api/lib/src/models/query_parameters/id_query_parameter.dart @@ -26,10 +26,7 @@ class IdQueryParameter with _$IdQueryParameter { '${field}__isnull': '0', }, fromId: (id) { - if (id == null) { - return {}; - } - return {'${field}_id': '$id'}; + return {'${field}__id': '$id'}; }, ); } diff --git a/pubspec.lock b/pubspec.lock index 6ccb921..4526cf1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -57,14 +57,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.0" - asn1lib: - dependency: transitive - description: - name: asn1lib - sha256: ab96a1cb3beeccf8145c52e449233fe68364c9641623acd3adad66f8184f1039 - url: "https://pub.dev" - source: hosted - version: "1.4.0" async: dependency: transitive description: @@ -442,22 +434,6 @@ packages: url: "https://github.com/sawankumarbundelkhandi/edge_detection" source: git version: "1.1.1" - encrypt: - dependency: transitive - description: - name: encrypt - sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb" - url: "https://pub.dev" - source: hosted - version: "5.0.1" - encrypted_shared_preferences: - dependency: "direct main" - description: - name: encrypted_shared_preferences - sha256: f4109e4d176a81b203ee120b79b30c1ab93dfd9eee03cac5b8c10a888c231639 - url: "https://pub.dev" - source: hosted - version: "3.0.1" equatable: dependency: "direct main" description: @@ -729,14 +705,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" - flutter_staggered_grid_view: - dependency: "direct main" - description: - name: flutter_staggered_grid_view - sha256: "1312314293acceb65b92754298754801b0e1f26a1845833b740b30415bbbcf07" - url: "https://pub.dev" - source: hosted - version: "0.6.2" flutter_svg: dependency: "direct main" description: @@ -864,14 +832,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.13.5" - http_interceptor: - dependency: "direct main" - description: - name: http_interceptor - sha256: "94b5b191abb2d18a76780a2c5feffb900e54cad16f61ffcfc16997785e21d383" - url: "https://pub.dev" - source: hosted - version: "2.0.0-beta.6" http_multi_server: dependency: transitive description: @@ -904,22 +864,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.3.0" - in_app_review: - dependency: "direct main" - description: - name: in_app_review - sha256: "16328b8202d36522322b95804ae5d975577aa9f584d634985849ba1099645850" - url: "https://pub.dev" - source: hosted - version: "2.0.6" - in_app_review_platform_interface: - dependency: transitive - description: - name: in_app_review_platform_interface - sha256: b12ec9aaf6b34d3a72aa95895eb252b381896246bdad4ef378d444affe8410ef - url: "https://pub.dev" - source: hosted - version: "2.0.4" integration_test: dependency: "direct dev" description: flutter @@ -1062,7 +1006,7 @@ packages: source: hosted version: "1.8.0" mime: - dependency: "direct main" + dependency: transitive description: name: mime sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e @@ -1364,14 +1308,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.3" - pointycastle: - dependency: transitive - description: - name: pointycastle - sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346 - url: "https://pub.dev" - source: hosted - version: "3.6.2" pool: dependency: transitive description: @@ -1476,62 +1412,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.2.0" - shared_preferences: - dependency: transitive - description: - name: shared_preferences - sha256: "5949029e70abe87f75cfe59d17bf5c397619c4b74a099b10116baeb34786fad9" - url: "https://pub.dev" - source: hosted - version: "2.0.17" - shared_preferences_android: - dependency: transitive - description: - name: shared_preferences_android - sha256: "955e9736a12ba776bdd261cf030232b30eadfcd9c79b32a3250dd4a494e8c8f7" - url: "https://pub.dev" - source: hosted - version: "2.0.15" - shared_preferences_foundation: - dependency: transitive - description: - name: shared_preferences_foundation - sha256: "2b55c18636a4edc529fa5cd44c03d3f3100c00513f518c5127c951978efcccd0" - url: "https://pub.dev" - source: hosted - version: "2.1.3" - shared_preferences_linux: - dependency: transitive - description: - name: shared_preferences_linux - sha256: f8ea038aa6da37090093974ebdcf4397010605fd2ff65c37a66f9d28394cb874 - url: "https://pub.dev" - source: hosted - version: "2.1.3" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - sha256: da9431745ede5ece47bc26d5d73a9d3c6936ef6945c101a5aca46f62e52c1cf3 - url: "https://pub.dev" - source: hosted - version: "2.1.0" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - sha256: a4b5bc37fe1b368bbc81f953197d55e12f49d0296e7e412dfe2d2d77d6929958 - url: "https://pub.dev" - source: hosted - version: "2.0.4" - shared_preferences_windows: - dependency: transitive - description: - name: shared_preferences_windows - sha256: "5eaf05ae77658d3521d0e993ede1af962d4b326cd2153d312df716dc250f00c9" - url: "https://pub.dev" - source: hosted - version: "2.1.3" shelf: dependency: transitive description: