TF-239 Delete single email permanently
This commit is contained in:
@@ -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;
|
||||
});
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user