TF-4128 Separate download handling into independent class to decouple from views on web

This commit is contained in:
dab246
2025-10-28 16:44:40 +07:00
committed by Dat H. Pham
parent 832f8e1391
commit be8eaf6258
37 changed files with 955 additions and 1095 deletions
@@ -1,6 +1,5 @@
import 'dart:async';
import 'package:core/data/network/config/dynamic_url_interceptors.dart';
import 'package:core/domain/extensions/datetime_extension.dart';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
@@ -11,10 +10,8 @@ import 'package:core/presentation/utils/html_transformer/transform_configuration
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/utils/theme_utils.dart';
import 'package:core/presentation/views/bottom_popup/confirmation_dialog_action_sheet_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/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
@@ -23,7 +20,6 @@ import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/download/download_task_id.dart';
import 'package:model/email/email_action_type.dart';
import 'package:model/email/mark_star_action.dart';
import 'package:model/email/presentation_email.dart';
@@ -32,21 +28,17 @@ import 'package:model/extensions/email_address_extension.dart';
import 'package:model/extensions/list_email_address_extension.dart';
import 'package:model/extensions/presentation_email_extension.dart';
import 'package:model/extensions/presentation_mailbox_extension.dart';
import 'package:model/extensions/session_extension.dart';
import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_manager.dart';
import 'package:tmail_ui_user/features/base/widget/context_menu/context_menu_item_action.dart';
import 'package:tmail_ui_user/features/base/widget/popup_menu/popup_menu_item_action_widget.dart';
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart';
import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.dart';
import 'package:tmail_ui_user/features/email/domain/model/email_print.dart';
import 'package:tmail_ui_user/features/email/domain/model/mark_read_action.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';
import 'package:tmail_ui_user/features/email/domain/state/download_attachment_for_web_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/print_email_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/get_email_content_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';
@@ -70,7 +62,6 @@ import 'package:tmail_ui_user/main/routes/navigation_router.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/routes/route_utils.dart';
import 'package:tmail_ui_user/main/utils/app_utils.dart';
import 'package:uuid/uuid.dart';
typedef OpenBottomSheetContextMenuAction = Future<void> Function({
required BuildContext context,
@@ -93,7 +84,6 @@ class EmailActionReactor {
this._createNewEmailRuleFilterInteractor,
this._printEmailInteractor,
this._getEmailContentInteractor,
this._downloadAttachmentForWebInteractor,
);
final MarkAsEmailReadInteractor _markAsEmailReadInteractor;
@@ -101,7 +91,6 @@ class EmailActionReactor {
final CreateNewEmailRuleFilterInteractor? _createNewEmailRuleFilterInteractor;
final PrintEmailInteractor _printEmailInteractor;
final GetEmailContentInteractor _getEmailContentInteractor;
final DownloadAttachmentForWebInteractor _downloadAttachmentForWebInteractor;
static final _isEmailAddressDialogOpened = false.obs;
static bool get isDialogOpened => _isEmailAddressDialogOpened.value;
@@ -429,45 +418,6 @@ class EmailActionReactor {
)
);
}
Stream<Either<Failure, Success>> downloadMessageAsEML(
Session session,
AccountId accountId,
PresentationEmail presentationEmail, {
required StreamController<Either<Failure, Success>> downloadProgressStateController,
}) async* {
final emlAttachment = presentationEmail.createEMLAttachment();
if (emlAttachment.blobId == null) {
yield* Stream.value(Left(DownloadAttachmentForWebFailure(
exception: NotFoundEmailBlobIdException(),
)));
return;
}
final generateTaskId = DownloadTaskId(const Uuid().v4());
try {
final baseDownloadUrl = session.getDownloadUrl(
jmapUrl: getBinding<DynamicUrlInterceptors>()?.jmapUrl,
);
final cancelToken = CancelToken();
yield* _downloadAttachmentForWebInteractor.execute(
generateTaskId,
emlAttachment,
accountId,
baseDownloadUrl,
downloadProgressStateController,
cancelToken: cancelToken,
previewerSupported: false,
);
} catch (e) {
logError('SingleEmailController::downloadAttachmentForWeb(): $e');
yield* Stream.value(Left(DownloadAttachmentForWebFailure(
attachment: emlAttachment,
taskId: generateTaskId,
exception: e,
)));
}
}
void editAsNewEmail(
PresentationEmail presentationEmail, {