From dc552dc4a7a064162c48a2ae8c2413503ec4bf64 Mon Sep 17 00:00:00 2001 From: "konrad.lys@eu.equinix.com" Date: Thu, 1 Jun 2023 12:59:29 +0200 Subject: [PATCH] FEATURE download a document pdf file without uploading it to server --- lib/core/navigation/push_routes.dart | 1 + .../cubit/document_upload_cubit.dart | 18 +++++- .../document_upload_preparation_page.dart | 56 +++++++++++++++++++ .../services/local_notification_service.dart | 44 +++++++++++++++ packages/mock_server/pubspec.yaml | 2 +- 5 files changed, 119 insertions(+), 2 deletions(-) diff --git a/lib/core/navigation/push_routes.dart b/lib/core/navigation/push_routes.dart index 07b5beb..17b03a1 100644 --- a/lib/core/navigation/push_routes.dart +++ b/lib/core/navigation/push_routes.dart @@ -347,6 +347,7 @@ Future pushDocumentUploadPreparationPage( create: (_) => DocumentUploadCubit( context.read(), context.read(), + context.read(), ), child: DocumentUploadPreparationPage( fileBytes: bytes, diff --git a/lib/features/document_upload/cubit/document_upload_cubit.dart b/lib/features/document_upload/cubit/document_upload_cubit.dart index e066c15..0bc5a23 100644 --- a/lib/features/document_upload/cubit/document_upload_cubit.dart +++ b/lib/features/document_upload/cubit/document_upload_cubit.dart @@ -5,6 +5,8 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/repository/label_repository.dart'; +import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart'; +import 'package:paperless_mobile/core/service/file_service.dart'; part 'document_upload_state.dart'; @@ -13,7 +15,9 @@ class DocumentUploadCubit extends Cubit { final LabelRepository _labelRepository; - DocumentUploadCubit(this._labelRepository, this._documentApi) + final LocalNotificationService _notificationService; + + DocumentUploadCubit(this._labelRepository, this._documentApi, this._notificationService) : super(const DocumentUploadState()) { _labelRepository.addListener( this, @@ -49,6 +53,18 @@ class DocumentUploadCubit extends Cubit { ); } + Future saveLocally( + Uint8List bytes, String fileName, String preferredLocaleSubtag + ) async { + var file = await FileService.saveToFile(bytes, fileName); + _notificationService.notifyFileSaved( + filename: fileName, + filePath: file.path, + finished: true, + locale: preferredLocaleSubtag, + ); + } + @override Future close() async { _labelRepository.removeListener(this); 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 cb5be3a..0b94bce 100644 --- a/lib/features/document_upload/view/document_upload_preparation_page.dart +++ b/lib/features/document_upload/view/document_upload_preparation_page.dart @@ -1,12 +1,17 @@ +import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; +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/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/core/database/tables/local_user_account.dart'; import 'package:paperless_mobile/core/repository/label_repository.dart'; import 'package:paperless_mobile/core/type/types.dart'; @@ -19,6 +24,8 @@ import 'package:paperless_mobile/features/labels/view/widgets/label_form_field.d 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'; +import 'package:permission_handler/permission_handler.dart'; class DocumentUploadResult { final bool success; @@ -75,6 +82,8 @@ class _DocumentUploadPreparationPageState extends State _buildBottomAppBar() { + return BlocBuilder( + builder: (context, state) { + return BottomAppBar( + child: BlocBuilder( + builder: (context, connectivityState) { + return Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + IconButton( + tooltip: "Save a local copy", + icon: const Icon(Icons.download), + onPressed: () => _onLocalSave(), + ).paddedOnly(right: 4.0), + ], + ); + }, + ), + ); + }, + ); + } + + String _padWithExtension(String source, [String? extension]) { final ext = extension ?? '.pdf'; return source.endsWith(ext) ? source : '$source$ext'; @@ -299,4 +332,27 @@ class _DocumentUploadPreparationPageState extends State _onLocalSave() async { + final cubit = context.read(); + + try { + final globalSettings = Hive.box(HiveBoxes.globalSettings).getValue()!; + if (Platform.isAndroid && androidInfo!.version.sdkInt <= 29) { + final isGranted = await askForPermission(Permission.storage); + if (!isGranted) { + return; + //TODO: Ask user to grant permissions + } + } + final title = (_formKey.currentState?.fields[fkFileName]?.value ?? widget.filename) as String; + + var fileName = "$title.${widget.fileExtension}"; + + await cubit.saveLocally(widget.fileBytes, fileName, globalSettings.preferredLocaleSubtag); + } catch (error) { + showGenericError(context, error); + } + } + } diff --git a/lib/features/notifications/services/local_notification_service.dart b/lib/features/notifications/services/local_notification_service.dart index 089132c..9f69782 100644 --- a/lib/features/notifications/services/local_notification_service.dart +++ b/lib/features/notifications/services/local_notification_service.dart @@ -90,6 +90,50 @@ class LocalNotificationService { ); //TODO: INTL } + Future notifyFileSaved({ + required String filename, + required String filePath, + required bool finished, + required String locale, + }) async { + final tr = await S.delegate.load(Locale(locale)); + + await _plugin.show( + filePath.hashCode, + filename, + finished + ? tr.notificationDownloadComplete + : tr.notificationDownloadingDocument, + NotificationDetails( + android: AndroidNotificationDetails( + NotificationChannel.documentDownload.id + "_$filename", + NotificationChannel.documentDownload.name, + ongoing: !finished, + indeterminate: true, + importance: Importance.max, + priority: Priority.high, + showProgress: !finished, + when: DateTime.now().millisecondsSinceEpoch, + category: AndroidNotificationCategory.progress, + icon: finished ? 'file_download_done' : 'downloading', + ), + iOS: DarwinNotificationDetails( + attachments: [ + DarwinNotificationAttachment( + filePath, + ), + ], + ), + ), + payload: jsonEncode( + OpenDownloadedDocumentPayload( + filePath: filePath, + ).toJson(), + ), + ); //TODO: INTL + } + + //TODO: INTL Future notifyTaskChanged(Task task) { log("[LocalNotificationService] notifyTaskChanged: ${task.toString()}"); diff --git a/packages/mock_server/pubspec.yaml b/packages/mock_server/pubspec.yaml index 4963a32..ccbc099 100644 --- a/packages/mock_server/pubspec.yaml +++ b/packages/mock_server/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: logging: ^1.1.1 flutter: sdk: flutter - http: ^0.13.4 + http: ^0.13.5 dev_dependencies: flutter_test: