TF-3454 Download all attachments as ZIP
This commit is contained in:
@@ -16,8 +16,10 @@ 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/email/data/repository/email_repository_impl.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/download_all_attachments_for_web_interactor.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/usecases/export_all_attachments_interactor.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/get_stored_email_state_interactor.dart';
|
||||
@@ -80,6 +82,8 @@ class EmailBindings extends BaseBindings {
|
||||
Get.find<ParseEmailByBlobIdInteractor>(),
|
||||
Get.find<PreviewEmailFromEmlFileInteractor>(),
|
||||
Get.find<GetHtmlContentFromAttachmentInteractor>(),
|
||||
Get.find<DownloadAllAttachmentsForWebInteractor>(),
|
||||
Get.find<ExportAllAttachmentsInteractor>(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -168,6 +172,16 @@ class EmailBindings extends BaseBindings {
|
||||
Get.lazyPut(() => PreviewEmailFromEmlFileInteractor(Get.find<EmailRepository>()));
|
||||
IdentityInteractorsBindings().dependencies();
|
||||
Get.lazyPut(() => GetHtmlContentFromAttachmentInteractor(Get.find<DownloadAttachmentForWebInteractor>()));
|
||||
Get.lazyPut(() => DownloadAllAttachmentsForWebInteractor(
|
||||
Get.find<EmailRepository>(),
|
||||
Get.find<AccountRepository>(),
|
||||
Get.find<AuthenticationOIDCRepository>(),
|
||||
Get.find<CredentialRepository>()));
|
||||
Get.lazyPut(() => ExportAllAttachmentsInteractor(
|
||||
Get.find<EmailRepository>(),
|
||||
Get.find<AccountRepository>(),
|
||||
Get.find<AuthenticationOIDCRepository>(),
|
||||
Get.find<CredentialRepository>()));
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -13,9 +13,11 @@ import 'package:dartz/dartz.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_file_dialog/flutter_file_dialog.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:flutter_svg/flutter_svg.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/capability/capability_identifier.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/id.dart';
|
||||
@@ -55,8 +57,10 @@ import 'package:tmail_ui_user/features/email/domain/state/calendar_event_accept_
|
||||
import 'package:tmail_ui_user/features/email/domain/state/calendar_event_maybe_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/calendar_event_reject_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/calendar_event_reply_state.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/email/domain/state/download_attachments_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/export_all_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/get_html_content_from_attachment_state.dart';
|
||||
@@ -72,6 +76,8 @@ import 'package:tmail_ui_user/features/email/domain/state/send_receipt_to_sender
|
||||
import 'package:tmail_ui_user/features/email/domain/state/store_event_attendance_status_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/state/unsubscribe_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/calendar_event_accept_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/download_all_attachments_for_web_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/export_all_attachments_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/maybe_calendar_event_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/email/domain/usecases/calendar_event_reject_interactor.dart';
|
||||
@@ -109,6 +115,7 @@ import 'package:tmail_ui_user/features/email/presentation/widgets/html_attachmen
|
||||
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/home/domain/extensions/session_extensions.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/action/mailbox_ui_action.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
|
||||
@@ -157,6 +164,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
final ParseEmailByBlobIdInteractor _parseEmailByBlobIdInteractor;
|
||||
final PreviewEmailFromEmlFileInteractor _previewEmailFromEmlFileInteractor;
|
||||
final GetHtmlContentFromAttachmentInteractor _getHtmlContentFromAttachmentInteractor;
|
||||
final DownloadAllAttachmentsForWebInteractor _downloadAllAttachmentsForWebInteractor;
|
||||
final ExportAllAttachmentsInteractor _exportAllAttachmentsInteractor;
|
||||
|
||||
CreateNewEmailRuleFilterInteractor? _createNewEmailRuleFilterInteractor;
|
||||
SendReceiptToSenderInteractor? _sendReceiptToSenderInteractor;
|
||||
@@ -213,6 +222,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
this._parseEmailByBlobIdInteractor,
|
||||
this._previewEmailFromEmlFileInteractor,
|
||||
this._getHtmlContentFromAttachmentInteractor,
|
||||
this._downloadAllAttachmentsForWebInteractor,
|
||||
this._exportAllAttachmentsInteractor,
|
||||
);
|
||||
|
||||
@override
|
||||
@@ -240,6 +251,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
_handleMarkAsEmailReadCompleted(success.readActions);
|
||||
} else if (success is ExportAttachmentSuccess) {
|
||||
_exportAttachmentSuccessAction(success);
|
||||
} else if (success is ExportAllAttachmentsSuccess) {
|
||||
_exportAllAttachmentsSuccessAction(success);
|
||||
} else if (success is MoveToMailboxSuccess) {
|
||||
_moveToMailboxSuccess(success);
|
||||
} else if (success is MarkAsStarEmailSuccess) {
|
||||
@@ -250,6 +263,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
_updateAttachmentsViewState(success.attachment.blobId, Right(success));
|
||||
} else if (success is DownloadingAttachmentForWeb) {
|
||||
_updateAttachmentsViewState(success.attachment.blobId, Right(success));
|
||||
} else if (success is DownloadAllAttachmentsForWebSuccess) {
|
||||
mailboxDashBoardController.deleteDownloadTask(success.taskId);
|
||||
} else if (success is GetAllIdentitiesSuccess) {
|
||||
_getAllIdentitiesSuccess(success);
|
||||
} else if (success is SendReceiptToSenderSuccess) {
|
||||
@@ -298,8 +313,12 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
_downloadAttachmentsFailure(failure);
|
||||
} else if (failure is ExportAttachmentFailure) {
|
||||
_exportAttachmentFailureAction(failure);
|
||||
} else if (failure is ExportAllAttachmentsFailure) {
|
||||
_exportAllAttachmentsFailureAction(failure);
|
||||
} else if (failure is DownloadAttachmentForWebFailure) {
|
||||
_downloadAttachmentForWebFailureAction(failure);
|
||||
} else if (failure is DownloadAllAttachmentsForWebFailure) {
|
||||
_downloadAllAttachmentsForWebFailure(failure);
|
||||
} else if (failure is ParseCalendarEventFailure) {
|
||||
_handleParseCalendarEventFailure(failure);
|
||||
} else if (failure is GetEmailContentFailure) {
|
||||
@@ -445,15 +464,44 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
log('SingleEmailController::DownloadingAttachmentForWeb(): $percent%');
|
||||
|
||||
emailSupervisorController.mailboxDashBoardController.updateDownloadTask(
|
||||
success.taskId,
|
||||
(currentTask) {
|
||||
final newTask = currentTask.copyWith(
|
||||
progress: success.progress,
|
||||
downloaded: success.downloaded,
|
||||
total: success.total);
|
||||
success.taskId,
|
||||
(currentTask) {
|
||||
final newTask = currentTask.copyWith(
|
||||
progress: success.progress,
|
||||
downloaded: success.downloaded,
|
||||
total: success.total);
|
||||
|
||||
return newTask;
|
||||
});
|
||||
return newTask;
|
||||
});
|
||||
} else if (success is StartDownloadAllAttachmentsForWeb) {
|
||||
emailSupervisorController.mailboxDashBoardController.addDownloadTask(
|
||||
DownloadTaskState(
|
||||
taskId: success.taskId,
|
||||
attachment: success.attachment,
|
||||
),
|
||||
);
|
||||
|
||||
if (currentOverlayContext != null && currentContext != null) {
|
||||
appToast.showToastMessage(
|
||||
currentOverlayContext!,
|
||||
AppLocalizations.of(currentContext!).your_download_has_started,
|
||||
leadingSVGIconColor: AppColor.primaryColor,
|
||||
leadingSVGIcon: imagePaths.icDownload);
|
||||
}
|
||||
} else if (success is DownloadingAllAttachmentsForWeb) {
|
||||
final percent = success.progress.round();
|
||||
log('SingleEmailController::DownloadingAttachmentForWeb(): $percent%');
|
||||
|
||||
emailSupervisorController.mailboxDashBoardController.updateDownloadTask(
|
||||
success.taskId,
|
||||
(currentTask) {
|
||||
final newTask = currentTask.copyWith(
|
||||
progress: success.progress,
|
||||
downloaded: success.downloaded,
|
||||
total: success.total);
|
||||
|
||||
return newTask;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -804,11 +852,11 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
|
||||
void exportAttachment(BuildContext context, Attachment attachment) {
|
||||
final cancelToken = CancelToken();
|
||||
_showDownloadingFileDialog(context, attachment, cancelToken: cancelToken);
|
||||
_showDownloadingFileDialog(context, attachment.name ?? '', cancelToken: cancelToken);
|
||||
_exportAttachmentAction(attachment, cancelToken);
|
||||
}
|
||||
|
||||
void _showDownloadingFileDialog(BuildContext context, Attachment attachment, {CancelToken? cancelToken}) {
|
||||
void _showDownloadingFileDialog(BuildContext context, String attachmentName, {CancelToken? cancelToken}) {
|
||||
if (cancelToken != null) {
|
||||
showCupertinoDialog(
|
||||
context: context,
|
||||
@@ -816,7 +864,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
PointerInterceptor(child: (DownloadingFileDialogBuilder()
|
||||
..key(const Key('downloading_file_dialog'))
|
||||
..title(AppLocalizations.of(context).preparing_to_export)
|
||||
..content(AppLocalizations.of(context).downloading_file(attachment.name ?? ''))
|
||||
..content(AppLocalizations.of(context).downloading_file(attachmentName))
|
||||
..actionText(AppLocalizations.of(context).cancel)
|
||||
..addCancelDownloadActionClick(() {
|
||||
cancelToken.cancel([AppLocalizations.of(context).user_cancel_download_file]);
|
||||
@@ -830,7 +878,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
PointerInterceptor(child: (DownloadingFileDialogBuilder()
|
||||
..key(const Key('downloading_file_for_web_dialog'))
|
||||
..title(AppLocalizations.of(context).preparing_to_save)
|
||||
..content(AppLocalizations.of(context).downloading_file(attachment.name ?? '')))
|
||||
..content(AppLocalizations.of(context).downloading_file(attachmentName)))
|
||||
.build()));
|
||||
}
|
||||
}
|
||||
@@ -854,6 +902,36 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
}
|
||||
}
|
||||
|
||||
void exportAllAttachments(BuildContext context, String outputFileName) {
|
||||
final cancelToken = CancelToken();
|
||||
_showDownloadingFileDialog(context, outputFileName, cancelToken: cancelToken);
|
||||
_exportAllAttachmentsAction(outputFileName, cancelToken);
|
||||
}
|
||||
|
||||
void _exportAllAttachmentsAction(String outputFileName, CancelToken cancelToken) {
|
||||
if (accountId == null || session == null) {
|
||||
consumeState(Stream.value(Left(ExportAllAttachmentsFailure(
|
||||
exception: NotFoundSessionException(),
|
||||
))));
|
||||
return;
|
||||
}
|
||||
|
||||
final downloadAllSupported = session!.isDownloadAllSupported(accountId);
|
||||
if (!downloadAllSupported || _currentEmailId == null) {
|
||||
consumeState(Stream.value(Left(ExportAllAttachmentsFailure())));
|
||||
return;
|
||||
}
|
||||
|
||||
final baseDownloadAllUrl = session!.getDownloadAllCapability(accountId)!.endpoint!;
|
||||
consumeState(_exportAllAttachmentsInteractor.execute(
|
||||
accountId!,
|
||||
_currentEmailId!,
|
||||
baseDownloadAllUrl,
|
||||
outputFileName,
|
||||
cancelToken: cancelToken,
|
||||
));
|
||||
}
|
||||
|
||||
void _exportAttachmentFailureAction(ExportAttachmentFailure failure) {
|
||||
if (failure.exception is! CancelDownloadFileException) {
|
||||
popBack();
|
||||
@@ -871,6 +949,23 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
_openDownloadedPreviewWorkGroupDocument(success.downloadedResponse);
|
||||
}
|
||||
|
||||
void _exportAllAttachmentsFailureAction(ExportAllAttachmentsFailure failure) {
|
||||
if (failure.exception is! CancelDownloadFileException) {
|
||||
popBack();
|
||||
|
||||
if (currentOverlayContext != null && currentContext != null) {
|
||||
appToast.showToastErrorMessage(
|
||||
currentOverlayContext!,
|
||||
AppLocalizations.of(currentContext!).attachment_download_failed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _exportAllAttachmentsSuccessAction(ExportAllAttachmentsSuccess success) {
|
||||
popBack();
|
||||
_saveDownloadedZipAttachments(success.downloadedResponse.filePath);
|
||||
}
|
||||
|
||||
void _openDownloadedPreviewWorkGroupDocument(DownloadedResponse downloadedResponse) async {
|
||||
log('SingleEmailController::_openDownloadedPreviewWorkGroupDocument(): $downloadedResponse');
|
||||
if (downloadedResponse.mediaType == null) {
|
||||
@@ -892,6 +987,11 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _saveDownloadedZipAttachments(String filePath) async {
|
||||
final params = SaveFileDialogParams(sourceFilePath: filePath);
|
||||
await FlutterFileDialog.saveFile(params: params);
|
||||
}
|
||||
|
||||
void downloadAttachmentForWeb(Attachment attachment) {
|
||||
if (accountId != null && session != null) {
|
||||
final generateTaskId = DownloadTaskId(uuid.v4());
|
||||
@@ -921,6 +1021,65 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
}
|
||||
}
|
||||
|
||||
void downloadAllAttachmentsForWeb(String outputFileName) {
|
||||
final taskId = DownloadTaskId(uuid.v4());
|
||||
final session = this.session;
|
||||
final accountId = this.accountId;
|
||||
|
||||
if (accountId == null || session == null) {
|
||||
consumeState(Stream.value(Left(DownloadAllAttachmentsForWebFailure(
|
||||
exception: NotFoundSessionException(),
|
||||
taskId: taskId,
|
||||
))));
|
||||
return;
|
||||
}
|
||||
|
||||
final downloadAllSupported = session.isDownloadAllSupported(accountId);
|
||||
final emailId = _currentEmailId;
|
||||
|
||||
if (!downloadAllSupported || emailId == null) {
|
||||
consumeState(Stream.value(Left(DownloadAllAttachmentsForWebFailure(
|
||||
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,
|
||||
_downloadProgressStateController,
|
||||
cancelToken: cancelToken,
|
||||
));
|
||||
}
|
||||
|
||||
bool isDownloadAllSupported() {
|
||||
return session?.isDownloadAllSupported(accountId) ?? false;
|
||||
}
|
||||
|
||||
bool downloadAllButtonIsEnabled() {
|
||||
return isDownloadAllSupported() && attachments.length > 1;
|
||||
}
|
||||
|
||||
void _downloadAllAttachmentsForWebFailure(
|
||||
DownloadAllAttachmentsForWebFailure failure,
|
||||
) {
|
||||
mailboxDashBoardController.deleteDownloadTask(failure.taskId);
|
||||
if (currentOverlayContext != null && currentContext != null) {
|
||||
appToast.showToastErrorMessage(
|
||||
currentOverlayContext!,
|
||||
AppLocalizations.of(currentContext!).attachment_download_failed);
|
||||
}
|
||||
}
|
||||
|
||||
void _downloadAttachmentForWebSuccessAction(DownloadAttachmentForWebSuccess success) {
|
||||
log('SingleEmailController::_downloadAttachmentForWebSuccessAction():');
|
||||
|
||||
@@ -1675,6 +1834,10 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
..onCloseButtonAction(() => popBack())
|
||||
..onDownloadAttachmentFileAction((attachment) => handleDownloadAttachmentAction(context, attachment))
|
||||
..onViewAttachmentFileAction((attachment) => handleViewAttachmentAction(context, attachment))
|
||||
..onDownloadAllButtonAction(isDownloadAllSupported()
|
||||
? () => downloadAllAttachmentsForWeb('TwakeMail-${DateTime.now()}')
|
||||
: null
|
||||
)
|
||||
).show();
|
||||
} else {
|
||||
Get.dialog(
|
||||
@@ -1688,6 +1851,9 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
onCloseButtonAction: () => popBack(),
|
||||
onDownloadAttachmentFileAction: (attachment) => handleDownloadAttachmentAction(context, attachment),
|
||||
onViewAttachmentFileAction: (attachment) => handleViewAttachmentAction(context, attachment),
|
||||
onDownloadAllButtonAction: isDownloadAllSupported()
|
||||
? () => downloadAllAttachmentsForWeb('TwakeMail-${DateTime.now()}')
|
||||
: null,
|
||||
)
|
||||
),
|
||||
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
|
||||
@@ -1995,6 +2161,19 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
|
||||
}
|
||||
}
|
||||
|
||||
void handleDownloadAllAttachmentsAction(
|
||||
BuildContext context,
|
||||
String outputFileName,
|
||||
) {
|
||||
if (PlatformInfo.isWeb) {
|
||||
downloadAllAttachmentsForWeb(outputFileName);
|
||||
} else if (PlatformInfo.isMobile) {
|
||||
exportAllAttachments(context, outputFileName);
|
||||
} else {
|
||||
log('EmailView::handleDownloadAllAttachmentsAction: THE PLATFORM IS SUPPORTED');
|
||||
}
|
||||
}
|
||||
|
||||
void handleViewAttachmentAction(BuildContext context, Attachment attachment) {
|
||||
if (PlatformInfo.isWeb && PlatformInfo.isCanvasKit && attachment.isPDFFile) {
|
||||
previewPDFFileAction(context, attachment);
|
||||
|
||||
@@ -339,6 +339,8 @@ class EmailView extends GetWidget<SingleEmailController> {
|
||||
downloadAttachmentAction: (attachment) => controller.handleDownloadAttachmentAction(context, attachment),
|
||||
viewAttachmentAction: (attachment) => controller.handleViewAttachmentAction(context, attachment),
|
||||
onTapShowAllAttachmentFile: () => controller.openAttachmentList(context, controller.attachments),
|
||||
showDownloadAllAttachmentsButton: controller.downloadAllButtonIsEnabled(),
|
||||
onTapDownloadAllButton: () => controller.handleDownloadAllAttachmentsAction(context, 'TwakeMail-${DateTime.now()}'),
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
|
||||
@@ -42,9 +42,9 @@ class AttachmentListStyles {
|
||||
static const Color scrollbarThumbColor = AppColor.colorScrollbarThumbColor;
|
||||
static const Color scrollbarTrackBorderColor = Colors.transparent;
|
||||
static const Color separatorColor = AppColor.colorAttachmentBorder;
|
||||
static const Color downloadAllButtonColor = AppColor.primaryColor;
|
||||
static const Color downloadAllButtonColor = Colors.transparent;
|
||||
static const Color cancelButtonColor = Colors.transparent;
|
||||
static const Color downloadAllButtonTextColor = Colors.white;
|
||||
static const Color downloadAllButtonTextColor = AppColor.textButtonColor;
|
||||
static const Color cancelButtonTextColor = AppColor.primaryColor;
|
||||
static const Color cancelButtonBorderColor = AppColor.colorButtonBorder;
|
||||
static const Color barrierColor = AppColor.colorDefaultCupertinoActionSheet;
|
||||
|
||||
@@ -5,16 +5,16 @@ import 'package:flutter/material.dart';
|
||||
class EmailAttachmentsStyles {
|
||||
static const double headerTextSize = 15;
|
||||
static const double headerIconSize = 20;
|
||||
static const double headerSpace = 4;
|
||||
static const double headerSpace = 8;
|
||||
static const double marginHeader = 6;
|
||||
static const double buttonTextSize = 13;
|
||||
static const double buttonTextSize = 16;
|
||||
static const double buttonMoreAttachmentsTextSize = 14;
|
||||
static const double buttonBorderRadius = 8;
|
||||
static const double listSpace = 8;
|
||||
|
||||
static const Color headerTextColor = AppColor.colorTitleHeaderAttachment;
|
||||
static const Color headerIconColor = AppColor.colorAttachmentIcon;
|
||||
static const Color buttonTextColor = AppColor.primaryColor;
|
||||
static const Color buttonTextColor = AppColor.colorTextBody;
|
||||
static const Color buttonMoreAttachmentsTextColor = AppColor.colorLabelMoreAttachmentsButton;
|
||||
|
||||
static const FontWeight headerFontWeight = FontWeight.w400;
|
||||
@@ -24,4 +24,5 @@ class EmailAttachmentsStyles {
|
||||
static const EdgeInsetsGeometry padding = EdgeInsetsDirectional.only(start: 16, end: 16, bottom: 12);
|
||||
static const EdgeInsetsGeometry buttonPadding = EdgeInsets.symmetric(vertical: 8, horizontal: 12);
|
||||
static const EdgeInsetsGeometry moreButtonMargin = EdgeInsetsDirectional.only(bottom: 2, start: 8);
|
||||
static const attachmentsInfoPadding = EdgeInsetsDirectional.only(end: 8);
|
||||
}
|
||||
+9
-23
@@ -1,11 +1,10 @@
|
||||
import 'package:core/presentation/views/button/icon_button_web.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/styles/attachment/attachment_list_styles.dart';
|
||||
|
||||
class AttachmentListActionButtonBuilder extends StatelessWidget {
|
||||
final String? name;
|
||||
final TextStyle? textStyle;
|
||||
final Color? bgColor;
|
||||
final Color? borderColor;
|
||||
final Function? action;
|
||||
|
||||
const AttachmentListActionButtonBuilder({
|
||||
@@ -13,32 +12,19 @@ class AttachmentListActionButtonBuilder extends StatelessWidget {
|
||||
this.name,
|
||||
this.textStyle,
|
||||
this.bgColor,
|
||||
this.borderColor,
|
||||
this.action
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: () => action?.call(),
|
||||
child: Container(
|
||||
padding: AttachmentListStyles.buttonsPadding,
|
||||
decoration: BoxDecoration(
|
||||
color: bgColor,
|
||||
borderRadius: AttachmentListStyles.buttonRadius,
|
||||
border: Border.all(
|
||||
width: borderColor != null ? AttachmentListStyles.buttonBorderWidth : 0,
|
||||
color: borderColor ?? Colors.transparent
|
||||
)
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
name ?? '',
|
||||
textAlign: TextAlign.center,
|
||||
style: textStyle
|
||||
),
|
||||
),
|
||||
),
|
||||
return buildButtonWrapText(
|
||||
name ?? '',
|
||||
radius: 10,
|
||||
height: 44,
|
||||
textStyle: textStyle,
|
||||
bgColor: bgColor,
|
||||
onTap: () => action?.call(),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-4
@@ -1,3 +1,4 @@
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -118,13 +119,16 @@ class AttachmentListBottomSheetBodyBuilder extends StatelessWidget {
|
||||
Padding(
|
||||
padding: AttachmentListStyles.actionButtonsRowPadding,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
if (onDownloadAllButtonAction != null)
|
||||
AttachmentListActionButtonBuilder(
|
||||
name: AppLocalizations.of(context).downloadAll,
|
||||
bgColor: AttachmentListStyles.downloadAllButtonColor,
|
||||
textStyle: AttachmentListStyles.downloadAllButtonTextStyle
|
||||
bgColor: AppColor.primaryColor,
|
||||
textStyle: AttachmentListStyles.downloadAllButtonTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
action: onDownloadAllButtonAction,
|
||||
),
|
||||
if (onDownloadAllButtonAction != null && onCancelButtonAction != null)
|
||||
const SizedBox(width: AttachmentListStyles.buttonsSpaceBetween),
|
||||
@@ -132,7 +136,6 @@ class AttachmentListBottomSheetBodyBuilder extends StatelessWidget {
|
||||
AttachmentListActionButtonBuilder(
|
||||
name: AppLocalizations.of(context).close,
|
||||
bgColor: AttachmentListStyles.cancelButtonColor,
|
||||
borderColor: AttachmentListStyles.cancelButtonBorderColor,
|
||||
textStyle: AttachmentListStyles.cancelButtonTextStyle
|
||||
)
|
||||
],
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ class AttachmentListBottomSheetBuilder {
|
||||
_statusBarHeight = Get.statusBarHeight / MediaQuery.of(_context).devicePixelRatio;
|
||||
}
|
||||
|
||||
void onDownloadAllButtonAction(OnDownloadAllButtonAction onDownloadAllButtonAction) {
|
||||
void onDownloadAllButtonAction(OnDownloadAllButtonAction? onDownloadAllButtonAction) {
|
||||
_onDownloadAllButtonAction = onDownloadAllButtonAction;
|
||||
}
|
||||
|
||||
|
||||
+7
-4
@@ -1,3 +1,4 @@
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -124,13 +125,16 @@ class AttachmentListDialogBodyBuilder extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
if (onDownloadAllButtonAction != null)
|
||||
AttachmentListActionButtonBuilder(
|
||||
name: AppLocalizations.of(context).downloadAll,
|
||||
bgColor: AttachmentListStyles.downloadAllButtonColor,
|
||||
textStyle: AttachmentListStyles.downloadAllButtonTextStyle
|
||||
bgColor: AppColor.primaryColor,
|
||||
textStyle: AttachmentListStyles.downloadAllButtonTextStyle.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
action: onDownloadAllButtonAction,
|
||||
),
|
||||
if (onDownloadAllButtonAction != null && onCancelButtonAction != null)
|
||||
const SizedBox(width: AttachmentListStyles.buttonsSpaceBetween),
|
||||
@@ -138,7 +142,6 @@ class AttachmentListDialogBodyBuilder extends StatelessWidget {
|
||||
AttachmentListActionButtonBuilder(
|
||||
name: AppLocalizations.of(context).close,
|
||||
bgColor: AttachmentListStyles.cancelButtonColor,
|
||||
borderColor: AttachmentListStyles.cancelButtonBorderColor,
|
||||
textStyle: AttachmentListStyles.cancelButtonTextStyle
|
||||
)
|
||||
],
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/utils/responsive_utils.dart';
|
||||
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/styles/email_attachments_styles.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
class AttachmentsInfo extends StatelessWidget {
|
||||
const AttachmentsInfo({
|
||||
super.key,
|
||||
required this.imagePaths,
|
||||
required this.numberOfAttachments,
|
||||
required this.totalSizeInfo,
|
||||
required this.responsiveUtils,
|
||||
this.onTapShowAllAttachmentFile,
|
||||
this.downloadAllEnabled = false,
|
||||
this.onTapDownloadAllButton,
|
||||
});
|
||||
|
||||
final ImagePaths imagePaths;
|
||||
final int numberOfAttachments;
|
||||
final String totalSizeInfo;
|
||||
final ResponsiveUtils responsiveUtils;
|
||||
final VoidCallback? onTapShowAllAttachmentFile;
|
||||
final bool downloadAllEnabled;
|
||||
final VoidCallback? onTapDownloadAllButton;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<Widget> attachmentsAmountAndSize = [
|
||||
SvgPicture.asset(
|
||||
imagePaths.icAttachment,
|
||||
width: EmailAttachmentsStyles.headerIconSize,
|
||||
height: EmailAttachmentsStyles.headerIconSize,
|
||||
colorFilter: EmailAttachmentsStyles.headerIconColor.asFilter(),
|
||||
fit: BoxFit.fill
|
||||
),
|
||||
const SizedBox(width: EmailAttachmentsStyles.headerSpace),
|
||||
Text(
|
||||
AppLocalizations.of(context).titleHeaderAttachment(
|
||||
numberOfAttachments,
|
||||
totalSizeInfo,
|
||||
),
|
||||
style: const TextStyle(
|
||||
fontSize: EmailAttachmentsStyles.headerTextSize,
|
||||
fontWeight: EmailAttachmentsStyles.headerFontWeight,
|
||||
color: EmailAttachmentsStyles.headerTextColor
|
||||
)
|
||||
),
|
||||
];
|
||||
|
||||
final showAllAttachments = (numberOfAttachments > 2)
|
||||
? TMailButtonWidget(
|
||||
text: AppLocalizations.of(context).showAll,
|
||||
backgroundColor: Colors.transparent,
|
||||
borderRadius: EmailAttachmentsStyles.buttonBorderRadius,
|
||||
padding: EmailAttachmentsStyles.buttonPadding,
|
||||
textStyle: const TextStyle(
|
||||
fontSize: EmailAttachmentsStyles.buttonTextSize,
|
||||
color: EmailAttachmentsStyles.buttonTextColor,
|
||||
fontWeight: EmailAttachmentsStyles.buttonFontWeight
|
||||
),
|
||||
onTapActionCallback: onTapShowAllAttachmentFile,
|
||||
)
|
||||
: const SizedBox.shrink();
|
||||
|
||||
List<Widget> downloadAllAttachments = downloadAllEnabled && !responsiveUtils.isMobile(context)
|
||||
? [
|
||||
const Spacer(),
|
||||
TMailButtonWidget(
|
||||
text: AppLocalizations.of(context).downloadAll,
|
||||
icon: imagePaths.icDownloadAll,
|
||||
iconAlignment: TextDirection.rtl,
|
||||
backgroundColor: Colors.transparent,
|
||||
borderRadius: EmailAttachmentsStyles.buttonBorderRadius,
|
||||
padding: EmailAttachmentsStyles.buttonPadding,
|
||||
textStyle: const TextStyle(
|
||||
fontSize: EmailAttachmentsStyles.buttonTextSize,
|
||||
color: EmailAttachmentsStyles.buttonTextColor,
|
||||
fontWeight: EmailAttachmentsStyles.buttonFontWeight
|
||||
),
|
||||
onTapActionCallback: onTapDownloadAllButton,
|
||||
),
|
||||
]
|
||||
: const [];
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
...attachmentsAmountAndSize,
|
||||
if (!PlatformInfo.isWeb) const Spacer(),
|
||||
showAllAttachments,
|
||||
...downloadAllAttachments,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,15 @@
|
||||
import 'package:core/presentation/action/action_callback_define.dart';
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/utils/responsive_utils.dart';
|
||||
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:filesize/filesize.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:model/email/attachment.dart';
|
||||
import 'package:model/extensions/list_attachment_extension.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/styles/email_attachments_styles.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_item_widget.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/widgets/attachments_info.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/widgets/draggable_attachment_item_widget.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
|
||||
@@ -24,6 +23,8 @@ class EmailAttachmentsWidget extends StatelessWidget {
|
||||
final ResponsiveUtils responsiveUtils;
|
||||
final ImagePaths imagePaths;
|
||||
final OnTapActionCallback? onTapShowAllAttachmentFile;
|
||||
final bool showDownloadAllAttachmentsButton;
|
||||
final OnTapActionCallback? onTapDownloadAllButton;
|
||||
|
||||
const EmailAttachmentsWidget({
|
||||
super.key,
|
||||
@@ -35,6 +36,8 @@ class EmailAttachmentsWidget extends StatelessWidget {
|
||||
this.downloadAttachmentAction,
|
||||
this.viewAttachmentAction,
|
||||
this.onTapShowAllAttachmentFile,
|
||||
this.showDownloadAllAttachmentsButton = false,
|
||||
this.onTapDownloadAllButton,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -46,51 +49,14 @@ class EmailAttachmentsWidget extends StatelessWidget {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(width: EmailAttachmentsStyles.headerSpace),
|
||||
SvgPicture.asset(
|
||||
imagePaths.icAttachment,
|
||||
width: EmailAttachmentsStyles.headerIconSize,
|
||||
height: EmailAttachmentsStyles.headerIconSize,
|
||||
colorFilter: EmailAttachmentsStyles.headerIconColor.asFilter(),
|
||||
fit: BoxFit.fill
|
||||
),
|
||||
const SizedBox(width: EmailAttachmentsStyles.headerSpace),
|
||||
Expanded(
|
||||
child: Text(
|
||||
AppLocalizations.of(context).titleHeaderAttachment(
|
||||
attachments.length,
|
||||
filesize(attachments.totalSize, 1)
|
||||
),
|
||||
style: const TextStyle(
|
||||
fontSize: EmailAttachmentsStyles.headerTextSize,
|
||||
fontWeight: EmailAttachmentsStyles.headerFontWeight,
|
||||
color: EmailAttachmentsStyles.headerTextColor
|
||||
)
|
||||
)
|
||||
),
|
||||
const SizedBox(width: EmailAttachmentsStyles.headerSpace),
|
||||
]
|
||||
)
|
||||
),
|
||||
if (attachments.length > 2)
|
||||
TMailButtonWidget(
|
||||
text: AppLocalizations.of(context).showAll,
|
||||
backgroundColor: Colors.transparent,
|
||||
borderRadius: EmailAttachmentsStyles.buttonBorderRadius,
|
||||
padding: EmailAttachmentsStyles.buttonPadding,
|
||||
textStyle: const TextStyle(
|
||||
fontSize: EmailAttachmentsStyles.buttonTextSize,
|
||||
color: EmailAttachmentsStyles.buttonTextColor,
|
||||
fontWeight: EmailAttachmentsStyles.buttonFontWeight
|
||||
),
|
||||
onTapActionCallback: onTapShowAllAttachmentFile,
|
||||
)
|
||||
],
|
||||
AttachmentsInfo(
|
||||
imagePaths: imagePaths,
|
||||
numberOfAttachments: attachments.length,
|
||||
totalSizeInfo: filesize(attachments.totalSize, 1),
|
||||
responsiveUtils: responsiveUtils,
|
||||
onTapShowAllAttachmentFile: onTapShowAllAttachmentFile,
|
||||
downloadAllEnabled: showDownloadAllAttachmentsButton,
|
||||
onTapDownloadAllButton: onTapDownloadAllButton,
|
||||
),
|
||||
const SizedBox(height: EmailAttachmentsStyles.marginHeader),
|
||||
Row(
|
||||
@@ -121,7 +87,7 @@ class EmailAttachmentsWidget extends StatelessWidget {
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
if (hideItemsCount > 0)
|
||||
if (hideItemsCount > 0 && !responsiveUtils.isMobile(context))
|
||||
TMailButtonWidget(
|
||||
text: AppLocalizations.of(context).moreAttachments(hideItemsCount),
|
||||
backgroundColor: Colors.transparent,
|
||||
@@ -137,6 +103,42 @@ class EmailAttachmentsWidget extends StatelessWidget {
|
||||
),
|
||||
]
|
||||
),
|
||||
const SizedBox(height: EmailAttachmentsStyles.marginHeader),
|
||||
if (responsiveUtils.isMobile(context))
|
||||
Row(
|
||||
children: [
|
||||
if (hideItemsCount > 0)
|
||||
TMailButtonWidget(
|
||||
text: AppLocalizations.of(context).moreAttachments(hideItemsCount),
|
||||
backgroundColor: Colors.transparent,
|
||||
borderRadius: EmailAttachmentsStyles.buttonBorderRadius,
|
||||
padding: EdgeInsets.zero,
|
||||
margin: EmailAttachmentsStyles.moreButtonMargin,
|
||||
textStyle: const TextStyle(
|
||||
fontSize: EmailAttachmentsStyles.buttonMoreAttachmentsTextSize,
|
||||
color: EmailAttachmentsStyles.buttonMoreAttachmentsTextColor,
|
||||
fontWeight: EmailAttachmentsStyles.buttonMoreAttachmentsFontWeight,
|
||||
),
|
||||
onTapActionCallback: onTapShowAllAttachmentFile,
|
||||
),
|
||||
const Spacer(),
|
||||
if (showDownloadAllAttachmentsButton)
|
||||
TMailButtonWidget(
|
||||
text: AppLocalizations.of(context).downloadAll,
|
||||
icon: imagePaths.icDownloadAll,
|
||||
iconAlignment: TextDirection.rtl,
|
||||
backgroundColor: Colors.transparent,
|
||||
borderRadius: EmailAttachmentsStyles.buttonBorderRadius,
|
||||
padding: EmailAttachmentsStyles.buttonPadding,
|
||||
textStyle: const TextStyle(
|
||||
fontSize: EmailAttachmentsStyles.buttonTextSize,
|
||||
color: EmailAttachmentsStyles.buttonTextColor,
|
||||
fontWeight: EmailAttachmentsStyles.buttonFontWeight
|
||||
),
|
||||
onTapActionCallback: onTapDownloadAllButton,
|
||||
),
|
||||
]
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user