TF-82 Discard email drafts

This commit is contained in:
dab246
2022-02-21 13:55:19 +07:00
committed by Dat H. Pham
parent ea29405f08
commit a2ffd9b354
14 changed files with 186 additions and 27 deletions
@@ -12,11 +12,11 @@ class SaveEmailAsDraftsInteractor {
Stream<Either<Failure, Success>> execute(AccountId accountId, Email email) async* {
try {
final result = await emailRepository.saveEmailAsDrafts(accountId, email);
if (result) {
yield Right<Failure, Success>(SaveEmailAsDraftsSuccess(email));
final emailAsDrafts = await emailRepository.saveEmailAsDrafts(accountId, email);
if (emailAsDrafts != null) {
yield Right<Failure, Success>(SaveEmailAsDraftsSuccess(emailAsDrafts));
} else {
yield Left<Failure, Success>(SaveEmailAsDraftsFailure(result));
yield Left<Failure, Success>(SaveEmailAsDraftsFailure(null));
}
} catch (e) {
yield Left<Failure, Success>(SaveEmailAsDraftsFailure(e));
@@ -58,6 +58,7 @@ class ComposerBindings extends BaseBindings {
Get.lazyPut(() => AutoCompleteDataSourceImpl());
Get.lazyPut(() => LocalAutoCompleteDataSourceImpl(Get.find<EmailAddressDatabaseManager>()));
Get.lazyPut(() => ContactDataSourceImpl());
Get.lazyPut(() => EmailDataSourceImpl(Get.find<EmailAPI>()));
Get.lazyPut(() => HtmlDataSourceImpl(
Get.find<HtmlAnalyzer>(),
Get.find<DioClient>()
@@ -84,7 +85,6 @@ class ComposerBindings extends BaseBindings {
DataSourceType.local: Get.find<LocalAutoCompleteDataSourceImpl>(),
}));
Get.lazyPut(() => ContactRepositoryImpl(Get.find<ContactDataSource>()));
Get.lazyPut(() => EmailDataSourceImpl(Get.find<EmailAPI>()));
Get.lazyPut(() => EmailRepositoryImpl(
Get.find<EmailDataSource>(),
Get.find<HtmlDataSource>()
@@ -97,7 +97,6 @@ class ComposerBindings extends BaseBindings {
Get.lazyPut<AutoCompleteRepository>(() => Get.find<AutoCompleteRepositoryImpl>());
Get.lazyPut<ContactRepository>(() => Get.find<ContactRepositoryImpl>());
Get.lazyPut<EmailRepository>(() => Get.find<EmailRepositoryImpl>());
}
@override
@@ -35,5 +35,7 @@ abstract class EmailDataSource {
MarkStarAction markStarAction
);
Future<bool> saveEmailAsDrafts(AccountId accountId, Email email);
Future<Email?> saveEmailAsDrafts(AccountId accountId, Email email);
Future<bool> removeEmailDrafts(AccountId accountId, EmailId emailId);
}
@@ -88,11 +88,20 @@ class EmailDataSourceImpl extends EmailDataSource {
}
@override
Future<bool> saveEmailAsDrafts(AccountId accountId, Email email) {
Future<Email?> saveEmailAsDrafts(AccountId accountId, Email email) {
return Future.sync(() async {
return await emailAPI.saveEmailAsDrafts(accountId, email);
}).catchError((error) {
throw error;
});
}
@override
Future<bool> removeEmailDrafts(AccountId accountId, EmailId emailId) {
return Future.sync(() async {
return await emailAPI.removeEmailDrafts(accountId, emailId);
}).catchError((error) {
throw error;
});
}
}
+26 -2
View File
@@ -254,7 +254,7 @@ class EmailAPI {
});
}
Future<bool> saveEmailAsDrafts(AccountId accountId, Email email) async {
Future<Email?> saveEmailAsDrafts(AccountId accountId, Email email) async {
final setEmailMethod = SetEmailMethod(accountId)
..addCreate(email.id.id, email);
@@ -272,7 +272,31 @@ class EmailAPI {
SetEmailResponse.deserialize);
return Future.sync(() async {
return setEmailResponse?.created?[email.id.id] != null;
return setEmailResponse?.created?[email.id.id];
}).catchError((error) {
throw error;
});
}
Future<bool> removeEmailDrafts(AccountId accountId, EmailId emailId) async {
final setEmailMethod = SetEmailMethod(accountId)
..addDestroy({emailId.id});
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
final response = await (requestBuilder
..usings(setEmailMethod.requiredCapabilities))
.build()
.execute();
final setEmailResponse = response.parse<SetEmailResponse>(
setEmailInvocation.methodCallId,
SetEmailResponse.deserialize);
return Future.sync(() async {
return setEmailResponse?.destroyed?.contains(emailId.id) == true;
}).catchError((error) {
throw error;
});
@@ -90,7 +90,12 @@ class EmailRepositoryImpl extends EmailRepository {
}
@override
Future<bool> saveEmailAsDrafts(AccountId accountId, Email email) {
Future<Email?> saveEmailAsDrafts(AccountId accountId, Email email) {
return emailDataSource.saveEmailAsDrafts(accountId, email);
}
@override
Future<bool> removeEmailDrafts(AccountId accountId, EmailId emailId) {
return emailDataSource.removeEmailDrafts(accountId, emailId);
}
}
@@ -42,5 +42,7 @@ abstract class EmailRepository {
AccountId accountId
);
Future<bool> saveEmailAsDrafts(AccountId accountId, Email email);
Future<Email?> saveEmailAsDrafts(AccountId accountId, Email email);
Future<bool> removeEmailDrafts(AccountId accountId, EmailId emailId);
}
@@ -32,17 +32,18 @@ class BottomBarMailWidgetBuilder {
color: Colors.white,
child: MediaQuery(
data: MediaQueryData(padding: EdgeInsets.zero),
child: _presentationEmail != null ? _buildListOptionButton() : SizedBox.shrink()
child: _presentationEmail != null ? _buildListOptionButton(_presentationEmail!) : SizedBox.shrink()
)
);
}
Widget _buildListOptionButton() {
Widget _buildListOptionButton(PresentationEmail presentationEmail) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
(ButtonBuilder(_imagePaths.icReplyAllV2)
if (presentationEmail.numberOfAllEmailAddress() > 1)
(ButtonBuilder(_imagePaths.icReplyAllV2)
..key(Key('button_reply_all_message'))
..size(20)
..paddingIcon(EdgeInsets.only(
@@ -9,6 +9,7 @@ import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/caching/caching_manager.dart';
import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_read_state.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart';
import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_request.dart';
@@ -22,6 +23,7 @@ import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_tree_b
import 'package:tmail_ui_user/features/mailbox/presentation/extensions/list_mailbox_node_extension.dart';
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/mailbox_creator_arguments.dart';
import 'package:tmail_ui_user/features/mailbox_creator/presentation/model/new_mailbox_arguments.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/thread/domain/state/mark_as_multiple_email_read_state.dart';
import 'package:tmail_ui_user/features/thread/domain/state/move_multiple_email_to_mailbox_state.dart';
@@ -84,6 +86,10 @@ class MailboxController extends BaseController {
|| success is MoveMultipleEmailToMailboxHasSomeEmailFailure) {
mailboxDashBoardController.clearState();
refreshMailboxChanges();
} else if (success is SaveEmailAsDraftsSuccess) {
refreshMailboxChanges();
} else if (success is RemoveEmailDraftsSuccess) {
refreshMailboxChanges();
}
});
});
@@ -0,0 +1,18 @@
import 'package:core/core.dart';
class RemoveEmailDraftsSuccess extends UIState {
RemoveEmailDraftsSuccess();
@override
List<Object?> get props => [];
}
class RemoveEmailDraftsFailure extends FeatureFailure {
final exception;
RemoveEmailDraftsFailure(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/mailbox_dashboard/domain/state/remove_email_drafts_state.dart';
class RemoveEmailDraftsInteractor {
final EmailRepository emailRepository;
RemoveEmailDraftsInteractor(this.emailRepository);
Stream<Either<Failure, Success>> execute(AccountId accountId, EmailId emailId) async* {
try {
final result = await emailRepository.removeEmailDrafts(accountId, emailId);
if (result) {
yield Right<Failure, Success>(RemoveEmailDraftsSuccess());
} else {
yield Left<Failure, Success>(RemoveEmailDraftsFailure(result));
}
} catch (e) {
yield Left<Failure, Success>(RemoveEmailDraftsFailure(e));
}
}
}
@@ -1,30 +1,77 @@
import 'package:core/core.dart';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tmail_ui_user/features/base/base_bindings.dart';
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
import 'package:tmail_ui_user/features/email/data/datasource/html_datasource.dart';
import 'package:tmail_ui_user/features/email/data/datasource_impl/email_datasource_impl.dart';
import 'package:tmail_ui_user/features/email/data/datasource_impl/html_datasource_impl.dart';
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/presentation/email_bindings.dart';
import 'package:tmail_ui_user/features/login/data/repository/credential_repository_impl.dart';
import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_bindings.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_user_profile_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_email_drafts_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/thread/presentation/thread_bindings.dart';
class MailboxDashBoardBindings extends Bindings {
class MailboxDashBoardBindings extends BaseBindings {
@override
void dependencies() {
Get.lazyPut(() => CredentialRepositoryImpl(Get.find<SharedPreferences>()));
Get.lazyPut<CredentialRepository>(() => Get.find<CredentialRepositoryImpl>());
Get.lazyPut(() => GetUserProfileInteractor(Get.find<CredentialRepository>()));
Get.put(MailboxDashBoardController(
Get.find<GetUserProfileInteractor>(),
Get.find<AppToast>(),
Get.find<ImagePaths>(),
));
super.dependencies();
MailboxBindings().dependencies();
ThreadBindings().dependencies();
EmailBindings().dependencies();
}
@override
void bindingsController() {
Get.put(MailboxDashBoardController(
Get.find<GetUserProfileInteractor>(),
Get.find<AppToast>(),
Get.find<ImagePaths>(),
Get.find<RemoveEmailDraftsInteractor>(),
));
}
@override
void bindingsDataSource() {
Get.lazyPut<EmailDataSource>(() => Get.find<EmailDataSourceImpl>());
Get.lazyPut<HtmlDataSource>(() => Get.find<HtmlDataSourceImpl>());
}
@override
void bindingsDataSourceImpl() {
Get.lazyPut(() => EmailDataSourceImpl(Get.find<EmailAPI>()));
Get.lazyPut(() => HtmlDataSourceImpl(
Get.find<HtmlAnalyzer>(),
Get.find<DioClient>()
));
}
@override
void bindingsInteractor() {
Get.lazyPut(() => GetUserProfileInteractor(Get.find<CredentialRepository>()));
Get.lazyPut(() => RemoveEmailDraftsInteractor(Get.find<EmailRepository>()));
}
@override
void bindingsRepository() {
Get.lazyPut<CredentialRepository>(() => Get.find<CredentialRepositoryImpl>());
Get.lazyPut<EmailRepository>(() => Get.find<EmailRepositoryImpl>());
}
@override
void bindingsRepositoryImpl() {
Get.lazyPut(() => CredentialRepositoryImpl(Get.find<SharedPreferences>()));
Get.lazyPut(() => EmailRepositoryImpl(
Get.find<EmailDataSource>(),
Get.find<HtmlDataSource>()
));
}
}
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
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:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
@@ -11,7 +12,9 @@ import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_draft
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
import 'package:tmail_ui_user/features/email/presentation/email_controller.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/get_user_profile_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/get_user_profile_interactor.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/usecases/remove_email_drafts_interactor.dart';
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
import 'package:tmail_ui_user/features/thread/domain/state/search_email_state.dart';
import 'package:tmail_ui_user/features/thread/presentation/model/search_state.dart';
@@ -23,6 +26,7 @@ class MailboxDashBoardController extends BaseController {
final GetUserProfileInteractor _getUserProfileInteractor;
final AppToast _appToast;
final ImagePaths _imagePaths;
final RemoveEmailDraftsInteractor _removeEmailDraftsInteractor;
final scaffoldKey = GlobalKey<ScaffoldState>();
final selectedMailbox = Rxn<PresentationMailbox>();
@@ -43,6 +47,7 @@ class MailboxDashBoardController extends BaseController {
this._getUserProfileInteractor,
this._appToast,
this._imagePaths,
this._removeEmailDraftsInteractor,
);
@override
@@ -96,6 +101,9 @@ class MailboxDashBoardController extends BaseController {
clearState();
} else if (success is SaveEmailAsDraftsSuccess) {
_saveEmailAsDraftsSuccess(success);
clearState();
} else if (success is RemoveEmailDraftsSuccess) {
clearState();
}
}
);
@@ -199,11 +207,18 @@ class MailboxDashBoardController extends BaseController {
Get.overlayContext!,
AppLocalizations.of(Get.context!).drafts_saved,
AppLocalizations.of(Get.context!).discard,
() {}
() => _discardEmail(success.emailAsDrafts)
);
}
}
void _discardEmail(Email email) {
final currentAccountId = accountId.value;
if (currentAccountId != null) {
consumeState(_removeEmailDraftsInteractor.execute(currentAccountId, email.id));
}
}
@override
void onClose() {
searchInputController.dispose();
@@ -14,6 +14,7 @@ import 'package:jmap_dart_client/jmap/mail/email/email_filter_condition.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/composer/domain/state/save_email_as_drafts_state.dart';
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/state/mark_as_email_star_state.dart';
@@ -22,6 +23,7 @@ import 'package:tmail_ui_user/features/email/domain/state/move_to_mailbox_state.
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/state/remove_email_drafts_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.dart';
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
@@ -132,6 +134,10 @@ class ThreadController extends BaseController {
mailboxDashBoardController.clearState();
} else if (success is SearchEmailNewQuery){
_searchEmail();
} else if (success is SaveEmailAsDraftsSuccess
|| success is RemoveEmailDraftsSuccess) {
cancelSelectEmail();
_refreshEmailChanges();
}
});
});