Files
workavia-mail-front/lib/features/email/presentation/email_controller.dart
T
2021-09-24 17:50:26 +07:00

268 lines
10 KiB
Dart

import 'package:core/core.dart';
import 'package:core/presentation/views/dialog/downloading_file_dialog_builder.dart';
import 'package:dartz/dartz.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:model/model.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart';
import 'package:tmail_ui_user/features/email/domain/state/download_attachments_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/export_attachment_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/download_attachments_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/export_attachment_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/get_email_content_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:share/share.dart' as share_library;
class EmailController extends BaseController {
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
final responsiveUtils = Get.find<ResponsiveUtils>();
final GetEmailContentInteractor _getEmailContentInteractor;
final MarkAsEmailReadInteractor _markAsEmailReadInteractor;
final DownloadAttachmentsInteractor _downloadAttachmentsInteractor;
final DeviceManager _deviceManager;
final AppToast _appToast;
final ExportAttachmentInteractor _exportAttachmentInteractor;
final emailAddressExpandMode = ExpandMode.COLLAPSE.obs;
final attachmentsExpandMode = ExpandMode.COLLAPSE.obs;
final emailContent = Rxn<EmailContent>();
EmailController(
this._getEmailContentInteractor,
this._markAsEmailReadInteractor,
this._downloadAttachmentsInteractor,
this._deviceManager,
this._appToast,
this._exportAttachmentInteractor,
);
@override
void onReady() {
super.onReady();
mailboxDashBoardController.selectedEmail.listen((presentationEmail) {
_clearEmailContent();
final accountId = mailboxDashBoardController.accountId.value;
if (accountId != null && presentationEmail != null) {
_getEmailContentAction(accountId, presentationEmail.id);
if (presentationEmail.isUnReadEmail()) {
markAsEmailRead(presentationEmail, ReadActions.markAsRead);
}
}
});
}
@override
void onClose() {
mailboxDashBoardController.selectedEmail.close();
super.onClose();
}
void _getEmailContentAction(AccountId accountId, EmailId emailId) async {
consumeState(_getEmailContentInteractor.execute(accountId, emailId));
}
@override
void onData(Either<Failure, Success> newState) {
super.onData(newState);
}
@override
void onDone() {
viewState.value.fold(
(failure) {
if (failure is MarkAsEmailReadFailure) {
_markAsEmailReadFailure(failure);
} else if (failure is DownloadAttachmentsFailure) {
_downloadAttachmentsFailure(failure);
} else if (failure is ExportAttachmentFailure) {
_exportAttachmentFailureAction(failure);
}
},
(success) {
if (success is GetEmailContentSuccess) {
emailContent.value = success.emailContent;
} else if (success is MarkAsEmailReadSuccess) {
_markAsEmailReadSuccess(success);
} else if (success is ExportAttachmentSuccess) {
_exportAttachmentSuccessAction(success);
}
});
}
@override
void onError(error) {
}
void _clearEmailContent() {
toggleDisplayEmailAddressAction(expandMode: ExpandMode.COLLAPSE);
attachmentsExpandMode.value = ExpandMode.COLLAPSE;
emailContent.value = null;
}
void toggleDisplayEmailAddressAction({required ExpandMode expandMode}) {
emailAddressExpandMode.value = expandMode;
}
void markAsEmailRead(PresentationEmail presentationEmail, ReadActions readActions) async {
final accountId = mailboxDashBoardController.accountId.value;
final mailboxCurrent = mailboxDashBoardController.selectedMailbox.value;
if (accountId != null && mailboxCurrent != null) {
consumeState(_markAsEmailReadInteractor.execute(accountId, presentationEmail.id, readActions));
}
}
void _markAsEmailReadSuccess(Success success) {
mailboxDashBoardController.dispatchState(Right(success));
if (success is MarkAsEmailReadSuccess && success.readActions == ReadActions.markAsUnread) {
backToThreadView();
}
}
void _markAsEmailReadFailure(Failure failure) {
backToThreadView();
}
void toggleDisplayAttachmentsAction() {
final newExpandMode = attachmentsExpandMode.value == ExpandMode.COLLAPSE
? ExpandMode.EXPAND
: ExpandMode.COLLAPSE;
attachmentsExpandMode.value = newExpandMode;
}
void downloadAttachments(BuildContext context, List<Attachment> attachments) async {
final needRequestPermission = await _deviceManager.isNeedRequestStoragePermissionOnAndroid();
if (needRequestPermission) {
final status = await Permission.storage.status;
switch (status) {
case PermissionStatus.granted:
_downloadAttachmentsAction(context, attachments);
break;
case PermissionStatus.permanentlyDenied:
_appToast.showToast(AppLocalizations.of(context).you_need_to_grant_files_permission_to_download_attachments);
break;
default: {
final requested = await Permission.storage.request();
switch (requested) {
case PermissionStatus.granted:
_downloadAttachmentsAction(context, attachments);
break;
default:
_appToast.showToast(AppLocalizations.of(context).you_need_to_grant_files_permission_to_download_attachments);
break;
}
}
}
} else {
_downloadAttachmentsAction(context, attachments);
}
}
void _downloadAttachmentsAction(BuildContext context, List<Attachment> attachments) async {
final accountId = mailboxDashBoardController.accountId.value;
if (accountId != null && mailboxDashBoardController.sessionCurrent != null) {
final baseDownloadUrl = mailboxDashBoardController.sessionCurrent!.getDownloadUrl();
consumeState(_downloadAttachmentsInteractor.execute(attachments, accountId, baseDownloadUrl));
}
}
void _downloadAttachmentsFailure(Failure failure) {
if (Get.context != null) {
_appToast.showErrorToast(AppLocalizations.of(Get.context!).attachment_download_failed);
}
}
void exportAttachment(BuildContext context, Attachment attachment) {
final cancelToken = CancelToken();
_showDownloadingFileDialog(context, attachment, cancelToken);
_exportAttachmentAction(attachment, cancelToken);
}
void _showDownloadingFileDialog(BuildContext context, Attachment attachment, CancelToken cancelToken) {
showCupertinoDialog(
context: context,
builder: (_) => (DownloadingFileDialogBuilder()
..key(Key('downloading_file_dialog'))
..title(AppLocalizations.of(context).preparing_to_export)
..content(AppLocalizations.of(context).downloading_file(attachment.name ?? ''))
..actionText(AppLocalizations.of(context).cancel)
..addCancelDownloadActionClick(() {
cancelToken.cancel([AppLocalizations.of(context).user_cancel_download_file]);
popBack();
}))
.build());
}
void _exportAttachmentAction(Attachment attachment, CancelToken cancelToken) async {
final accountId = mailboxDashBoardController.accountId.value;
if (accountId != null && mailboxDashBoardController.sessionCurrent != null) {
final baseDownloadUrl = mailboxDashBoardController.sessionCurrent!.getDownloadUrl();
consumeState(_exportAttachmentInteractor.execute(attachment, accountId, baseDownloadUrl, cancelToken));
}
}
void _exportAttachmentFailureAction(Failure failure) {
if (failure is ExportAttachmentFailure && !(failure.exception is CancelDownloadFileException)) {
popBack();
}
}
void _exportAttachmentSuccessAction(Success success) async {
popBack();
if (success is ExportAttachmentSuccess) {
await share_library.Share.shareFiles([success.filePath]);
}
}
void openDestinationPickerView(PresentationEmail email) {
final currentMailboxId = mailboxDashBoardController.selectedMailbox.value?.id;
final accountId = mailboxDashBoardController.accountId.value;
if (currentMailboxId != null && accountId != null) {
push(
AppRoutes.DESTINATION_PICKER,
arguments: DestinationPickerArguments(accountId, [email.id], currentMailboxId)
);
}
}
bool canComposeEmail() => mailboxDashBoardController.sessionCurrent != null
&& mailboxDashBoardController.userProfile.value != null
&& mailboxDashBoardController.mapMailboxId.containsKey(PresentationMailbox.roleOutbox)
&& mailboxDashBoardController.selectedEmail.value != null;
void backToThreadView() {
popBack();
}
void pressEmailAction(EmailActionType emailActionType) {
if (canComposeEmail()) {
push(
AppRoutes.COMPOSER,
arguments: ComposerArguments(
emailActionType: emailActionType,
presentationEmail: mailboxDashBoardController.selectedEmail.value!,
emailContent: emailContent.value,
session: mailboxDashBoardController.sessionCurrent!,
userProfile: mailboxDashBoardController.userProfile.value!,
mapMailboxId: mailboxDashBoardController.mapMailboxId));
}
}
}