TF-3454 Download all attachments as ZIP
This commit is contained in:
@@ -201,4 +201,24 @@ abstract class EmailDataSource {
|
||||
Future<void> storePreviewEMLContentToSessionStorage(EMLPreviewer emlPreviewer);
|
||||
|
||||
Future<EMLPreviewer> getPreviewEMLContentInMemory(String keyStored);
|
||||
|
||||
Future<void> downloadAllAttachmentsForWeb(
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
String baseDownloadAllUrl,
|
||||
String outputFileName,
|
||||
AccountRequest accountRequest,
|
||||
DownloadTaskId taskId,
|
||||
StreamController<Either<Failure, Success>> onReceiveController,
|
||||
{CancelToken? cancelToken}
|
||||
);
|
||||
|
||||
Future<DownloadedResponse> exportAllAttachments(
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
String baseDownloadAllUrl,
|
||||
String outputFileName,
|
||||
AccountRequest accountRequest,
|
||||
{CancelToken? cancelToken}
|
||||
);
|
||||
}
|
||||
@@ -540,4 +540,46 @@ class EmailDataSourceImpl extends EmailDataSource {
|
||||
Future<EMLPreviewer> getPreviewEMLContentInMemory(String keyStored) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> downloadAllAttachmentsForWeb(
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
String baseDownloadAllUrl,
|
||||
String outputFileName,
|
||||
AccountRequest accountRequest,
|
||||
DownloadTaskId taskId,
|
||||
StreamController<Either<Failure, Success>> onReceiveController,
|
||||
{CancelToken? cancelToken}
|
||||
) => Future.sync(() async {
|
||||
return await emailAPI.downloadAllAttachmentsForWeb(
|
||||
accountId,
|
||||
emailId,
|
||||
baseDownloadAllUrl,
|
||||
outputFileName,
|
||||
accountRequest,
|
||||
taskId,
|
||||
onReceiveController,
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
}).catchError(_exceptionThrower.throwException);
|
||||
|
||||
@override
|
||||
Future<DownloadedResponse> exportAllAttachments(
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
String baseDownloadAllUrl,
|
||||
String outputFileName,
|
||||
AccountRequest accountRequest, {
|
||||
CancelToken? cancelToken,
|
||||
}) => Future.sync(() async {
|
||||
return await emailAPI.exportAllAttachments(
|
||||
accountId,
|
||||
emailId,
|
||||
baseDownloadAllUrl,
|
||||
outputFileName,
|
||||
accountRequest,
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
}).catchError(_exceptionThrower.throwException);
|
||||
}
|
||||
@@ -563,4 +563,23 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
|
||||
Future<EMLPreviewer> getPreviewEMLContentInMemory(String keyStored) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> downloadAllAttachmentsForWeb(
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
String baseDownloadAllUrl,
|
||||
String outputFileName,
|
||||
AccountRequest accountRequest,
|
||||
DownloadTaskId taskId,
|
||||
StreamController<Either<Failure, Success>> onReceiveController,
|
||||
{CancelToken? cancelToken}
|
||||
) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DownloadedResponse> exportAllAttachments(AccountId accountId, EmailId emailId, String baseDownloadAllUrl, String outputFileName, AccountRequest accountRequest, {CancelToken? cancelToken}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
@@ -254,4 +254,23 @@ class EmailLocalStorageDataSourceImpl extends EmailDataSource {
|
||||
Future<void> markAsForwarded(Session session, AccountId accountId, List<EmailId> emailIds) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> downloadAllAttachmentsForWeb(
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
String baseDownloadAllUrl,
|
||||
String outputFileName,
|
||||
AccountRequest accountRequest,
|
||||
DownloadTaskId taskId,
|
||||
StreamController<Either<Failure, Success>> onReceiveController,
|
||||
{CancelToken? cancelToken}
|
||||
) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DownloadedResponse> exportAllAttachments(AccountId accountId, EmailId emailId, String baseDownloadAllUrl, String outputFileName, AccountRequest accountRequest, {CancelToken? cancelToken}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
@@ -252,4 +252,23 @@ class EmailSessionStorageDatasourceImpl extends EmailDataSource {
|
||||
Future<void> markAsForwarded(Session session, AccountId accountId, List<EmailId> emailIds) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> downloadAllAttachmentsForWeb(
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
String baseDownloadAllUrl,
|
||||
String outputFileName,
|
||||
AccountRequest accountRequest,
|
||||
DownloadTaskId taskId,
|
||||
StreamController<Either<Failure, Success>> onReceiveController,
|
||||
{CancelToken? cancelToken}
|
||||
) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<DownloadedResponse> exportAllAttachments(AccountId accountId, EmailId emailId, String baseDownloadAllUrl, String outputFileName, AccountRequest accountRequest, {CancelToken? cancelToken}) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@ 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/account_id_extensions.dart';
|
||||
import 'package:model/extensions/email_extension.dart';
|
||||
import 'package:model/extensions/email_id_extensions.dart';
|
||||
import 'package:model/extensions/keyword_identifier_extension.dart';
|
||||
@@ -66,11 +67,13 @@ import 'package:tmail_ui_user/features/email/domain/extensions/email_id_extensio
|
||||
import 'package:tmail_ui_user/features/email/domain/model/event_action.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/model/move_to_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/model/restore_deleted_message_request.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/download_all_attachments_for_web_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/download_attachment_for_web_state.dart';
|
||||
import 'package:tmail_ui_user/features/login/domain/exceptions/authentication_exception.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.dart';
|
||||
import 'package:tmail_ui_user/main/error/capability_validator.dart';
|
||||
import 'package:uri/uri.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class EmailAPI with HandleSetErrorMixin {
|
||||
@@ -402,6 +405,88 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
return bytesDownloaded;
|
||||
}
|
||||
|
||||
Future<void> downloadAllAttachmentsForWeb(
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
String baseDownloadAllUrl,
|
||||
String outputFileName,
|
||||
AccountRequest accountRequest,
|
||||
DownloadTaskId taskId,
|
||||
StreamController<Either<Failure, Success>> onReceiveController,
|
||||
{CancelToken? cancelToken}
|
||||
) async {
|
||||
final authentication = accountRequest.authenticationType == AuthenticationType.oidc
|
||||
? accountRequest.bearerToken
|
||||
: accountRequest.basicAuth;
|
||||
final headerParam = _dioClient.getHeaders();
|
||||
headerParam[HttpHeaders.authorizationHeader] = authentication;
|
||||
headerParam[HttpHeaders.acceptHeader] = DioClient.jmapHeader;
|
||||
|
||||
final downloadAllUriTemplate = UriTemplate(Uri.decodeFull(baseDownloadAllUrl));
|
||||
final downloadAllUrl = downloadAllUriTemplate.expand({
|
||||
'accountId': accountId.asString,
|
||||
'emailId': emailId.asString,
|
||||
'name': outputFileName,
|
||||
});
|
||||
final downloadFileName = '$outputFileName.zip';
|
||||
|
||||
final bytesDownloaded = await _dioClient.get(
|
||||
downloadAllUrl,
|
||||
options: Options(
|
||||
headers: headerParam,
|
||||
responseType: ResponseType.bytes),
|
||||
onReceiveProgress: (downloaded, total) {
|
||||
log('EmailAPI::downloadFileForWeb(): downloaded = $downloaded | total: $total');
|
||||
double progress = 0;
|
||||
if (downloaded > 0 && total >= downloaded) {
|
||||
progress = (downloaded / total) * 100;
|
||||
}
|
||||
log('EmailAPI::downloadFileForWeb(): progress = ${progress.round()}%');
|
||||
onReceiveController.add(Right(DownloadingAllAttachmentsForWeb(
|
||||
taskId,
|
||||
downloadFileName,
|
||||
progress,
|
||||
downloaded,
|
||||
total > 0 ? total : 0,
|
||||
)));
|
||||
},
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
|
||||
_downloadManager.createAnchorElementDownloadFileWeb(
|
||||
bytesDownloaded,
|
||||
downloadFileName,
|
||||
);
|
||||
}
|
||||
|
||||
Future<DownloadedResponse> exportAllAttachments(
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
String baseDownloadAllUrl,
|
||||
String outputFileName,
|
||||
AccountRequest accountRequest,
|
||||
{CancelToken? cancelToken}
|
||||
) async {
|
||||
final authentication = accountRequest.authenticationType == AuthenticationType.oidc
|
||||
? accountRequest.bearerToken
|
||||
: accountRequest.basicAuth;
|
||||
|
||||
final downloadAllUriTemplate = UriTemplate(Uri.decodeFull(baseDownloadAllUrl));
|
||||
final downloadAllUrl = downloadAllUriTemplate.expand({
|
||||
'accountId': accountId.asString,
|
||||
'emailId': emailId.asString,
|
||||
'name': outputFileName,
|
||||
});
|
||||
final downloadFileName = '$outputFileName.zip';
|
||||
|
||||
return _downloadManager.downloadFile(
|
||||
downloadAllUrl,
|
||||
getTemporaryDirectory(),
|
||||
downloadFileName,
|
||||
authentication,
|
||||
cancelToken: cancelToken);
|
||||
}
|
||||
|
||||
Future<({
|
||||
List<EmailId> emailIdsSuccess,
|
||||
Map<Id, SetError> mapErrors,
|
||||
|
||||
@@ -530,4 +530,41 @@ class EmailRepositoryImpl extends EmailRepository {
|
||||
htmlContent,
|
||||
configuration);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> downloadAllAttachmentsForWeb(
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
String baseDownloadAllUrl,
|
||||
String outputFileName,
|
||||
AccountRequest accountRequest,
|
||||
DownloadTaskId taskId,
|
||||
StreamController<Either<Failure, Success>> onReceiveController,
|
||||
{CancelToken? cancelToken}
|
||||
) => emailDataSource[DataSourceType.network]!.downloadAllAttachmentsForWeb(
|
||||
accountId,
|
||||
emailId,
|
||||
baseDownloadAllUrl,
|
||||
outputFileName,
|
||||
accountRequest,
|
||||
taskId,
|
||||
onReceiveController,
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
|
||||
@override
|
||||
Future<DownloadedResponse> exportAllAttachments(
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
String baseDownloadAllUrl,
|
||||
String outputFileName,
|
||||
AccountRequest accountRequest, {
|
||||
CancelToken? cancelToken,
|
||||
}) => emailDataSource[DataSourceType.network]!.exportAllAttachments(
|
||||
accountId,
|
||||
emailId,
|
||||
baseDownloadAllUrl,
|
||||
outputFileName,
|
||||
accountRequest,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user