TF-4050 Preview and download uploaded file in composer on web
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/base/interactors_bindings.dart';
|
||||
import 'package:tmail_ui_user/features/caching/utils/local_storage_manager.dart';
|
||||
import 'package:tmail_ui_user/features/caching/utils/session_storage_manager.dart';
|
||||
import 'package:tmail_ui_user/features/download/data/datasource/download_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/download/data/datasource_impl/download_datasource_impl.dart';
|
||||
import 'package:tmail_ui_user/features/download/data/repository/download_repository_impl.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/repository/download_repository.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/download_all_attachments_for_web_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/download_and_get_html_content_from_attachment_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/download_attachment_for_web_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/export_all_attachments_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/export_attachment_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/get_html_content_from_upload_file_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/get_preview_email_eml_content_shared_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/get_preview_eml_content_in_memory_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/move_preview_eml_content_from_persistent_to_memory_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/parse_email_by_blob_id_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/preview_email_from_eml_file_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/remove_preview_email_eml_content_shared_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource_impl/email_datasource_impl.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource_impl/email_local_storage_datasource_impl.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource_impl/email_session_storage_datasource_impl.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource_impl/html_datasource_impl.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/local/html_analyzer.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
|
||||
import 'package:tmail_ui_user/features/login/domain/repository/account_repository.dart';
|
||||
import 'package:tmail_ui_user/features/login/domain/repository/authentication_oidc_repository.dart';
|
||||
import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart';
|
||||
import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart';
|
||||
import 'package:tmail_ui_user/main/exceptions/remote_exception_thrower.dart';
|
||||
|
||||
class DownloadInteractorBindings extends InteractorsBindings {
|
||||
@override
|
||||
void bindingsDataSourceImpl() {
|
||||
Get.lazyPut(
|
||||
() => DownloadDatasourceImpl(
|
||||
Get.find<EmailAPI>(),
|
||||
Get.find<RemoteExceptionThrower>(),
|
||||
),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => EmailDataSourceImpl(
|
||||
Get.find<EmailAPI>(),
|
||||
Get.find<RemoteExceptionThrower>(),
|
||||
),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => HtmlDataSourceImpl(
|
||||
Get.find<HtmlAnalyzer>(),
|
||||
Get.find<CacheExceptionThrower>(),
|
||||
),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => EmailSessionStorageDatasourceImpl(
|
||||
Get.find<SessionStorageManager>(),
|
||||
Get.find<CacheExceptionThrower>(),
|
||||
),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => EmailLocalStorageDataSourceImpl(
|
||||
Get.find<LocalStorageManager>(),
|
||||
Get.find<PreviewEmlFileUtils>(),
|
||||
Get.find<CacheExceptionThrower>(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void bindingsInteractor() {
|
||||
Get.lazyPut(
|
||||
() => DownloadAttachmentForWebInteractor(
|
||||
Get.find<DownloadRepository>(),
|
||||
Get.find<CredentialRepository>(),
|
||||
Get.find<AccountRepository>(),
|
||||
Get.find<AuthenticationOIDCRepository>(),
|
||||
),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => DownloadAllAttachmentsForWebInteractor(
|
||||
Get.find<DownloadRepository>(),
|
||||
Get.find<AccountRepository>(),
|
||||
Get.find<AuthenticationOIDCRepository>(),
|
||||
Get.find<CredentialRepository>(),
|
||||
),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => ExportAttachmentInteractor(
|
||||
Get.find<DownloadRepository>(),
|
||||
Get.find<CredentialRepository>(),
|
||||
Get.find<AccountRepository>(),
|
||||
Get.find<AuthenticationOIDCRepository>(),
|
||||
),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => ExportAllAttachmentsInteractor(
|
||||
Get.find<DownloadRepository>(),
|
||||
Get.find<AccountRepository>(),
|
||||
Get.find<AuthenticationOIDCRepository>(),
|
||||
Get.find<CredentialRepository>(),
|
||||
),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => ParseEmailByBlobIdInteractor(Get.find<DownloadRepository>()),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => PreviewEmailFromEmlFileInteractor(Get.find<DownloadRepository>()),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => DownloadAndGetHtmlContentFromAttachmentInteractor(
|
||||
Get.find<DownloadAttachmentForWebInteractor>(),
|
||||
),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => MovePreviewEmlContentFromPersistentToMemoryInteractor(
|
||||
Get.find<DownloadRepository>(),
|
||||
),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => RemovePreviewEmailEmlContentSharedInteractor(
|
||||
Get.find<DownloadRepository>(),
|
||||
),
|
||||
);
|
||||
|
||||
Get.lazyPut(
|
||||
() => GetPreviewEmailEMLContentSharedInteractor(
|
||||
Get.find<DownloadRepository>(),
|
||||
),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => GetPreviewEmlContentInMemoryInteractor(
|
||||
Get.find<DownloadRepository>(),
|
||||
),
|
||||
);
|
||||
Get.lazyPut(
|
||||
() => GetHtmlContentFromUploadFileInteractor(
|
||||
Get.find<DownloadRepository>(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void bindingsRepository() {
|
||||
Get.lazyPut<DownloadRepository>(() => Get.find<DownloadRepositoryImpl>());
|
||||
}
|
||||
|
||||
@override
|
||||
void bindingsRepositoryImpl() {
|
||||
Get.lazyPut(
|
||||
() => DownloadRepositoryImpl(
|
||||
Get.find<DownloadDatasource>(),
|
||||
{
|
||||
DataSourceType.session: Get.find<EmailSessionStorageDatasourceImpl>(),
|
||||
DataSourceType.local: Get.find<EmailLocalStorageDataSourceImpl>(),
|
||||
DataSourceType.network: Get.find<EmailDataSource>(),
|
||||
},
|
||||
Get.find<HtmlDataSource>(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void bindingsDataSource() {
|
||||
Get.lazyPut<DownloadDatasource>(() => Get.find<DownloadDatasourceImpl>());
|
||||
Get.lazyPut<EmailDataSource>(() => Get.find<EmailDataSourceImpl>());
|
||||
Get.lazyPut<HtmlDataSource>(() => Get.find<HtmlDataSourceImpl>());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:core/data/network/download/download_manager.dart';
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/utils/print_utils.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:model/download/download_task_id.dart';
|
||||
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/model/download_source_view.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/download_all_attachments_for_web_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/download_and_get_html_content_from_attachment_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/download_attachment_for_web_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/export_all_attachments_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/export_attachment_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/get_html_content_from_upload_file_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/parse_email_by_blob_id_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/preview_email_from_eml_file_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/download_all_attachments_for_web_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/download_and_get_html_content_from_attachment_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/download_attachment_for_web_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/export_all_attachments_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/export_attachment_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/get_html_content_from_upload_file_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/parse_email_by_blob_id_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/usecase/preview_email_from_eml_file_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/download/presentation/extensions/download_attachment_download_controller_extension.dart';
|
||||
import 'package:tmail_ui_user/features/download/presentation/extensions/preview_attachment_download_controller_extension.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/download_ui_action.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/download/download_task_state.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||
|
||||
typedef UpdateDownloadTaskStateCallback = DownloadTaskState Function(DownloadTaskState currentState);
|
||||
|
||||
class DownloadController extends BaseController {
|
||||
final DownloadManager downloadManager;
|
||||
final PrintUtils printUtils;
|
||||
final DownloadAttachmentForWebInteractor downloadAttachmentForWebInteractor;
|
||||
final DownloadAllAttachmentsForWebInteractor
|
||||
downloadAllAttachmentsForWebInteractor;
|
||||
final ParseEmailByBlobIdInteractor parseEmailByBlobIdInteractor;
|
||||
final PreviewEmailFromEmlFileInteractor previewEmailFromEmlFileInteractor;
|
||||
final DownloadAndGetHtmlContentFromAttachmentInteractor
|
||||
downloadAndGetHtmlContentFromAttachmentInteractor;
|
||||
final GetHtmlContentFromUploadFileInteractor
|
||||
getHtmlContentFromUploadFileInteractor;
|
||||
final ExportAttachmentInteractor exportAttachmentInteractor;
|
||||
final ExportAllAttachmentsInteractor exportAllAttachmentsInteractor;
|
||||
|
||||
DownloadController(
|
||||
this.downloadManager,
|
||||
this.printUtils,
|
||||
this.downloadAttachmentForWebInteractor,
|
||||
this.downloadAllAttachmentsForWebInteractor,
|
||||
this.parseEmailByBlobIdInteractor,
|
||||
this.previewEmailFromEmlFileInteractor,
|
||||
this.downloadAndGetHtmlContentFromAttachmentInteractor,
|
||||
this.getHtmlContentFromUploadFileInteractor,
|
||||
this.exportAttachmentInteractor,
|
||||
this.exportAllAttachmentsInteractor,
|
||||
);
|
||||
|
||||
final listDownloadTaskState = RxList<DownloadTaskState>();
|
||||
final hideDownloadTaskbar = RxBool(false);
|
||||
final downloadUIAction = Rxn<DownloadUIAction>();
|
||||
|
||||
final downloadProgressStateController =
|
||||
StreamController<Either<Failure, Success>>.broadcast();
|
||||
StreamSubscription<Either<Failure, Success>>?
|
||||
_downloadProgressStateSubscription;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
_registerDownloadProgressState();
|
||||
}
|
||||
|
||||
void _registerDownloadProgressState() {
|
||||
_downloadProgressStateSubscription = downloadProgressStateController.stream
|
||||
.listen(_onDownloadProgressStateChanged);
|
||||
}
|
||||
|
||||
void _onDownloadProgressStateChanged(Either<Failure, Success> state) {
|
||||
state.fold((_) => null, (success) {
|
||||
if (success is StartDownloadAttachmentForWeb) {
|
||||
_handleStartSingleDownload(success);
|
||||
} else if (success is DownloadingAttachmentForWeb) {
|
||||
_updateDownloadProgress(
|
||||
success.taskId,
|
||||
success.progress,
|
||||
success.downloaded,
|
||||
success.total,
|
||||
);
|
||||
} else if (success is StartDownloadAllAttachmentsForWeb) {
|
||||
_handleStartAllDownload(success);
|
||||
} else if (success is DownloadingAllAttachmentsForWeb) {
|
||||
_updateDownloadProgress(
|
||||
success.taskId,
|
||||
success.progress,
|
||||
success.downloaded,
|
||||
success.total,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void _handleStartSingleDownload(StartDownloadAttachmentForWeb success) {
|
||||
if (success.previewerSupported) return;
|
||||
|
||||
addDownloadTask(
|
||||
DownloadTaskState(
|
||||
taskId: success.taskId,
|
||||
attachment: success.attachment,
|
||||
onCancel: success.cancelToken?.cancel,
|
||||
),
|
||||
);
|
||||
|
||||
if (_hasValidContext) {
|
||||
appToast.showToastMessage(
|
||||
currentOverlayContext!,
|
||||
AppLocalizations.of(currentContext!).your_download_has_started,
|
||||
leadingSVGIconColor: AppColor.primaryColor,
|
||||
leadingSVGIcon: imagePaths.icDownload,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _handleStartAllDownload(StartDownloadAllAttachmentsForWeb success) {
|
||||
addDownloadTask(
|
||||
DownloadTaskState(
|
||||
taskId: success.taskId,
|
||||
attachment: success.attachment,
|
||||
onCancel: () => success.cancelToken?.cancel(),
|
||||
),
|
||||
);
|
||||
|
||||
if (_hasValidContext) {
|
||||
appToast.showToastSuccessMessage(
|
||||
currentOverlayContext!,
|
||||
AppLocalizations.of(currentContext!).creatingAnArchiveForDownloading,
|
||||
leadingSVGIconColor: Colors.white,
|
||||
leadingSVGIcon: imagePaths.icDownloadAll,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _updateDownloadProgress(
|
||||
DownloadTaskId taskId,
|
||||
double progress,
|
||||
int downloaded,
|
||||
int total,
|
||||
) {
|
||||
final percent = progress.round();
|
||||
log('$runtimeType::_updateDownloadProgress(): $percent%');
|
||||
|
||||
updateDownloadTaskByTaskId(taskId, (currentTask) {
|
||||
return currentTask.copyWith(
|
||||
progress: progress,
|
||||
downloaded: downloaded,
|
||||
total: total,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
bool get _hasValidContext =>
|
||||
currentOverlayContext != null && currentContext != null;
|
||||
|
||||
bool get notEmptyListDownloadTask => listDownloadTaskState.isNotEmpty;
|
||||
|
||||
void addDownloadTask(DownloadTaskState task) {
|
||||
log('DownloadController::addDownloadTask(): ${task.taskId}');
|
||||
listDownloadTaskState.add(task);
|
||||
hideDownloadTaskbar.value = false;
|
||||
}
|
||||
|
||||
void updateDownloadTaskByTaskId(
|
||||
DownloadTaskId downloadTaskId,
|
||||
UpdateDownloadTaskStateCallback updateDownloadTaskCallback,
|
||||
) {
|
||||
final matchIndex = listDownloadTaskState
|
||||
.indexWhere((task) => task.taskId == downloadTaskId);
|
||||
if (matchIndex >= 0) {
|
||||
listDownloadTaskState[matchIndex] = updateDownloadTaskCallback(listDownloadTaskState[matchIndex]);
|
||||
listDownloadTaskState.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void deleteDownloadTask(DownloadTaskId taskId) {
|
||||
log('DownloadController::deleteDownloadTask(): $taskId');
|
||||
final matchIndex = listDownloadTaskState
|
||||
.indexWhere((task) => task.taskId == taskId);
|
||||
if (matchIndex >= 0) {
|
||||
listDownloadTaskState.removeAt(matchIndex);
|
||||
listDownloadTaskState.refresh();
|
||||
}
|
||||
if (listDownloadTaskState.isEmpty) {
|
||||
hideDownloadTaskbar.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
void pushDownloadUIAction(DownloadUIAction action) {
|
||||
downloadUIAction.value = action;
|
||||
}
|
||||
|
||||
void clearDownloadUIAction() {
|
||||
downloadUIAction.value = null;
|
||||
}
|
||||
|
||||
@override
|
||||
void handleSuccessViewState(Success success) {
|
||||
if (success is DownloadAttachmentForWebSuccess) {
|
||||
handleDownloadAttachmentForWebSuccess(success);
|
||||
} else if (success is StartDownloadAttachmentForWeb &&
|
||||
success.sourceView == DownloadSourceView.emailView) {
|
||||
pushDownloadUIAction(UpdateAttachmentsViewStateAction(
|
||||
success.attachment.blobId,
|
||||
Right<Failure, Success>(success),
|
||||
));
|
||||
} else if (success is DownloadingAttachmentForWeb &&
|
||||
success.sourceView == DownloadSourceView.emailView) {
|
||||
pushDownloadUIAction(UpdateAttachmentsViewStateAction(
|
||||
success.attachment.blobId,
|
||||
Right<Failure, Success>(success),
|
||||
));
|
||||
} else if (success is DownloadAllAttachmentsForWebSuccess) {
|
||||
deleteDownloadTask(success.taskId);
|
||||
} else if (success is ParseEmailByBlobIdSuccess) {
|
||||
handleParseEmailByBlobIdSuccess(
|
||||
context: currentContext,
|
||||
accountId: success.accountId,
|
||||
session: success.session,
|
||||
ownEmailAddress: success.ownEmailAddress,
|
||||
blobId: success.blobId,
|
||||
email: success.email,
|
||||
);
|
||||
} else if (success is PreviewEmailFromEmlFileSuccess) {
|
||||
handlePreviewEmailFromEmlFileSuccess(success);
|
||||
} else if (success is DownloadAndGetHtmlContentFromAttachmentSuccess) {
|
||||
handleDownloadAndGetHtmlContentFromAttachmentSuccess(success);
|
||||
} else if (success is DownloadAndGettingHtmlContentFromAttachment &&
|
||||
success.sourceView == DownloadSourceView.emailView) {
|
||||
pushDownloadUIAction(
|
||||
UpdateAttachmentsViewStateAction(
|
||||
success.blobId,
|
||||
Right<Failure, Success>(success),
|
||||
),
|
||||
);
|
||||
} else if (success is ExportAttachmentSuccess) {
|
||||
exportAttachmentSuccessAction(success.downloadedResponse);
|
||||
} else if (success is ExportAllAttachmentsSuccess) {
|
||||
exportAllAttachmentsSuccessAction(success.downloadedResponse.filePath);
|
||||
} else if (success is GetHtmlContentFromUploadFileSuccess) {
|
||||
handleGetHtmlContentFromUploadFileSuccess(success);
|
||||
} else {
|
||||
super.handleSuccessViewState(success);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void handleFailureViewState(Failure failure) {
|
||||
if (failure is DownloadAllAttachmentsForWebFailure) {
|
||||
downloadAllAttachmentsForWebFailure(failureState: failure);
|
||||
} else if (failure is DownloadAttachmentForWebFailure) {
|
||||
downloadAttachmentForWebFailureAction(failureState: failure);
|
||||
} else if (failure is ParseEmailByBlobIdFailure) {
|
||||
handleParseEmailByBlobIdFailure(failure);
|
||||
} else if (failure is PreviewEmailFromEmlFileFailure) {
|
||||
handlePreviewEmailFromEMLFileFailure(failure);
|
||||
} else if (failure is GetHtmlContentFromUploadFileFailure ||
|
||||
failure is DownloadAndGetHtmlContentFromAttachmentFailure) {
|
||||
handlePreviewHtmlFileFailure(failureState: failure);
|
||||
} else if (failure is ExportAttachmentFailure) {
|
||||
exportAttachmentFailureAction(failure);
|
||||
} else if (failure is ExportAllAttachmentsFailure) {
|
||||
exportAllAttachmentsFailureAction(failure);
|
||||
} else {
|
||||
super.handleFailureViewState(failure);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
_downloadProgressStateSubscription?.cancel();
|
||||
_downloadProgressStateSubscription = null;
|
||||
downloadProgressStateController.close();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
+631
@@ -0,0 +1,631 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:core/data/network/download/downloaded_response.dart';
|
||||
import 'package:core/domain/exceptions/download_file_exception.dart';
|
||||
import 'package:core/presentation/extensions/media_type_extension.dart';
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:core/presentation/views/dialog/downloading_file_dialog_builder.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_file_dialog/flutter_file_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:http_parser/http_parser.dart';
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:model/download/download_task_id.dart';
|
||||
import 'package:model/email/attachment.dart';
|
||||
import 'package:model/email/eml_attachment.dart';
|
||||
import 'package:model/email/presentation_email.dart';
|
||||
import 'package:model/extensions/presentation_email_extension.dart';
|
||||
import 'package:model/extensions/session_extension.dart';
|
||||
import 'package:open_file/open_file.dart' as open_file;
|
||||
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/exceptions/download_attachment_exceptions.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/model/download_source_view.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/download_all_attachments_for_web_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/download_attachment_for_web_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/export_all_attachments_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/export_attachment_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/presentation/controllers/download_controller.dart';
|
||||
import 'package:tmail_ui_user/features/download/presentation/extensions/preview_attachment_download_controller_extension.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/extensions/attachment_extension.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_item_widget.dart';
|
||||
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
|
||||
import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/download_ui_action.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||
|
||||
typedef OnDownloadWebFileAction = void Function(String name, Uint8List bytes);
|
||||
|
||||
extension DownloadAttachmentDownloadControllerExtension on DownloadController {
|
||||
void downloadAttachment({
|
||||
required Attachment attachment,
|
||||
required AccountId? accountId,
|
||||
required Session? session,
|
||||
bool previewerSupported = false,
|
||||
bool showBottomDownloadProgressBar = false,
|
||||
DownloadSourceView? sourceView,
|
||||
}) {
|
||||
if (PlatformInfo.isWeb) {
|
||||
downloadAttachmentForWeb(
|
||||
attachment: attachment,
|
||||
accountId: accountId,
|
||||
session: session,
|
||||
previewerSupported: previewerSupported,
|
||||
onReceiveController: showBottomDownloadProgressBar
|
||||
? downloadProgressStateController
|
||||
: null,
|
||||
sourceView: sourceView,
|
||||
);
|
||||
} else if (PlatformInfo.isMobile) {
|
||||
exportAttachment(
|
||||
attachment: attachment,
|
||||
accountId: accountId,
|
||||
session: session,
|
||||
);
|
||||
} else {
|
||||
log('$runtimeType::downloadAttachment: THE PLATFORM IS SUPPORTED');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> downloadAllAttachments({
|
||||
required String outputFileName,
|
||||
required EmailId? emailId,
|
||||
required AccountId? accountId,
|
||||
required Session? session,
|
||||
bool showBottomDownloadProgressBar = false,
|
||||
}) async {
|
||||
if (PlatformInfo.isWeb) {
|
||||
downloadAllAttachmentsForWeb(
|
||||
outputFileName: outputFileName,
|
||||
emailId: emailId,
|
||||
session: session,
|
||||
accountId: accountId,
|
||||
onReceiveController: showBottomDownloadProgressBar
|
||||
? downloadProgressStateController
|
||||
: null,
|
||||
);
|
||||
} else if (PlatformInfo.isMobile) {
|
||||
exportAllAttachments(
|
||||
outputFileName: outputFileName,
|
||||
emailId: emailId,
|
||||
session: session,
|
||||
accountId: accountId,
|
||||
);
|
||||
} else {
|
||||
log('$runtimeType::downloadAllAttachments: THE PLATFORM IS SUPPORTED');
|
||||
}
|
||||
}
|
||||
|
||||
void exportAttachment({
|
||||
required Attachment attachment,
|
||||
required AccountId? accountId,
|
||||
required Session? session,
|
||||
}) {
|
||||
final cancelToken = CancelToken();
|
||||
|
||||
showDownloadingFileDialog(
|
||||
attachmentName: attachment.name ?? '',
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
|
||||
if (session == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: ExportAttachmentFailure(NotFoundSessionException()),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (accountId == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: ExportAttachmentFailure(NotFoundAccountIdException()),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final baseDownloadUrl = session.getSafetyDownloadUrl(
|
||||
jmapUrl: dynamicUrlInterceptors.jmapUrl,
|
||||
);
|
||||
|
||||
consumeState(
|
||||
exportAttachmentInteractor.execute(
|
||||
attachment,
|
||||
accountId,
|
||||
baseDownloadUrl,
|
||||
cancelToken,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void showDownloadingFileDialog({
|
||||
required String attachmentName,
|
||||
required CancelToken cancelToken,
|
||||
}) {
|
||||
Get.dialog(
|
||||
PointerInterceptor(
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
final appLocalizations = AppLocalizations.of(context);
|
||||
return (DownloadingFileDialogBuilder()
|
||||
..key(const Key('downloading_file_dialog'))
|
||||
..title(appLocalizations.preparing_to_export)
|
||||
..content(appLocalizations.downloading_file(attachmentName))
|
||||
..actionText(appLocalizations.cancel)
|
||||
..addCancelDownloadActionClick(() {
|
||||
cancelToken.cancel([
|
||||
appLocalizations.user_cancel_download_file,
|
||||
]);
|
||||
popBack();
|
||||
}))
|
||||
.build();
|
||||
},
|
||||
),
|
||||
),
|
||||
barrierDismissible: false,
|
||||
);
|
||||
}
|
||||
|
||||
void downloadAttachmentForWeb({
|
||||
required Attachment attachment,
|
||||
required AccountId? accountId,
|
||||
required Session? session,
|
||||
bool previewerSupported = false,
|
||||
StreamController<Either<Failure, Success>>? onReceiveController,
|
||||
DownloadSourceView? sourceView,
|
||||
}) {
|
||||
if (session == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: DownloadAttachmentForWebFailure(
|
||||
attachment: attachment,
|
||||
exception: NotFoundSessionException(),
|
||||
sourceView: sourceView,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (accountId == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: DownloadAttachmentForWebFailure(
|
||||
attachment: attachment,
|
||||
exception: NotFoundAccountIdException(),
|
||||
sourceView: sourceView,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final generateTaskId = DownloadTaskId(uuid.v4());
|
||||
final baseDownloadUrl = session.getSafetyDownloadUrl(
|
||||
jmapUrl: dynamicUrlInterceptors.jmapUrl,
|
||||
);
|
||||
final cancelToken = CancelToken();
|
||||
|
||||
consumeState(downloadAttachmentForWebInteractor.execute(
|
||||
generateTaskId,
|
||||
attachment,
|
||||
accountId,
|
||||
baseDownloadUrl,
|
||||
onReceiveController: onReceiveController,
|
||||
cancelToken: cancelToken,
|
||||
previewerSupported: previewerSupported,
|
||||
sourceView: sourceView,
|
||||
));
|
||||
}
|
||||
|
||||
void exportAttachmentSuccessAction(DownloadedResponse downloadedResponse) {
|
||||
popBack();
|
||||
_openDownloadedPreviewWorkGroupDocument(
|
||||
filePath: downloadedResponse.filePath,
|
||||
mediaType: downloadedResponse.mediaType,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _openDownloadedPreviewWorkGroupDocument({
|
||||
required String filePath,
|
||||
MediaType? mediaType,
|
||||
}) async {
|
||||
if (mediaType == null) {
|
||||
await _saveFileToStorage(filePath);
|
||||
return;
|
||||
}
|
||||
|
||||
final openResult = await open_file.OpenFile.open(
|
||||
filePath,
|
||||
type: Platform.isAndroid ? mediaType.mimeType : null,
|
||||
// "xdg" is default value
|
||||
linuxDesktopName:
|
||||
Platform.isIOS ? mediaType.getDocumentUti().value ?? 'xdg' : 'xdg',
|
||||
);
|
||||
|
||||
if (openResult.type != open_file.ResultType.done) {
|
||||
await _saveFileToStorage(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _saveFileToStorage(String filePath) async {
|
||||
final params = SaveFileDialogParams(sourceFilePath: filePath);
|
||||
await FlutterFileDialog.saveFile(params: params);
|
||||
}
|
||||
|
||||
void exportAllAttachmentsSuccessAction(String filePath) {
|
||||
popBack();
|
||||
_saveFileToStorage(filePath);
|
||||
}
|
||||
|
||||
void exportAllAttachmentsFailureAction(dynamic exception) {
|
||||
if (exception is CancelDownloadFileException) {
|
||||
if (currentOverlayContext != null && currentContext != null) {
|
||||
appToast.showToastWarningMessage(
|
||||
currentOverlayContext!,
|
||||
AppLocalizations.of(currentContext!).user_cancel_download_file,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
popBack();
|
||||
if (currentOverlayContext != null && currentContext != null) {
|
||||
appToast.showToastErrorMessage(
|
||||
currentOverlayContext!,
|
||||
AppLocalizations.of(currentContext!).attachment_download_failed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void exportAttachmentFailureAction(dynamic exception) {
|
||||
if (exception is CancelDownloadFileException) {
|
||||
if (currentOverlayContext != null && currentContext != null) {
|
||||
appToast.showToastWarningMessage(
|
||||
currentOverlayContext!,
|
||||
AppLocalizations.of(currentContext!).user_cancel_download_file,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Get.isDialogOpen == true) {
|
||||
popBack();
|
||||
}
|
||||
|
||||
if (currentOverlayContext != null && currentContext != null) {
|
||||
appToast.showToastErrorMessage(
|
||||
currentOverlayContext!,
|
||||
AppLocalizations.of(currentContext!).attachment_download_failed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void downloadAttachmentForWebFailureAction({
|
||||
required DownloadAttachmentForWebFailure failureState,
|
||||
}) {
|
||||
closeDialogLoading();
|
||||
|
||||
if (failureState.taskId != null) {
|
||||
deleteDownloadTask(failureState.taskId!);
|
||||
}
|
||||
|
||||
if (failureState.attachment != null &&
|
||||
failureState.sourceView == DownloadSourceView.emailView) {
|
||||
pushDownloadUIAction(
|
||||
UpdateAttachmentsViewStateAction(
|
||||
failureState.attachment?.blobId,
|
||||
Left<Failure, Success>(failureState),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (currentOverlayContext == null || currentContext == null) return;
|
||||
|
||||
final appLocalizations = AppLocalizations.of(currentContext!);
|
||||
String message = appLocalizations.attachment_download_failed;
|
||||
if (failureState.attachment is EMLAttachment) {
|
||||
message = appLocalizations.downloadMessageAsEMLFailed;
|
||||
} else if (failureState.cancelToken?.isCancelled == true) {
|
||||
message = appLocalizations.downloadAttachmentHasBeenCancelled;
|
||||
}
|
||||
|
||||
appToast.showToastErrorMessage(currentOverlayContext!, message);
|
||||
}
|
||||
|
||||
void downloadAllAttachmentsForWebFailure({
|
||||
required DownloadAllAttachmentsForWebFailure failureState,
|
||||
}) {
|
||||
deleteDownloadTask(failureState.taskId);
|
||||
|
||||
if (currentOverlayContext == null || currentContext == null) return;
|
||||
|
||||
final appLocalizations = AppLocalizations.of(currentContext!);
|
||||
final message = failureState.cancelToken?.isCancelled == true
|
||||
? appLocalizations.downloadAttachmentHasBeenCancelled
|
||||
: appLocalizations.attachment_download_failed;
|
||||
|
||||
appToast.showToastErrorMessage(currentOverlayContext!, message);
|
||||
}
|
||||
|
||||
void downloadFileWeb({
|
||||
required String fileName,
|
||||
required Uint8List fileBytes,
|
||||
}) {
|
||||
downloadManager.createAnchorElementDownloadFileWeb(
|
||||
fileBytes,
|
||||
fileName,
|
||||
);
|
||||
}
|
||||
|
||||
void downloadAttachmentInEMLPreview({
|
||||
required OnDownloadAttachmentFileAction onDownloadAction,
|
||||
required Uri? uri,
|
||||
}) {
|
||||
if (uri == null) return;
|
||||
|
||||
final attachment = EmailUtils.parsingAttachmentByUri(uri);
|
||||
if (attachment == null) return;
|
||||
|
||||
onDownloadAction(attachment);
|
||||
}
|
||||
|
||||
void exportAllAttachments({
|
||||
required String outputFileName,
|
||||
required EmailId? emailId,
|
||||
required AccountId? accountId,
|
||||
required Session? session,
|
||||
}) {
|
||||
final cancelToken = CancelToken();
|
||||
|
||||
showDownloadingFileDialog(
|
||||
attachmentName: outputFileName,
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
|
||||
if (session == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: ExportAllAttachmentsFailure(
|
||||
exception: NotFoundSessionException(),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (accountId == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: ExportAllAttachmentsFailure(
|
||||
exception: NotFoundAccountIdException(),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (emailId == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: ExportAllAttachmentsFailure(
|
||||
exception: NotFoundEmailException(),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final downloadAllSupported = session.isDownloadAllSupported(accountId);
|
||||
if (!downloadAllSupported) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: ExportAllAttachmentsFailure(
|
||||
exception: CapabilityDownloadAllNotSupportedException(),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final baseDownloadAllUrl =
|
||||
session.getDownloadAllCapability(accountId)!.endpoint!;
|
||||
|
||||
consumeState(
|
||||
exportAllAttachmentsInteractor.execute(
|
||||
accountId,
|
||||
emailId,
|
||||
baseDownloadAllUrl,
|
||||
outputFileName,
|
||||
cancelToken,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void downloadAllAttachmentsForWeb({
|
||||
required String outputFileName,
|
||||
required EmailId? emailId,
|
||||
required AccountId? accountId,
|
||||
required Session? session,
|
||||
bool previewerSupported = false,
|
||||
StreamController<Either<Failure, Success>>? onReceiveController,
|
||||
}) {
|
||||
final taskId = DownloadTaskId(uuid.v4());
|
||||
|
||||
if (session == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: DownloadAllAttachmentsForWebFailure(
|
||||
exception: NotFoundSessionException(),
|
||||
taskId: taskId,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (accountId == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: DownloadAllAttachmentsForWebFailure(
|
||||
exception: NotFoundAccountIdException(),
|
||||
taskId: taskId,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (emailId == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: DownloadAllAttachmentsForWebFailure(
|
||||
exception: NotFoundEmailException(),
|
||||
taskId: taskId,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final downloadAllSupported = session.isDownloadAllSupported(accountId);
|
||||
|
||||
if (!downloadAllSupported) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: DownloadAllAttachmentsForWebFailure(
|
||||
exception: CapabilityDownloadAllNotSupportedException(),
|
||||
taskId: taskId,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final baseDownloadAllUrl =
|
||||
session.getDownloadAllCapability(accountId)!.endpoint!;
|
||||
|
||||
final downloadAttachment = Attachment(
|
||||
name: outputFileName,
|
||||
type: MediaType('application', 'zip'),
|
||||
);
|
||||
|
||||
final cancelToken = CancelToken();
|
||||
|
||||
consumeState(
|
||||
downloadAllAttachmentsForWebInteractor.execute(
|
||||
accountId,
|
||||
emailId,
|
||||
baseDownloadAllUrl,
|
||||
downloadAttachment,
|
||||
taskId,
|
||||
onReceiveController: onReceiveController,
|
||||
cancelToken: cancelToken,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void downloadMessageAsEML({
|
||||
required PresentationEmail presentationEmail,
|
||||
required AccountId? accountId,
|
||||
required Session? session,
|
||||
bool showBottomDownloadProgressBar = false,
|
||||
}) {
|
||||
if (session == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: DownloadAttachmentForWebFailure(
|
||||
exception: NotFoundSessionException(),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (accountId == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: DownloadAttachmentForWebFailure(
|
||||
exception: NotFoundAccountIdException(),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final emlAttachment = presentationEmail.createEMLAttachment();
|
||||
if (emlAttachment.blobId == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: DownloadAttachmentForWebFailure(
|
||||
exception: NotFoundEmailBlobIdException(),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final generateTaskId = DownloadTaskId(uuid.v4());
|
||||
final baseDownloadUrl = session.getSafetyDownloadUrl(
|
||||
jmapUrl: dynamicUrlInterceptors.jmapUrl,
|
||||
);
|
||||
final cancelToken = CancelToken();
|
||||
|
||||
consumeState(
|
||||
downloadAttachmentForWebInteractor.execute(
|
||||
generateTaskId,
|
||||
emlAttachment,
|
||||
accountId,
|
||||
baseDownloadUrl,
|
||||
onReceiveController: showBottomDownloadProgressBar
|
||||
? downloadProgressStateController
|
||||
: null,
|
||||
cancelToken: cancelToken,
|
||||
previewerSupported: false,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void handleDownloadAttachmentForWebSuccess(
|
||||
DownloadAttachmentForWebSuccess success,
|
||||
) {
|
||||
closeDialogLoading();
|
||||
|
||||
if (success.sourceView == DownloadSourceView.emailView) {
|
||||
pushDownloadUIAction(UpdateAttachmentsViewStateAction(
|
||||
success.attachment.blobId,
|
||||
Right<Failure, Success>(success),
|
||||
));
|
||||
}
|
||||
|
||||
deleteDownloadTask(success.taskId);
|
||||
|
||||
if (!success.previewerSupported) {
|
||||
downloadFileWeb(
|
||||
fileBytes: success.bytes,
|
||||
fileName: success.attachment.generateFileName(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (success.attachment.isImage) {
|
||||
previewImageFile(
|
||||
fileName: success.attachment.generateFileName(),
|
||||
imageBytes: success.bytes,
|
||||
context: currentContext,
|
||||
onDownloadWebFileAction: (name, bytes) => downloadFileWeb(
|
||||
fileName: name,
|
||||
fileBytes: bytes,
|
||||
),
|
||||
);
|
||||
} else if (success.attachment.isText || success.attachment.isJson) {
|
||||
previewPlainTextFile(
|
||||
fileName: success.attachment.generateFileName(),
|
||||
fileBytes: success.bytes,
|
||||
context: currentContext,
|
||||
onDownloadWebFileAction: (name, bytes) => downloadFileWeb(
|
||||
fileName: name,
|
||||
fileBytes: bytes,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
+763
@@ -0,0 +1,763 @@
|
||||
import 'package:core/domain/exceptions/web_session_exception.dart';
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/dom/sanitize_hyper_link_tag_in_html_transformers.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/text/standardize_html_sanitizing_transformers.dart';
|
||||
import 'package:core/presentation/utils/html_transformer/transform_configuration.dart';
|
||||
import 'package:core/presentation/views/html_viewer/html_content_viewer_widget.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/utils/html/html_utils.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:get/get_navigation/src/dialog/dialog_route.dart';
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:model/download/download_task_id.dart';
|
||||
import 'package:model/email/attachment.dart';
|
||||
import 'package:model/extensions/session_extension.dart';
|
||||
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/exceptions/download_attachment_exceptions.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/model/download_source_view.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/download_and_get_html_content_from_attachment_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/get_html_content_from_upload_file_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/parse_email_by_blob_id_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/domain/state/preview_email_from_eml_file_state.dart';
|
||||
import 'package:tmail_ui_user/features/download/presentation/controllers/download_controller.dart';
|
||||
import 'package:tmail_ui_user/features/download/presentation/extensions/download_attachment_download_controller_extension.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/model/preview_email_eml_request.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/extensions/attachment_extension.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/model/eml_previewer.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_item_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/widgets/html_attachment_previewer.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/widgets/pdf_viewer/pdf_viewer.dart';
|
||||
import 'package:tmail_ui_user/features/email_previewer/email_previewer_dialog_view.dart';
|
||||
import 'package:tmail_ui_user/features/home/data/exceptions/session_exceptions.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/action/download_ui_action.dart';
|
||||
import 'package:tmail_ui_user/features/upload/presentation/model/upload_file_state.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:tmail_ui_user/main/routes/route_utils.dart';
|
||||
import 'package:twake_previewer_flutter/core/constants/supported_charset.dart';
|
||||
import 'package:twake_previewer_flutter/core/previewer_options/options/previewer_state.dart';
|
||||
import 'package:twake_previewer_flutter/core/previewer_options/options/top_bar_options.dart';
|
||||
import 'package:twake_previewer_flutter/core/previewer_options/previewer_options.dart';
|
||||
import 'package:twake_previewer_flutter/twake_image_previewer/twake_image_previewer.dart';
|
||||
import 'package:twake_previewer_flutter/twake_plain_text_previewer/twake_plain_text_previewer.dart';
|
||||
|
||||
typedef OnPreviewOrDownloadAttachmentAction = void Function(
|
||||
Attachment attachment,
|
||||
bool isPreviewSupported,
|
||||
);
|
||||
|
||||
extension PreviewAttachmentDownloadControllerExtension on DownloadController {
|
||||
void previewAttachment({
|
||||
required BuildContext context,
|
||||
required Attachment attachment,
|
||||
required AccountId? accountId,
|
||||
required Session? session,
|
||||
required String ownEmailAddress,
|
||||
required OnPreviewOrDownloadAttachmentAction onPreviewOrDownloadAction,
|
||||
bool isDialogLoadingVisible = false,
|
||||
DownloadSourceView? sourceView,
|
||||
}) {
|
||||
final appLocalizations = AppLocalizations.of(context);
|
||||
|
||||
if (PlatformInfo.isWeb && attachment.isPDFFile) {
|
||||
_previewPDFFile(
|
||||
context: context,
|
||||
attachment: attachment,
|
||||
accountId: accountId,
|
||||
session: session,
|
||||
);
|
||||
} else if (attachment.isEMLFile) {
|
||||
_preparePreviewEMLFile(
|
||||
appLocalizations: appLocalizations,
|
||||
accountId: accountId,
|
||||
session: session,
|
||||
ownEmailAddress: ownEmailAddress,
|
||||
blobId: attachment.blobId,
|
||||
);
|
||||
} else if (attachment.isHTMLFile) {
|
||||
_preparePreviewHtmlFile(
|
||||
appLocalizations: appLocalizations,
|
||||
session: session,
|
||||
accountId: accountId,
|
||||
attachment: attachment,
|
||||
isDialogLoadingVisible: isDialogLoadingVisible,
|
||||
sourceView: sourceView,
|
||||
);
|
||||
} else {
|
||||
if (isDialogLoadingVisible) {
|
||||
showDialogLoading(appLocalizations);
|
||||
}
|
||||
onPreviewOrDownloadAction(
|
||||
attachment,
|
||||
attachment.isPreviewSupported,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void previewUploadFile({
|
||||
required BuildContext context,
|
||||
required UploadFileState uploadFile,
|
||||
required AccountId? accountId,
|
||||
required Session? session,
|
||||
required String ownEmailAddress,
|
||||
required OnPreviewOrDownloadAttachmentAction onPreviewOrDownloadAction,
|
||||
bool isDialogLoadingVisible = false,
|
||||
}) {
|
||||
final attachment = uploadFile.attachment;
|
||||
final appLocalizations = AppLocalizations.of(context);
|
||||
|
||||
if (attachment == null) {
|
||||
showPreviewNotAvailableToastMessage(context);
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlatformInfo.isWeb && attachment.isPDFFile == true) {
|
||||
_previewPDFFile(
|
||||
context: context,
|
||||
attachment: attachment,
|
||||
accountId: accountId,
|
||||
session: session,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (attachment.isEMLFile == true) {
|
||||
_preparePreviewEMLFile(
|
||||
appLocalizations: appLocalizations,
|
||||
accountId: accountId,
|
||||
session: session,
|
||||
ownEmailAddress: ownEmailAddress,
|
||||
blobId: attachment.blobId,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (attachment.isHTMLFile == true) {
|
||||
if (uploadFile.file?.bytes != null) {
|
||||
_preparePreviewHtmlFileByUploadFile(
|
||||
appLocalizations: appLocalizations,
|
||||
uploadFile: uploadFile,
|
||||
accountId: accountId,
|
||||
session: session,
|
||||
isDialogLoadingVisible: isDialogLoadingVisible,
|
||||
);
|
||||
} else {
|
||||
_preparePreviewHtmlFile(
|
||||
appLocalizations: appLocalizations,
|
||||
attachment: attachment,
|
||||
accountId: accountId,
|
||||
session: session,
|
||||
isDialogLoadingVisible: isDialogLoadingVisible,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (attachment.isImage == true && uploadFile.file?.bytes != null) {
|
||||
previewImageFile(
|
||||
fileName: attachment.generateFileName(),
|
||||
imageBytes: uploadFile.file!.bytes!,
|
||||
context: context,
|
||||
onDownloadWebFileAction: (fileName, fileBytes) => downloadFileWeb(
|
||||
fileName: fileName,
|
||||
fileBytes: fileBytes,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((attachment.isText == true || attachment.isJson == true) &&
|
||||
uploadFile.file?.bytes != null) {
|
||||
previewPlainTextFile(
|
||||
fileName: attachment.generateFileName(),
|
||||
fileBytes: uploadFile.file!.bytes!,
|
||||
context: context,
|
||||
onDownloadWebFileAction: (fileName, fileBytes) => downloadFileWeb(
|
||||
fileName: fileName,
|
||||
fileBytes: fileBytes,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (uploadFile.file?.bytes != null) {
|
||||
downloadFileWeb(
|
||||
fileName: attachment.generateFileName(),
|
||||
fileBytes: uploadFile.file!.bytes!,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDialogLoadingVisible) {
|
||||
showDialogLoading(appLocalizations);
|
||||
}
|
||||
onPreviewOrDownloadAction(attachment, attachment.isPreviewSupported);
|
||||
}
|
||||
|
||||
Future<void> _previewPDFFile({
|
||||
required BuildContext context,
|
||||
required Attachment attachment,
|
||||
required AccountId? accountId,
|
||||
required Session? session,
|
||||
}) async {
|
||||
final downloadUrl = session?.getSafetyDownloadUrl(
|
||||
jmapUrl: dynamicUrlInterceptors.jmapUrl,
|
||||
);
|
||||
|
||||
if (accountId == null || session == null || downloadUrl == null) {
|
||||
showPreviewNotAvailableToastMessage(context);
|
||||
return;
|
||||
}
|
||||
|
||||
await Get.generalDialog(
|
||||
barrierColor: Colors.black.withValues(alpha: 0.8),
|
||||
pageBuilder: (_, __, ___) {
|
||||
return PointerInterceptor(
|
||||
child: PDFViewer(
|
||||
attachment: attachment,
|
||||
accountId: accountId,
|
||||
downloadUrl: downloadUrl,
|
||||
downloadAction: (bytes, name) =>
|
||||
downloadFileWeb(fileName: name, fileBytes: bytes),
|
||||
printAction: printUtils.printPDFFile,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _preparePreviewEMLFile({
|
||||
required AppLocalizations appLocalizations,
|
||||
required AccountId? accountId,
|
||||
required Session? session,
|
||||
required String ownEmailAddress,
|
||||
required Id? blobId,
|
||||
}) {
|
||||
showDialogLoading(appLocalizations);
|
||||
|
||||
if (session == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: ParseEmailByBlobIdFailure(NotFoundSessionException()),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (accountId == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: ParseEmailByBlobIdFailure(NotFoundAccountIdException()),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (blobId == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: ParseEmailByBlobIdFailure(NotFoundBlobIdException([])),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
consumeState(
|
||||
parseEmailByBlobIdInteractor.execute(
|
||||
accountId,
|
||||
session,
|
||||
ownEmailAddress,
|
||||
blobId,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _preparePreviewHtmlFile({
|
||||
required AppLocalizations appLocalizations,
|
||||
required Session? session,
|
||||
required AccountId? accountId,
|
||||
required Attachment attachment,
|
||||
bool isDialogLoadingVisible = false,
|
||||
DownloadSourceView? sourceView,
|
||||
}) {
|
||||
if (isDialogLoadingVisible) {
|
||||
showDialogLoading(appLocalizations);
|
||||
}
|
||||
|
||||
final downloadUrl = session?.getSafetyDownloadUrl(
|
||||
jmapUrl: dynamicUrlInterceptors.jmapUrl,
|
||||
);
|
||||
final blobId = attachment.blobId;
|
||||
|
||||
if (session == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: DownloadAndGetHtmlContentFromAttachmentFailure(
|
||||
exception: NotFoundSessionException(),
|
||||
blobId: blobId,
|
||||
sourceView: sourceView,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (accountId == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: DownloadAndGetHtmlContentFromAttachmentFailure(
|
||||
exception: NotFoundAccountIdException(),
|
||||
blobId: blobId,
|
||||
sourceView: sourceView,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (blobId == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: DownloadAndGetHtmlContentFromAttachmentFailure(
|
||||
exception: NotFoundBlobIdException([]),
|
||||
blobId: blobId,
|
||||
sourceView: sourceView,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (downloadUrl == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: DownloadAndGetHtmlContentFromAttachmentFailure(
|
||||
exception: DownloadUrlIsNullException(),
|
||||
blobId: blobId,
|
||||
sourceView: sourceView,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
consumeState(
|
||||
downloadAndGetHtmlContentFromAttachmentInteractor.execute(
|
||||
accountId,
|
||||
session,
|
||||
attachment,
|
||||
DownloadTaskId(blobId.value),
|
||||
downloadUrl,
|
||||
TransformConfiguration.create(
|
||||
customDomTransformers: [SanitizeHyperLinkTagInHtmlTransformer()],
|
||||
customTextTransformers: [
|
||||
const StandardizeHtmlSanitizingTransformers()
|
||||
],
|
||||
),
|
||||
sourceView: sourceView,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _preparePreviewHtmlFileByUploadFile({
|
||||
required AppLocalizations appLocalizations,
|
||||
required UploadFileState uploadFile,
|
||||
required AccountId? accountId,
|
||||
required Session? session,
|
||||
bool isDialogLoadingVisible = false,
|
||||
}) {
|
||||
if (isDialogLoadingVisible) {
|
||||
showDialogLoading(appLocalizations);
|
||||
}
|
||||
consumeState(
|
||||
getHtmlContentFromUploadFileInteractor.execute(
|
||||
uploadFile: uploadFile,
|
||||
accountId: accountId,
|
||||
session: session,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void handleParseEmailByBlobIdSuccess({
|
||||
required BuildContext? context,
|
||||
required AccountId accountId,
|
||||
required Session session,
|
||||
required String ownEmailAddress,
|
||||
required Id blobId,
|
||||
required Email email,
|
||||
}) {
|
||||
if (context == null) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: PreviewEmailFromEmlFileFailure(NotFoundContextException()),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final downloadUrl = session.getDownloadUrl(
|
||||
jmapUrl: dynamicUrlInterceptors.jmapUrl,
|
||||
);
|
||||
|
||||
if (downloadUrl.isEmpty) {
|
||||
emitFailure(
|
||||
controller: this,
|
||||
failure: PreviewEmailFromEmlFileFailure(DownloadUrlIsNullException()),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
consumeState(
|
||||
previewEmailFromEmlFileInteractor.execute(
|
||||
PreviewEmailEMLRequest(
|
||||
accountId: accountId,
|
||||
session: session,
|
||||
ownEmailAddress: ownEmailAddress,
|
||||
blobId: blobId,
|
||||
email: email,
|
||||
locale: Localizations.localeOf(context),
|
||||
appLocalizations: AppLocalizations.of(context),
|
||||
baseDownloadUrl: downloadUrl,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void handleParseEmailByBlobIdFailure(ParseEmailByBlobIdFailure failure) {
|
||||
closeDialogLoading();
|
||||
toastManager.showMessageFailure(failure);
|
||||
}
|
||||
|
||||
void handlePreviewEmailFromEMLFileFailure(
|
||||
PreviewEmailFromEmlFileFailure failure,
|
||||
) {
|
||||
closeDialogLoading();
|
||||
toastManager.showMessageFailure(failure);
|
||||
}
|
||||
|
||||
void handleGetHtmlContentFromUploadFileSuccess(
|
||||
GetHtmlContentFromUploadFileSuccess success,
|
||||
) {
|
||||
closeDialogLoading();
|
||||
|
||||
previewHtmlFile(
|
||||
attachment: success.attachment,
|
||||
title: success.htmlAttachmentTitle,
|
||||
content: success.sanitizedHtmlContent,
|
||||
openMailToLink: (uri) async {
|
||||
if (uri == null) return;
|
||||
pushDownloadUIAction(OpenComposerFromMailtoLinkAction(uri));
|
||||
},
|
||||
onDownloadAction: (attachment) => downloadAttachment(
|
||||
attachment: attachment,
|
||||
accountId: success.accountId,
|
||||
session: success.session,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void handleDownloadAndGetHtmlContentFromAttachmentSuccess(
|
||||
DownloadAndGetHtmlContentFromAttachmentSuccess success,
|
||||
) {
|
||||
if (success.sourceView == DownloadSourceView.emailView) {
|
||||
pushDownloadUIAction(
|
||||
UpdateAttachmentsViewStateAction(
|
||||
success.attachment.blobId,
|
||||
Right<Failure, Success>(success),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
closeDialogLoading();
|
||||
|
||||
previewHtmlFile(
|
||||
attachment: success.attachment,
|
||||
title: success.htmlAttachmentTitle,
|
||||
content: success.sanitizedHtmlContent,
|
||||
openMailToLink: (uri) async {
|
||||
if (uri == null) return;
|
||||
pushDownloadUIAction(OpenComposerFromMailtoLinkAction(uri));
|
||||
},
|
||||
onDownloadAction: (attachment) => downloadAttachment(
|
||||
attachment: attachment,
|
||||
accountId: success.accountId,
|
||||
session: success.session,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void handlePreviewEmailFromEmlFileSuccess(
|
||||
PreviewEmailFromEmlFileSuccess success,
|
||||
) {
|
||||
previewEMLFile(
|
||||
emlPreviewer: success.emlPreviewer,
|
||||
context: currentContext,
|
||||
onMailtoAction: (uri) async {
|
||||
if (uri == null) return;
|
||||
pushDownloadUIAction(OpenComposerFromMailtoLinkAction(uri));
|
||||
},
|
||||
onDownloadAction: (uri) async => downloadAttachmentInEMLPreview(
|
||||
uri: uri,
|
||||
onDownloadAction: (attachment) => downloadAttachment(
|
||||
attachment: attachment,
|
||||
accountId: success.accountId,
|
||||
session: success.session,
|
||||
)),
|
||||
onPreviewAction: (uri) async => openEMLPreviewer(
|
||||
accountId: success.accountId,
|
||||
session: success.session,
|
||||
ownEmailAddress: success.ownEmailAddress,
|
||||
uri: uri,
|
||||
appLocalizations: success.appLocalizations,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void previewEMLFile({
|
||||
required EMLPreviewer emlPreviewer,
|
||||
required BuildContext? context,
|
||||
required OnMailtoDelegateAction onMailtoAction,
|
||||
required OnDownloadAttachmentDelegateAction onDownloadAction,
|
||||
required OnPreviewEMLDelegateAction onPreviewAction,
|
||||
}) {
|
||||
closeDialogLoading();
|
||||
|
||||
if (PlatformInfo.isWeb) {
|
||||
bool isOpen = HtmlUtils.openNewWindowByUrl(
|
||||
RouteUtils.createUrlWebLocationBar(
|
||||
AppRoutes.emailEMLPreviewer,
|
||||
previewId: emlPreviewer.id,
|
||||
).toString(),
|
||||
);
|
||||
|
||||
if (!isOpen) {
|
||||
toastManager.showMessageFailure(
|
||||
PreviewEmailFromEmlFileFailure(CannotOpenNewWindowException()),
|
||||
);
|
||||
}
|
||||
} else if (PlatformInfo.isMobile) {
|
||||
if (context == null) {
|
||||
toastManager.showMessageFailure(
|
||||
PreviewEmailFromEmlFileFailure(NotFoundContextException()),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlatformInfo.isAndroid) {
|
||||
showModalSheetToPreviewEMLAttachment(
|
||||
context: context,
|
||||
emlPreviewer: emlPreviewer,
|
||||
onMailtoAction: onMailtoAction,
|
||||
onDownloadAction: onDownloadAction,
|
||||
onPreviewAction: onPreviewAction,
|
||||
);
|
||||
} else if (PlatformInfo.isIOS) {
|
||||
showDialogToPreviewEMLAttachment(
|
||||
context: context,
|
||||
emlPreviewer: emlPreviewer,
|
||||
onMailtoAction: onMailtoAction,
|
||||
onDownloadAction: onDownloadAction,
|
||||
onPreviewAction: onPreviewAction,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void showModalSheetToPreviewEMLAttachment({
|
||||
required BuildContext context,
|
||||
required EMLPreviewer emlPreviewer,
|
||||
required OnMailtoDelegateAction onMailtoAction,
|
||||
required OnDownloadAttachmentDelegateAction onDownloadAction,
|
||||
required OnPreviewEMLDelegateAction onPreviewAction,
|
||||
}) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
showDragHandle: true,
|
||||
useSafeArea: true,
|
||||
isScrollControlled: true,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(20.0),
|
||||
topRight: Radius.circular(20.0),
|
||||
),
|
||||
),
|
||||
builder: (_) {
|
||||
return DraggableScrollableSheet(
|
||||
initialChildSize: 1.0,
|
||||
builder: (context, ___) => EmailPreviewerDialogView(
|
||||
emlPreviewer: emlPreviewer,
|
||||
imagePaths: imagePaths,
|
||||
onMailtoDelegateAction: onMailtoAction,
|
||||
onPreviewEMLDelegateAction: onPreviewAction,
|
||||
onDownloadAttachmentDelegateAction: onDownloadAction,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void showDialogToPreviewEMLAttachment({
|
||||
required BuildContext context,
|
||||
required EMLPreviewer emlPreviewer,
|
||||
required OnMailtoDelegateAction onMailtoAction,
|
||||
required OnDownloadAttachmentDelegateAction onDownloadAction,
|
||||
required OnPreviewEMLDelegateAction onPreviewAction,
|
||||
}) {
|
||||
Get.dialog(
|
||||
EmailPreviewerDialogView(
|
||||
emlPreviewer: emlPreviewer,
|
||||
imagePaths: imagePaths,
|
||||
onMailtoDelegateAction: onMailtoAction,
|
||||
onPreviewEMLDelegateAction: onPreviewAction,
|
||||
onDownloadAttachmentDelegateAction: onDownloadAction,
|
||||
),
|
||||
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
|
||||
);
|
||||
}
|
||||
|
||||
void handlePreviewHtmlFileFailure({required Failure failureState}) {
|
||||
if (failureState is DownloadAndGetHtmlContentFromAttachmentFailure &&
|
||||
failureState.sourceView == DownloadSourceView.emailView) {
|
||||
pushDownloadUIAction(
|
||||
UpdateAttachmentsViewStateAction(
|
||||
failureState.blobId,
|
||||
Left<Failure, Success>(failureState),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
closeDialogLoading();
|
||||
|
||||
if (currentOverlayContext != null && currentContext != null) {
|
||||
appToast.showToastErrorMessage(
|
||||
currentOverlayContext!,
|
||||
AppLocalizations.of(currentContext!)
|
||||
.thisHtmlAttachmentCannotBePreviewed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void previewImageFile({
|
||||
required String fileName,
|
||||
required Uint8List imageBytes,
|
||||
required BuildContext? context,
|
||||
required OnDownloadWebFileAction onDownloadWebFileAction,
|
||||
}) {
|
||||
log('$runtimeType::previewImageFile: Attachment fileName is $fileName');
|
||||
if (context == null) return;
|
||||
|
||||
Navigator.of(context).push(
|
||||
GetDialogRoute(
|
||||
pageBuilder: (context, _, __) => PointerInterceptor(
|
||||
child: TwakeImagePreviewer(
|
||||
bytes: imageBytes,
|
||||
zoomable: true,
|
||||
previewerOptions: const PreviewerOptions(
|
||||
previewerState: PreviewerState.success,
|
||||
),
|
||||
topBarOptions: TopBarOptions(
|
||||
title: fileName,
|
||||
onClose: () => Navigator.maybePop(context),
|
||||
onDownload: () => onDownloadWebFileAction(fileName, imageBytes),
|
||||
),
|
||||
),
|
||||
),
|
||||
barrierDismissible: false,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void previewPlainTextFile({
|
||||
required String fileName,
|
||||
required Uint8List fileBytes,
|
||||
required BuildContext? context,
|
||||
required OnDownloadWebFileAction onDownloadWebFileAction,
|
||||
}) {
|
||||
log('$runtimeType::previewPlainTextFile: Attachment fileName is $fileName');
|
||||
if (context == null) return;
|
||||
|
||||
Navigator.of(context).push(
|
||||
GetDialogRoute(
|
||||
pageBuilder: (context, _, __) => PointerInterceptor(
|
||||
child: TwakePlainTextPreviewer(
|
||||
supportedCharset: SupportedCharset.utf8,
|
||||
bytes: fileBytes,
|
||||
previewerOptions: PreviewerOptions(
|
||||
previewerState: PreviewerState.success,
|
||||
width: context.width * 0.8,
|
||||
),
|
||||
topBarOptions: TopBarOptions(
|
||||
title: fileName,
|
||||
onClose: () => Navigator.maybePop(context),
|
||||
onDownload: () => onDownloadWebFileAction(fileName, fileBytes),
|
||||
),
|
||||
),
|
||||
),
|
||||
barrierDismissible: false,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void previewHtmlFile({
|
||||
required Attachment attachment,
|
||||
required String title,
|
||||
required String content,
|
||||
required OnMailtoDelegateAction openMailToLink,
|
||||
required OnDownloadAttachmentFileAction onDownloadAction,
|
||||
}) {
|
||||
Get.dialog(
|
||||
HtmlAttachmentPreviewer(
|
||||
title: title,
|
||||
htmlContent: content,
|
||||
mailToClicked: openMailToLink,
|
||||
downloadAttachmentClicked: () => onDownloadAction(attachment),
|
||||
responsiveUtils: responsiveUtils,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> openEMLPreviewer({
|
||||
required AppLocalizations appLocalizations,
|
||||
required Uri? uri,
|
||||
required AccountId? accountId,
|
||||
required Session? session,
|
||||
required String ownEmailAddress,
|
||||
}) async {
|
||||
if (uri == null) return;
|
||||
|
||||
final blobId = uri.path;
|
||||
if (blobId.isEmpty) return;
|
||||
|
||||
_preparePreviewEMLFile(
|
||||
appLocalizations: appLocalizations,
|
||||
accountId: accountId,
|
||||
session: session,
|
||||
ownEmailAddress: ownEmailAddress,
|
||||
blobId: Id(blobId),
|
||||
);
|
||||
}
|
||||
|
||||
void showDialogLoading(AppLocalizations appLocalizations) {
|
||||
SmartDialog.showLoading(
|
||||
msg: appLocalizations.loadingPleaseWait,
|
||||
maskColor: Colors.black38,
|
||||
);
|
||||
}
|
||||
|
||||
void closeDialogLoading() {
|
||||
if (SmartDialog.checkExist()) {
|
||||
SmartDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
void showPreviewNotAvailableToastMessage(BuildContext context) {
|
||||
appToast.showToastErrorMessage(
|
||||
context,
|
||||
AppLocalizations.of(context).noPreviewAvailable,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user