From ee692d52a22377e5ff7ff3a2c56d2941b03d54f8 Mon Sep 17 00:00:00 2001 From: Dat PHAM HOANG Date: Wed, 8 Jun 2022 22:25:00 +0700 Subject: [PATCH] TF-629 Download file and get the contentType to open file in Android/iOS --- core/lib/core.dart | 168 +++++++++--------- .../network/download/download_manager.dart | 27 ++- .../data/datasource/email_datasource.dart | 3 +- .../email_datasource_impl.dart | 3 +- .../email/data/network/email_api.dart | 13 +- .../repository/email_repository_impl.dart | 3 +- .../domain/repository/email_repository.dart | 3 +- .../domain/state/export_attachment_state.dart | 8 +- .../export_attachment_interactor.dart | 4 +- .../email/presentation/email_controller.dart | 34 +++- .../email/presentation/email_view.dart | 10 +- lib/l10n/intl_messages.arb | 8 +- lib/main/localizations/app_localizations.dart | 7 + pubspec.yaml | 2 + 14 files changed, 179 insertions(+), 114 deletions(-) diff --git a/core/lib/core.dart b/core/lib/core.dart index f8a0a644a..1fd573682 100644 --- a/core/lib/core.dart +++ b/core/lib/core.dart @@ -1,20 +1,80 @@ library core; -export 'package:core/domain/extensions/media_type_extension.dart'; -// Preview -export 'package:core/domain/preview/document_uti.dart'; -export 'package:core/domain/preview/supported_preview_file_types.dart'; +// Extensions +export 'presentation/extensions/color_extension.dart'; +export 'presentation/extensions/url_extension.dart'; +export 'presentation/extensions/capitalize_extension.dart'; +export 'presentation/extensions/list_extensions.dart'; +export 'domain/extensions/datetime_extension.dart'; +export 'presentation/extensions/html_extension.dart'; +export 'presentation/extensions/compare_string_extension.dart'; +export 'presentation/extensions/compare_list_extensions.dart'; +export 'domain/extensions/media_type_extension.dart'; -export 'data/constants/constant.dart'; +// Exceptions +export 'domain/exceptions/download_file_exception.dart'; export 'data/extensions/options_extensions.dart'; -// Local -export 'data/local/config/database_config.dart'; -export 'data/local/config/email_address_table.dart'; -export 'data/local/database_client.dart'; -export 'data/local/database_manager.dart'; -export 'data/model/query/query_parameter.dart'; -// Model -export 'data/model/source_type/data_source_type.dart'; + +// Utils +export 'presentation/utils/theme_utils.dart'; +export 'presentation/utils/responsive_utils.dart'; +export 'presentation/utils/keyboard_utils.dart'; +export 'presentation/utils/style_utils.dart'; +export 'presentation/utils/app_toast.dart'; +export 'presentation/utils/html_transformer/html_template.dart'; +export 'presentation/utils/html_transformer/html_transform.dart'; +export 'presentation/utils/html_transformer/transform_configuration.dart'; +export 'presentation/utils/html_transformer/dom/add_tooltip_link_transformers.dart'; +export 'data/utils/device_manager.dart'; +export 'utils/app_logger.dart'; +export 'utils/benchmark.dart'; +export 'utils/fps_manager.dart'; +export 'utils/build_utils.dart'; + +// Views +export 'presentation/views/text/slogan_builder.dart'; +export 'presentation/views/text/text_field_builder.dart'; +export 'presentation/views/text/input_decoration_builder.dart'; +export 'presentation/views/text/text_builder.dart'; +export 'presentation/views/text/rich_text_builder.dart'; +export 'presentation/views/responsive/responsive_widget.dart'; +export 'presentation/views/list/tree_view.dart'; +export 'presentation/views/button/button_builder.dart'; +export 'presentation/views/button/icon_button_web.dart'; +export 'presentation/views/image/avatar_builder.dart'; +export 'presentation/views/list/sliver_grid_delegate_fixed_height.dart'; +export 'presentation/views/image/icon_builder.dart'; +export 'presentation/views/context_menu/context_menu_action_builder.dart'; +export 'presentation/views/context_menu/context_menu_builder.dart'; +export 'presentation/views/context_menu/context_menu_header_builder.dart'; +export 'presentation/views/context_menu/simple_context_menu_action_builder.dart'; +export 'presentation/views/dialog/downloading_file_dialog_builder.dart'; +export 'presentation/views/dialog/confirmation_dialog_builder.dart'; +export 'presentation/views/dialog/edit_text_dialog_builder.dart'; +export 'presentation/views/background/background_widget_builder.dart'; +export 'presentation/views/html_viewer/html_content_viewer_widget.dart'; +export 'presentation/views/html_viewer/html_content_viewer_on_web_widget.dart'; +export 'presentation/views/html_viewer/html_viewer_controller_for_web.dart'; +export 'presentation/views/floating_button/scrolling_floating_button_animated.dart'; +export 'presentation/views/bottom_popup/cupertino_action_sheet_action_builder.dart'; +export 'presentation/views/bottom_popup/cupertino_action_sheet_builder.dart'; +export 'presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart'; +export 'presentation/views/modal_sheets/edit_text_modal_sheet_builder.dart'; +export 'presentation/views/search/search_bar_view.dart'; +export 'presentation/views/popup_menu/popup_menu_item_widget.dart'; +export 'presentation/views/tab_bar/custom_tab_indicator.dart'; +export 'presentation/views/quick_search/quick_search_input_form.dart'; +export 'presentation/views/toast/toast_position.dart'; +export 'presentation/views/toast/tmail_toast.dart'; + +// Resources +export 'presentation/resources/assets_paths.dart'; +export 'presentation/resources/image_paths.dart'; + +// Constants +export 'presentation/constants/constants_ui.dart'; +export 'data/constants/constant.dart'; + // Network export 'data/network/config/dynamic_url_interceptors.dart'; export 'data/network/config/service_path.dart'; @@ -22,73 +82,19 @@ export 'data/network/dio_client.dart'; export 'data/network/download/download_client.dart'; export 'data/network/download/download_manager.dart'; export 'data/network/download/downloaded_response.dart'; -export 'data/utils/device_manager.dart'; -// Exceptions -export 'domain/exceptions/download_file_exception.dart'; -export 'domain/extensions/datetime_extension.dart'; -// Constants -export 'presentation/constants/constants_ui.dart'; -export 'presentation/extensions/capitalize_extension.dart'; -// Extensions -export 'presentation/extensions/color_extension.dart'; -export 'presentation/extensions/compare_list_extensions.dart'; -export 'presentation/extensions/compare_string_extension.dart'; -export 'presentation/extensions/html_extension.dart'; -export 'presentation/extensions/list_extensions.dart'; -export 'presentation/extensions/url_extension.dart'; -// Resources -export 'presentation/resources/assets_paths.dart'; -export 'presentation/resources/image_paths.dart'; -export 'presentation/state/app_state.dart'; -export 'presentation/state/failure.dart'; +export 'data/network/download/download_client.dart'; + // State export 'presentation/state/success.dart'; -export 'presentation/utils/app_toast.dart'; -export 'presentation/utils/html_transformer/dom/add_tooltip_link_transformers.dart'; -export 'presentation/utils/html_transformer/html_template.dart'; -export 'presentation/utils/html_transformer/html_transform.dart'; -export 'presentation/utils/html_transformer/transform_configuration.dart'; -export 'presentation/utils/keyboard_utils.dart'; -export 'presentation/utils/responsive_utils.dart'; -export 'presentation/utils/style_utils.dart'; -// Utils -export 'presentation/utils/theme_utils.dart'; -export 'presentation/views/background/background_widget_builder.dart'; -export 'presentation/views/bottom_popup/confirmation_dialog_action_sheet_builder.dart'; -export 'presentation/views/bottom_popup/cupertino_action_sheet_action_builder.dart'; -export 'presentation/views/bottom_popup/cupertino_action_sheet_builder.dart'; -export 'presentation/views/button/button_builder.dart'; -export 'presentation/views/button/icon_button_web.dart'; -export 'presentation/views/context_menu/context_menu_action_builder.dart'; -export 'presentation/views/context_menu/context_menu_builder.dart'; -export 'presentation/views/context_menu/context_menu_header_builder.dart'; -export 'presentation/views/context_menu/simple_context_menu_action_builder.dart'; -export 'presentation/views/dialog/confirmation_dialog_builder.dart'; -export 'presentation/views/dialog/downloading_file_dialog_builder.dart'; -export 'presentation/views/dialog/edit_text_dialog_builder.dart'; -export 'presentation/views/floating_button/scrolling_floating_button_animated.dart'; -export 'presentation/views/html_viewer/html_content_viewer_on_web_widget.dart'; -export 'presentation/views/html_viewer/html_content_viewer_widget.dart'; -export 'presentation/views/html_viewer/html_viewer_controller_for_web.dart'; -export 'presentation/views/image/avatar_builder.dart'; -export 'presentation/views/image/icon_builder.dart'; -export 'presentation/views/list/sliver_grid_delegate_fixed_height.dart'; -export 'presentation/views/list/tree_view.dart'; -export 'presentation/views/modal_sheets/edit_text_modal_sheet_builder.dart'; -export 'presentation/views/popup_menu/popup_menu_item_widget.dart'; -export 'presentation/views/quick_search/quick_search_input_form.dart'; -export 'presentation/views/responsive/responsive_widget.dart'; -export 'presentation/views/search/search_bar_view.dart'; -export 'presentation/views/tab_bar/custom_tab_indicator.dart'; -export 'presentation/views/text/input_decoration_builder.dart'; -export 'presentation/views/text/rich_text_builder.dart'; -// Views -export 'presentation/views/text/slogan_builder.dart'; -export 'presentation/views/text/text_builder.dart'; -export 'presentation/views/text/text_field_builder.dart'; -export 'presentation/views/toast/tmail_toast.dart'; -export 'presentation/views/toast/toast_position.dart'; -export 'utils/app_logger.dart'; -export 'utils/benchmark.dart'; -export 'utils/build_utils.dart'; -export 'utils/fps_manager.dart'; \ No newline at end of file +export 'presentation/state/failure.dart'; +export 'presentation/state/app_state.dart'; + +// Local +export 'data/local/config/database_config.dart'; +export 'data/local/config/email_address_table.dart'; +export 'data/local/database_client.dart'; +export 'data/local/database_manager.dart'; + +// Model +export 'data/model/source_type/data_source_type.dart'; +export 'data/model/query/query_parameter.dart'; \ No newline at end of file diff --git a/core/lib/data/network/download/download_manager.dart b/core/lib/data/network/download/download_manager.dart index cf71081c6..34ea38941 100644 --- a/core/lib/data/network/download/download_manager.dart +++ b/core/lib/data/network/download/download_manager.dart @@ -1,30 +1,35 @@ import 'dart:async'; import 'dart:io'; -import 'package:http/http.dart' as http; -import 'package:universal_html/html.dart' as html; + import 'package:core/core.dart'; +import 'package:core/data/network/download/downloaded_response.dart'; import 'package:dio/dio.dart'; +import 'package:http/http.dart' as http; +import 'package:http_parser/http_parser.dart'; +import 'package:universal_html/html.dart' as html; class DownloadManager { final DownloadClient _downloadClient; DownloadManager(this._downloadClient); - Future downloadFile( + Future downloadFile( String downloadUrl, Future directoryToSave, String filename, String basicAuth, {CancelToken? cancelToken} ) async { - final streamController = StreamController(); + final streamController = StreamController(); try { await Future.wait([ _downloadClient.downloadFile(downloadUrl, basicAuth, cancelToken), directoryToSave ]).then((values) { - final fileStream = (values[0] as ResponseBody).stream; + final response = (values[0] as ResponseBody); + final mediaType = _extractMediaTypeFromResponse(response); + final fileStream = response.stream; final tempFilePath = '${(values[1] as Directory).absolute.path}/$filename'; final file = File(tempFilePath); @@ -52,7 +57,7 @@ class DownloadManager { if (cancelToken != null && cancelToken.isCancelled) { streamController.sink.addError(CancelDownloadFileException(cancelToken.cancelError?.message)); } else { - streamController.sink.add(tempFilePath); + streamController.sink.add(DownloadedResponse(tempFilePath, mediaType: mediaType)); } await streamController.close(); }, onError: (error) async { @@ -100,4 +105,14 @@ class DownloadManager { return false; } + + MediaType? _extractMediaTypeFromResponse(ResponseBody responseBody) { + try { + final contentType = responseBody.headers[Headers.contentTypeHeader]; + return MediaType.parse(contentType!.first); + } catch (e) { + logError('DownloadManager::_extractMediaTypeFromResponse(): $e'); + return null; + } + } } \ No newline at end of file diff --git a/lib/features/email/data/datasource/email_datasource.dart b/lib/features/email/data/datasource/email_datasource.dart index a7b79d018..4bb166a72 100644 --- a/lib/features/email/data/datasource/email_datasource.dart +++ b/lib/features/email/data/datasource/email_datasource.dart @@ -1,3 +1,4 @@ +import 'package:core/core.dart'; import 'package:dio/dio.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; @@ -19,7 +20,7 @@ abstract class EmailDataSource { AccountRequest accountRequest ); - Future exportAttachment( + Future exportAttachment( Attachment attachment, AccountId accountId, String baseDownloadUrl, diff --git a/lib/features/email/data/datasource_impl/email_datasource_impl.dart b/lib/features/email/data/datasource_impl/email_datasource_impl.dart index 4e0fbe39c..832369024 100644 --- a/lib/features/email/data/datasource_impl/email_datasource_impl.dart +++ b/lib/features/email/data/datasource_impl/email_datasource_impl.dart @@ -1,3 +1,4 @@ +import 'package:core/core.dart'; import 'package:dio/dio.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; @@ -55,7 +56,7 @@ class EmailDataSourceImpl extends EmailDataSource { } @override - Future exportAttachment( + Future exportAttachment( Attachment attachment, AccountId accountId, String baseDownloadUrl, diff --git a/lib/features/email/data/network/email_api.dart b/lib/features/email/data/network/email_api.dart index 815d716bf..919c33f13 100644 --- a/lib/features/email/data/network/email_api.dart +++ b/lib/features/email/data/network/email_api.dart @@ -23,9 +23,18 @@ import 'package:jmap_dart_client/jmap/mail/email/submission/email_submission.dar import 'package:jmap_dart_client/jmap/mail/email/submission/email_submission_id.dart'; import 'package:jmap_dart_client/jmap/mail/email/submission/envelope.dart'; import 'package:jmap_dart_client/jmap/mail/email/submission/set/set_email_submission_method.dart'; +import 'package:model/account/account_request.dart'; +import 'package:model/account/authentication_type.dart'; +import 'package:model/download/download_task_id.dart'; +import 'package:model/email/attachment.dart'; +import 'package:model/email/mark_star_action.dart'; +import 'package:model/email/read_actions.dart'; +import 'package:model/extensions/email_extension.dart'; +import 'package:model/extensions/keyword_identifier_extension.dart'; +import 'package:model/extensions/list_email_id_extension.dart'; +import 'package:model/oidc/token.dart'; import 'package:path_provider/path_provider.dart'; import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart'; -import 'package:model/model.dart'; import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_request.dart'; import 'package:tmail_ui_user/features/login/domain/exceptions/authentication_exception.dart'; @@ -198,7 +207,7 @@ class EmailAPI { .toList(); } - Future exportAttachment( + Future exportAttachment( Attachment attachment, AccountId accountId, String baseDownloadUrl, diff --git a/lib/features/email/data/repository/email_repository_impl.dart b/lib/features/email/data/repository/email_repository_impl.dart index c30637b67..4c47dad52 100644 --- a/lib/features/email/data/repository/email_repository_impl.dart +++ b/lib/features/email/data/repository/email_repository_impl.dart @@ -1,4 +1,5 @@ +import 'package:core/core.dart'; import 'package:dio/dio.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; @@ -42,7 +43,7 @@ class EmailRepositoryImpl extends EmailRepository { } @override - Future exportAttachment( + Future exportAttachment( Attachment attachment, AccountId accountId, String baseDownloadUrl, diff --git a/lib/features/email/domain/repository/email_repository.dart b/lib/features/email/domain/repository/email_repository.dart index e8e1626e9..0dd4f28c2 100644 --- a/lib/features/email/domain/repository/email_repository.dart +++ b/lib/features/email/domain/repository/email_repository.dart @@ -1,3 +1,4 @@ +import 'package:core/core.dart'; import 'package:dio/dio.dart'; import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; @@ -19,7 +20,7 @@ abstract class EmailRepository { AccountRequest accountRequest ); - Future exportAttachment( + Future exportAttachment( Attachment attachment, AccountId accountId, String baseDownloadUrl, diff --git a/lib/features/email/domain/state/export_attachment_state.dart b/lib/features/email/domain/state/export_attachment_state.dart index b90959cd0..048f830bb 100644 --- a/lib/features/email/domain/state/export_attachment_state.dart +++ b/lib/features/email/domain/state/export_attachment_state.dart @@ -1,16 +1,16 @@ import 'package:core/core.dart'; class ExportAttachmentSuccess extends UIState { - final String filePath; + final DownloadedResponse downloadedResponse; - ExportAttachmentSuccess(this.filePath); + ExportAttachmentSuccess(this.downloadedResponse); @override - List get props => [filePath]; + List get props => [downloadedResponse]; } class ExportAttachmentFailure extends FeatureFailure { - final exception; + final dynamic exception; ExportAttachmentFailure(this.exception); diff --git a/lib/features/email/domain/usecases/export_attachment_interactor.dart b/lib/features/email/domain/usecases/export_attachment_interactor.dart index 240e730ba..d09e08aae 100644 --- a/lib/features/email/domain/usecases/export_attachment_interactor.dart +++ b/lib/features/email/domain/usecases/export_attachment_interactor.dart @@ -35,7 +35,7 @@ class ExportAttachmentInteractor { log('ExportAttachmentInteractor::execute(): account: $account'); - final filePath = await Future.wait([ + final downloadedResponse = await Future.wait([ if (account.authenticationType == AuthenticationType.oidc) _authenticationOIDCRepository.getStoredTokenOIDC(account.id) else @@ -66,7 +66,7 @@ class ExportAttachmentInteractor { accountRequest, cancelToken); }); - yield Right(ExportAttachmentSuccess(filePath)); + yield Right(ExportAttachmentSuccess(downloadedResponse)); } catch (exception) { log('ExportAttachmentInteractor::execute(): exception: $exception'); yield Left(ExportAttachmentFailure(exception)); diff --git a/lib/features/email/presentation/email_controller.dart b/lib/features/email/presentation/email_controller.dart index 6dc7d12b8..028afe19d 100644 --- a/lib/features/email/presentation/email_controller.dart +++ b/lib/features/email/presentation/email_controller.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:core/core.dart'; import 'package:dartz/dartz.dart'; import 'package:dio/dio.dart'; @@ -11,9 +13,12 @@ import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:model/model.dart'; +import 'package:open_file/open_file.dart' as open_file; import 'package:permission_handler/permission_handler.dart'; import 'package:pointer_interceptor/pointer_interceptor.dart'; +import 'package:share/share.dart' as share_library; import 'package:tmail_ui_user/features/base/base_controller.dart'; +import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart'; import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart'; import 'package:tmail_ui_user/features/email/domain/model/move_action.dart'; import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_request.dart'; @@ -21,15 +26,15 @@ import 'package:tmail_ui_user/features/email/domain/state/download_attachment_fo import 'package:tmail_ui_user/features/email/domain/state/download_attachments_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/export_attachment_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart'; -import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart'; +import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_state.dart'; +import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/download_attachment_for_web_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/download_attachments_interactor.dart'; -import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/export_attachment_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_interactor.dart'; -import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart'; +import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart'; import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_address_bottom_sheet_builder.dart'; @@ -37,12 +42,10 @@ import 'package:tmail_ui_user/features/email/presentation/widgets/email_address_ import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/dashboard_action.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart'; -import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/routes/app_routes.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; -import 'package:share/share.dart' as share_library; class EmailController extends BaseController { @@ -314,7 +317,26 @@ class EmailController extends BaseController { void _exportAttachmentSuccessAction(Success success) async { popBack(); if (success is ExportAttachmentSuccess) { - await share_library.Share.shareFiles([success.filePath]); + _openDownloadedPreviewWorkGroupDocument(success.downloadedResponse); + } + } + + void _openDownloadedPreviewWorkGroupDocument(DownloadedResponse downloadedResponse) async { + log('EmailController::_openDownloadedPreviewWorkGroupDocument(): $downloadedResponse'); + if (downloadedResponse.mediaType == null) { + await share_library.Share.shareFiles([downloadedResponse.filePath]); + } + + final openResult = await open_file.OpenFile.open( + downloadedResponse.filePath, + type: Platform.isAndroid ? downloadedResponse.mediaType!.mimeType : null, + uti: Platform.isIOS ? downloadedResponse.mediaType!.getDocumentUti().value : null); + + if (openResult.type != open_file.ResultType.done) { + logError('EmailController::_openDownloadedPreviewWorkGroupDocument(): no preview available'); + if (currentContext != null) { + _appToast.showErrorToast(AppLocalizations.of(currentContext!).noPreviewAvailable); + } } } diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index c14cf5dd2..190d9ca20 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -1,6 +1,5 @@ -import 'dart:io'; - import 'package:core/core.dart'; +import 'package:filesize/filesize.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -16,7 +15,6 @@ import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_fil import 'package:tmail_ui_user/features/email/presentation/widgets/bottom_bar_mail_widget_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; -import 'package:filesize/filesize.dart'; class EmailView extends GetView with NetworkConnectionMixin { @@ -411,11 +409,7 @@ class EmailView extends GetView with NetworkConnectionMixin { if (kIsWeb) { emailController.downloadAttachmentForWeb(context, attachment); } else { - if (Platform.isAndroid) { - emailController.downloadAttachments(context, [attachment]); - } else if (Platform.isIOS) { - emailController.exportAttachment(context, attachment); - } + emailController.exportAttachment(context, attachment); } })) .build()) diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index 0c39a0d1c..9f3daea61 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2022-06-06T13:32:00.583993", + "@@last_modified": "2022-06-13T12:33:59.446625", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -1411,5 +1411,11 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "noPreviewAvailable": "No preview available", + "@noPreviewAvailable": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } \ No newline at end of file diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index 3ce222825..3411e0211 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -1441,4 +1441,11 @@ class AppLocalizations { return Intl.message('Single sign-on (SSO) is not available', name: 'ssoNotAvailable'); } + + String get noPreviewAvailable { + return Intl.message( + 'No preview available', + name: 'noPreviewAvailable', + ); + } } \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 18875e5b6..b048fc1ab 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -153,6 +153,8 @@ dependencies: timeago: 3.2.2 + open_file: 3.2.1 + # OIDC Mobile flutter_appauth: 4.0.0