TF-239 Delete single email permanently

This commit is contained in:
dab246
2022-04-05 11:45:50 +07:00
committed by Dat H. Pham
parent 6445e3076f
commit a89c5db744
15 changed files with 171 additions and 20 deletions
@@ -52,5 +52,7 @@ abstract class EmailDataSource {
Future<Email?> updateEmailDrafts(AccountId accountId, Email newEmail, EmailId oldEmailId);
Future<List<EmailId>> deleteMultipleEmailPermanently(Session session, AccountId accountId, List<EmailId> emailIds);
Future<List<EmailId>> deleteMultipleEmailsPermanently(Session session, AccountId accountId, List<EmailId> emailIds);
Future<bool> deleteEmailPermanently(AccountId accountId, EmailId emailId);
}
@@ -135,9 +135,18 @@ class EmailDataSourceImpl extends EmailDataSource {
}
@override
Future<List<EmailId>> deleteMultipleEmailPermanently(Session session, AccountId accountId, List<EmailId> emailIds) {
Future<List<EmailId>> deleteMultipleEmailsPermanently(Session session, AccountId accountId, List<EmailId> emailIds) {
return Future.sync(() async {
return await emailAPI.deleteMultipleEmailPermanently(session, accountId, emailIds);
return await emailAPI.deleteMultipleEmailsPermanently(session, accountId, emailIds);
}).catchError((error) {
throw error;
});
}
@override
Future<bool> deleteEmailPermanently(AccountId accountId, EmailId emailId) {
return Future.sync(() async {
return await emailAPI.deleteEmailPermanently(accountId, emailId);
}).catchError((error) {
throw error;
});
+20 -1
View File
@@ -386,7 +386,7 @@ class EmailAPI {
});
}
Future<List<EmailId>> deleteMultipleEmailPermanently(Session session, AccountId accountId, List<EmailId> emailIds) async {
Future<List<EmailId>> deleteMultipleEmailsPermanently(Session session, AccountId accountId, List<EmailId> emailIds) async {
requireCapability(session, [CapabilityIdentifier.jmapCore, CapabilityIdentifier.jmapMail]);
final coreCapability = (session.capabilities[CapabilityIdentifier.jmapCore] as CoreCapability);
@@ -430,4 +430,23 @@ class EmailAPI {
return listEmailResult;
}
Future<bool> deleteEmailPermanently(AccountId accountId, EmailId emailId) async {
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
final setEmailMethod = SetEmailMethod(accountId)
..addDestroy(Set.of([emailId.id]));
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
final response = await (requestBuilder
..usings(setEmailMethod.requiredCapabilities))
.build()
.execute();
final setEmailResponse = response.parse<SetEmailResponse>(
setEmailInvocation.methodCallId,
SetEmailResponse.deserialize);
return setEmailResponse?.destroyed?.contains(emailId.id) == true;
}
}
@@ -117,7 +117,12 @@ class EmailRepositoryImpl extends EmailRepository {
}
@override
Future<List<EmailId>> deleteMultipleEmailPermanently(Session session, AccountId accountId, List<EmailId> emailIds) {
return emailDataSource.deleteMultipleEmailPermanently(session, accountId, emailIds);
Future<List<EmailId>> deleteMultipleEmailsPermanently(Session session, AccountId accountId, List<EmailId> emailIds) {
return emailDataSource.deleteMultipleEmailsPermanently(session, accountId, emailIds);
}
@override
Future<bool> deleteEmailPermanently(AccountId accountId, EmailId emailId) {
return emailDataSource.deleteEmailPermanently(accountId, emailId);
}
}
@@ -59,5 +59,7 @@ abstract class EmailRepository {
Future<Email?> updateEmailDrafts(AccountId accountId, Email newEmail, EmailId oldEmailId);
Future<List<EmailId>> deleteMultipleEmailPermanently(Session session, AccountId accountId, List<EmailId> emailIds);
Future<List<EmailId>> deleteMultipleEmailsPermanently(Session session, AccountId accountId, List<EmailId> emailIds);
Future<bool> deleteEmailPermanently(AccountId accountId, EmailId emailId);
}
@@ -0,0 +1,19 @@
import 'package:core/core.dart';
class DeleteEmailPermanentlySuccess extends UIState {
DeleteEmailPermanentlySuccess();
@override
List<Object?> get props => [];
}
class DeleteEmailPermanentlyFailure extends FeatureFailure {
final exception;
DeleteEmailPermanentlyFailure(this.exception);
@override
List<Object?> get props => [exception];
}
@@ -0,0 +1,25 @@
import 'package:core/core.dart';
import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_email_permanently_state.dart';
class DeleteEmailPermanentlyInteractor {
final EmailRepository emailRepository;
DeleteEmailPermanentlyInteractor(this.emailRepository);
Stream<Either<Failure, Success>> execute(AccountId accountId, EmailId emailId) async* {
try {
final result = await emailRepository.deleteEmailPermanently(accountId, emailId);
if (result) {
yield Right<Failure, Success>(DeleteEmailPermanentlySuccess());
} else {
yield Left<Failure, Success>(DeleteEmailPermanentlyFailure(null));
}
} catch (e) {
yield Left<Failure, Success>(DeleteEmailPermanentlyFailure(e));
}
}
}
@@ -4,7 +4,7 @@ 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:tmail_ui_user/features/email/domain/repository/email_repository.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_multiple_email_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_multiple_emails_permanently_state.dart';
class DeleteMultipleEmailsPermanentlyInteractor {
final EmailRepository emailRepository;
@@ -13,7 +13,7 @@ class DeleteMultipleEmailsPermanentlyInteractor {
Stream<Either<Failure, Success>> execute(Session session, AccountId accountId, List<EmailId> emailIds) async* {
try {
final listResult = await emailRepository.deleteMultipleEmailPermanently(session, accountId, emailIds);
final listResult = await emailRepository.deleteMultipleEmailsPermanently(session, accountId, emailIds);
if (listResult.length == emailIds.length) {
yield Right<Failure, Success>(DeleteMultipleEmailsPermanentlyAllSuccess(listResult));
} else if (listResult.isNotEmpty) {
@@ -5,6 +5,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.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';
@@ -36,6 +37,7 @@ import 'package:tmail_ui_user/features/email/presentation/widgets/email_address_
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/dashboard_action.dart';
import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.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';
@@ -442,6 +444,9 @@ class EmailController extends BaseController {
case EmailActionType.moveToTrash:
moveToTrashAction(context, presentationEmail);
break;
case EmailActionType.deletePermanently:
deleteEmailPermanently(context, presentationEmail);
break;
default:
break;
}
@@ -513,6 +518,37 @@ class EmailController extends BaseController {
}
}
void deleteEmailPermanently(BuildContext context, PresentationEmail email) {
if (responsiveUtils.isMobile(context)) {
(ConfirmationDialogActionSheetBuilder(context)
..messageText(DeleteActionType.single.getContentDialog(context))
..onCancelAction(AppLocalizations.of(context).cancel, () => popBack())
..onConfirmAction(DeleteActionType.single.getConfirmActionName(context), () => _deleteEmailPermanentlyAction(context, email)))
.show();
} else {
showDialog(
context: context,
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
builder: (BuildContext context) => PointerInterceptor(child: (ConfirmDialogBuilder(imagePaths)
..key(Key('confirm_dialog_delete_email_permanently'))
..title(DeleteActionType.single.getTitleDialog(context))
..content(DeleteActionType.single.getContentDialog(context))
..addIcon(SvgPicture.asset(imagePaths.icRemoveDialog, fit: BoxFit.fill))
..colorConfirmButton(AppColor.colorConfirmActionDialog)
..styleTextConfirmButton(TextStyle(fontSize: 17, fontWeight: FontWeight.w500, color: AppColor.colorActionDeleteConfirmDialog))
..onCloseButtonAction(() => popBack())
..onConfirmButtonAction(DeleteActionType.single.getConfirmActionName(context), () => _deleteEmailPermanentlyAction(context, email))
..onCancelButtonAction(AppLocalizations.of(context).cancel, () => popBack()))
.build()));
}
}
void _deleteEmailPermanentlyAction(BuildContext context, PresentationEmail email) {
popBack();
backToThreadView(context);
mailboxDashBoardController.deleteEmailPermanently(email);
}
void closeMoreMenu() {
popBack();
}
@@ -113,15 +113,18 @@ class AppBarMailWidgetBuilder {
_onEmailActionClick?.call(_presentationEmail!, _presentationEmail!.isFlaggedEmail() ? EmailActionType.markAsUnStar : EmailActionType.markAsStar);
}
}),
if (_currentMailbox?.role != PresentationMailbox.roleTrash)
buildIconWeb(
icon: SvgPicture.asset(_imagePaths.icDeleteEmail, fit: BoxFit.fill),
tooltip: AppLocalizations.of(_context).move_to_trash,
onTap: () {
if (_presentationEmail != null) {
_onEmailActionClick?.call(_presentationEmail!, EmailActionType.moveToTrash);
}
}),
buildIconWeb(
icon: SvgPicture.asset(_imagePaths.icDeleteEmail, fit: BoxFit.fill),
tooltip: _currentMailbox?.role != PresentationMailbox.roleTrash
? AppLocalizations.of(_context).move_to_trash
: AppLocalizations.of(_context).delete_permanently,
onTap: () {
if (_currentMailbox?.role != PresentationMailbox.roleTrash) {
_onEmailActionClick?.call(_presentationEmail!, EmailActionType.moveToTrash);
} else {
_onEmailActionClick?.call(_presentationEmail!, EmailActionType.deletePermanently);
}
}),
Padding(
padding: EdgeInsets.only(left: 10, right: 16),
child: buildIconWebHasPosition(
@@ -16,7 +16,8 @@ import 'package:tmail_ui_user/features/base/base_mailbox_controller.dart';
import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_multiple_email_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_email_permanently_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_multiple_emails_permanently_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/move_to_trash_state.dart';
@@ -134,6 +135,7 @@ class MailboxController extends BaseMailboxController {
} else if (success is MarkAsEmailReadSuccess
|| success is MoveToMailboxSuccess
|| success is MoveToTrashSuccess
|| success is DeleteEmailPermanentlySuccess
|| success is SaveEmailAsDraftsSuccess
|| success is RemoveEmailDraftsSuccess
|| success is SendEmailSuccess
@@ -9,6 +9,7 @@ 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/delete_email_permanently_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/move_to_trash_interactor.dart';
import 'package:tmail_ui_user/features/email/presentation/email_bindings.dart';
@@ -34,6 +35,7 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.put(MailboxDashBoardController(
Get.find<MoveToTrashInteractor>(),
Get.find<MoveToMailboxInteractor>(),
Get.find<DeleteEmailPermanentlyInteractor>(),
));
}
@@ -58,6 +60,7 @@ class MailboxDashBoardBindings extends BaseBindings {
Get.lazyPut(() => RemoveEmailDraftsInteractor(Get.find<EmailRepository>()));
Get.lazyPut(() => MoveToTrashInteractor(Get.find<EmailRepository>()));
Get.lazyPut(() => MoveToMailboxInteractor(Get.find<EmailRepository>()));
Get.lazyPut(() => DeleteEmailPermanentlyInteractor(Get.find<EmailRepository>()));
}
@override
@@ -23,7 +23,9 @@ import 'package:tmail_ui_user/features/composer/presentation/composer_bindings.d
import 'package:tmail_ui_user/features/composer/presentation/composer_controller.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_request.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_to_trash_request.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_email_permanently_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/move_to_trash_state.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/delete_email_permanently_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/move_to_trash_interactor.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
@@ -51,9 +53,11 @@ class MailboxDashBoardController extends ReloadableController {
final DeleteCredentialInteractor _deleteCredentialInteractor = Get.find<DeleteCredentialInteractor>();
final CachingManager _cachingManager = Get.find<CachingManager>();
final Connectivity _connectivity = Get.find<Connectivity>();
final ResponsiveUtils _responsiveUtils = Get.find<ResponsiveUtils>();
final MoveToTrashInteractor _moveToTrashInteractor;
final MoveToMailboxInteractor _moveToMailboxInteractor;
final DeleteEmailPermanentlyInteractor _deleteEmailPermanentlyInteractor;
final scaffoldKey = GlobalKey<ScaffoldState>();
final selectedMailbox = Rxn<PresentationMailbox>();
@@ -77,6 +81,7 @@ class MailboxDashBoardController extends ReloadableController {
MailboxDashBoardController(
this._moveToTrashInteractor,
this._moveToMailboxInteractor,
this._deleteEmailPermanentlyInteractor,
);
@override
@@ -149,6 +154,8 @@ class MailboxDashBoardController extends ReloadableController {
clearState();
} else if (success is MoveToTrashSuccess) {
_moveToTrashSuccess(success);
} else if (success is DeleteEmailPermanentlySuccess) {
_deleteEmailPermanentlySuccess(success);
}
}
);
@@ -310,6 +317,23 @@ class MailboxDashBoardController extends ReloadableController {
}
}
void deleteEmailPermanently(PresentationEmail email) {
final currentAccountId = accountId.value;
if (currentAccountId != null) {
consumeState(_deleteEmailPermanentlyInteractor.execute(currentAccountId, email.id));
}
}
void _deleteEmailPermanentlySuccess(DeleteEmailPermanentlySuccess success) {
if (currentContext != null && currentOverlayContext != null) {
_appToast.showToastWithIcon(
currentOverlayContext!,
widthToast: _responsiveUtils.isDesktop(currentContext!) ? 360 : null,
message: AppLocalizations.of(currentContext!).toast_message_delete_a_email_permanently_success,
icon: _imagePaths.icDeleteToast);
}
}
void dispatchDashBoardAction(DashBoardAction action, {RouterArguments? arguments}) {
switch(action) {
case DashBoardAction.none:
@@ -23,7 +23,8 @@ import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_request.dart';
import 'package:tmail_ui_user/features/email/domain/model/move_to_trash_request.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_multiple_email_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_email_permanently_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/delete_multiple_emails_permanently_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.dart';
@@ -148,6 +149,7 @@ class ThreadController extends BaseController {
|| success is MoveToMailboxSuccess
|| success is MoveToTrashSuccess
|| success is MarkAsStarEmailSuccess
|| success is DeleteEmailPermanentlySuccess
|| success is SaveEmailAsDraftsSuccess
|| success is RemoveEmailDraftsSuccess
|| success is SendEmailSuccess