TF-78 Implement mark as read & unread for multiple selected email in threads
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
|
||||
class MarkAsMultipleEmailReadAllSuccess extends UIState {
|
||||
final List<Either<Failure, Success>> resultList;
|
||||
|
||||
MarkAsMultipleEmailReadAllSuccess(this.resultList);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [resultList];
|
||||
}
|
||||
|
||||
class MarkAsMultipleEmailReadAllFailure extends FeatureFailure {
|
||||
final List<Either<Failure, Success>> resultList;
|
||||
|
||||
MarkAsMultipleEmailReadAllFailure(this.resultList);
|
||||
|
||||
@override
|
||||
List<Object> get props => [resultList];
|
||||
}
|
||||
|
||||
class MarkAsMultipleEmailReadHasSomeEmailFailure extends UIState {
|
||||
final List<Either<Failure, Success>> resultList;
|
||||
|
||||
MarkAsMultipleEmailReadHasSomeEmailFailure(this.resultList);
|
||||
|
||||
@override
|
||||
List<Object> get props => [resultList];
|
||||
}
|
||||
|
||||
class MarkAsMultipleEmailReadFailure extends FeatureFailure {
|
||||
final exception;
|
||||
|
||||
MarkAsMultipleEmailReadFailure(this.exception);
|
||||
|
||||
@override
|
||||
List<Object> get props => [exception];
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
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/usecases/mark_as_email_read_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/state/mark_as_multiple_email_read_state.dart';
|
||||
|
||||
class MarkAsMultipleEmailReadInteractor {
|
||||
final MarkAsEmailReadInteractor markAsEmailReadInteractor;
|
||||
|
||||
MarkAsMultipleEmailReadInteractor(this.markAsEmailReadInteractor);
|
||||
|
||||
Future<Either<Failure, Success>> execute(AccountId accountId, List<EmailId> listEmailId, bool unread) async {
|
||||
try {
|
||||
final listResult = await Future.wait(listEmailId.map((emailId) =>
|
||||
markAsEmailReadInteractor.execute(accountId, emailId, unread)));
|
||||
if (listResult.length == 1) {
|
||||
return listResult.first;
|
||||
} else {
|
||||
var failedFileCount = 0;
|
||||
listResult.forEach((element) {
|
||||
if (element is Left) {
|
||||
failedFileCount++;
|
||||
}
|
||||
});
|
||||
if (failedFileCount == 0) {
|
||||
return Right(MarkAsMultipleEmailReadAllSuccess(listResult));
|
||||
} else if (failedFileCount == listResult.length) {
|
||||
return Left(MarkAsMultipleEmailReadAllFailure(listResult));
|
||||
}
|
||||
return Right(MarkAsMultipleEmailReadHasSomeEmailFailure(listResult));
|
||||
}
|
||||
} catch (e) {
|
||||
return Left(MarkAsMultipleEmailReadFailure(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,20 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:core/presentation/utils/responsive_utils.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource/email_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/email/data/datasource_impl/email_datasource_impl.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/mark_as_email_read_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/datasource/thread_datasource.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/datasource_impl/thread_datasource_impl.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/network/thread_api.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/repository/thread_repository_impl.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/repository/thread_repository.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/usecases/get_emails_in_mailbox_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/usecases/mark_as_multiple_email_read_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/thread_controller.dart';
|
||||
|
||||
class ThreadBindings extends Bindings {
|
||||
@@ -18,10 +26,18 @@ class ThreadBindings extends Bindings {
|
||||
Get.lazyPut<ThreadRepository>(() => Get.find<ThreadRepositoryImpl>());
|
||||
Get.lazyPut(() => GetEmailsInMailboxInteractor(Get.find<ThreadRepository>()));
|
||||
Get.lazyPut(() => ScrollController());
|
||||
Get.lazyPut(() => EmailDataSourceImpl(Get.find<EmailAPI>()));
|
||||
Get.lazyPut<EmailDataSource>(() => Get.find<EmailDataSourceImpl>());
|
||||
Get.lazyPut(() => EmailRepositoryImpl(Get.find<EmailDataSource>()));
|
||||
Get.lazyPut<EmailRepository>(() => Get.find<EmailRepositoryImpl>());
|
||||
Get.lazyPut(() => MarkAsEmailReadInteractor(Get.find<EmailRepository>()));
|
||||
Get.lazyPut(() => MarkAsMultipleEmailReadInteractor(Get.find<MarkAsEmailReadInteractor>()));
|
||||
Get.put(ThreadController(
|
||||
Get.find<ResponsiveUtils>(),
|
||||
Get.find<GetEmailsInMailboxInteractor>(),
|
||||
Get.find<ScrollController>(),
|
||||
Get.find<MarkAsMultipleEmailReadInteractor>(),
|
||||
Get.find<AppToast>(),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,14 @@ 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/email/domain/state/mark_as_email_read_state.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/features/thread/domain/constants/thread_constants.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/state/get_all_email_state.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/usecases/get_emails_in_mailbox_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/thread/domain/usecases/mark_as_multiple_email_read_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/model/load_more_state.dart';
|
||||
import 'package:tmail_ui_user/features/thread/presentation/widgets/email_context_menu_action_builder.dart';
|
||||
import 'package:tmail_ui_user/main/actions/email_action.dart';
|
||||
@@ -32,6 +35,8 @@ class ThreadController extends BaseController {
|
||||
|
||||
final mailboxDashBoardController = Get.find<MailboxDashBoardController>();
|
||||
final GetEmailsInMailboxInteractor _getEmailsInMailboxInteractor;
|
||||
final MarkAsMultipleEmailReadInteractor _markAsMultipleEmailReadInteractor;
|
||||
final AppToast _appToast;
|
||||
final ResponsiveUtils responsiveUtils;
|
||||
final ScrollController listEmailController;
|
||||
|
||||
@@ -52,6 +57,8 @@ class ThreadController extends BaseController {
|
||||
this.responsiveUtils,
|
||||
this._getEmailsInMailboxInteractor,
|
||||
this.listEmailController,
|
||||
this._markAsMultipleEmailReadInteractor,
|
||||
this._appToast,
|
||||
);
|
||||
|
||||
@override
|
||||
@@ -204,7 +211,7 @@ class ThreadController extends BaseController {
|
||||
|
||||
bool _isUnSelectedAll() => emailList.every((email) => email.selectMode == SelectMode.INACTIVE);
|
||||
|
||||
bool _isEmailAllRead(List<PresentationEmail> listEmail) => listEmail.every((email) => !email.isUnReadEmail());
|
||||
bool _isEmailAllRead(List<PresentationEmail> listEmail) => listEmail.every((email) => email.isReadEmail());
|
||||
|
||||
void cancelSelectEmail() {
|
||||
emailList.value = emailList.map((email) => email.toSelectedEmail(selectMode: SelectMode.INACTIVE)).toList();
|
||||
@@ -218,8 +225,47 @@ class ThreadController extends BaseController {
|
||||
emailList.value = newEmailList;
|
||||
}
|
||||
|
||||
void unreadSelectedEmail(List<PresentationEmail> listEmail) {
|
||||
popBack();
|
||||
void unreadSelectedEmail(List<PresentationEmail> listEmail, {bool fromContextMenuAction = false}) {
|
||||
if (fromContextMenuAction) {
|
||||
popBack();
|
||||
}
|
||||
|
||||
final isUnread = _isEmailAllRead(listEmail);
|
||||
|
||||
final listEmailId = listEmail
|
||||
.where((email) => isUnread ? email.isReadEmail() : email.isUnReadEmail())
|
||||
.map((email) => email.id)
|
||||
.toList();
|
||||
|
||||
final accountId = mailboxDashBoardController.accountId.value;
|
||||
|
||||
if (accountId != null) {
|
||||
_markAsMultipleEmailReadInteractor
|
||||
.execute(accountId, listEmailId, isUnread)
|
||||
.then((result) => result.fold(
|
||||
(failure) {
|
||||
cancelSelectEmail();
|
||||
|
||||
if (failure is MarkAsEmailReadFailure
|
||||
|| failure is MarkAsMultipleEmailReadAllFailure
|
||||
|| failure is MarkAsMultipleEmailReadFailure) {
|
||||
_appToast.showErrorToast(AppLocalizations.of(Get.context!).an_error_occurred);
|
||||
}
|
||||
},
|
||||
(success) {
|
||||
cancelSelectEmail();
|
||||
|
||||
if (success is MarkAsEmailReadSuccess
|
||||
|| success is MarkAsMultipleEmailReadAllSuccess
|
||||
|| success is MarkAsMultipleEmailReadHasSomeEmailFailure) {
|
||||
if (Get.context != null) {
|
||||
_appToast.showSuccessToast(isUnread
|
||||
? AppLocalizations.of(Get.context!).marked_multiple_item_as_unread(listEmail.length)
|
||||
: AppLocalizations.of(Get.context!).marked_multiple_item_as_read(listEmail.length));
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
void openContextMenuSelectedEmail(BuildContext context, ImagePaths imagePaths, List<PresentationEmail> listEmail) {
|
||||
@@ -245,7 +291,7 @@ class ThreadController extends BaseController {
|
||||
SvgPicture.asset(imagePaths.icEyeDisable, width: 24, height: 24, fit: BoxFit.fill),
|
||||
_isEmailAllRead(listEmail) ? AppLocalizations.of(context).mark_as_unread : AppLocalizations.of(context).mark_as_read,
|
||||
listEmail)
|
||||
..onActionClick((data) => unreadSelectedEmail(data)))
|
||||
..onActionClick((data) => unreadSelectedEmail(data, fromContextMenuAction: true)))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -199,5 +199,24 @@
|
||||
"@move_to_spam": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"marked_multiple_item_as_read": "Marked {count} item as read",
|
||||
"@marked_multiple_item_as_read": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"count": {}
|
||||
}
|
||||
},
|
||||
"marked_multiple_item_as_unread": "Marked {count} item as unread",
|
||||
"@marked_multiple_item_as_unread": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"count": {}
|
||||
}
|
||||
},
|
||||
"an_error_occurred": "Error! An error occurred. Please try again later.",
|
||||
"@an_error_occurred": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
@@ -199,5 +199,24 @@
|
||||
"@move_to_spam": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"marked_multiple_item_as_read": "Marked {count} item as read",
|
||||
"@marked_multiple_item_as_read": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"count": {}
|
||||
}
|
||||
},
|
||||
"marked_multiple_item_as_unread": "Marked {count} item as unread",
|
||||
"@marked_multiple_item_as_unread": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"count": {}
|
||||
}
|
||||
},
|
||||
"an_error_occurred": "Error! An error occurred. Please try again later.",
|
||||
"@an_error_occurred": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"@@last_modified": "2021-09-15T10:03:14.927099",
|
||||
"@@last_modified": "2021-09-15T11:00:57.061103",
|
||||
"initializing_data": "Initializing data...",
|
||||
"@initializing_data": {
|
||||
"type": "text",
|
||||
@@ -254,5 +254,24 @@
|
||||
"@move_to_spam": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"marked_multiple_item_as_read": "Marked {count} item as read",
|
||||
"@marked_multiple_item_as_read": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"count": {}
|
||||
}
|
||||
},
|
||||
"marked_multiple_item_as_unread": "Marked {count} item as unread",
|
||||
"@marked_multiple_item_as_unread": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"count": {}
|
||||
}
|
||||
},
|
||||
"an_error_occurred": "Error! An error occurred. Please try again later.",
|
||||
"@an_error_occurred": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
@@ -199,5 +199,24 @@
|
||||
"@move_to_spam": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"marked_multiple_item_as_read": "Marked {count} item as read",
|
||||
"@marked_multiple_item_as_read": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"count": {}
|
||||
}
|
||||
},
|
||||
"marked_multiple_item_as_unread": "Marked {count} item as unread",
|
||||
"@marked_multiple_item_as_unread": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"count": {}
|
||||
}
|
||||
},
|
||||
"an_error_occurred": "Error! An error occurred. Please try again later.",
|
||||
"@an_error_occurred": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
@@ -199,5 +199,24 @@
|
||||
"@move_to_spam": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"marked_multiple_item_as_read": "Marked {count} item as read",
|
||||
"@marked_multiple_item_as_read": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"count": {}
|
||||
}
|
||||
},
|
||||
"marked_multiple_item_as_unread": "Marked {count} item as unread",
|
||||
"@marked_multiple_item_as_unread": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"count": {}
|
||||
}
|
||||
},
|
||||
"an_error_occurred": "Error! An error occurred. Please try again later.",
|
||||
"@an_error_occurred": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
@@ -277,5 +277,28 @@ class AppLocalizations {
|
||||
name: 'move_to_spam',
|
||||
);
|
||||
}
|
||||
|
||||
String marked_multiple_item_as_read(int count) {
|
||||
return Intl.message(
|
||||
'Marked $count item as read',
|
||||
name: 'marked_multiple_item_as_read',
|
||||
args: [count]
|
||||
);
|
||||
}
|
||||
|
||||
String marked_multiple_item_as_unread(int count) {
|
||||
return Intl.message(
|
||||
'Marked $count item as unread',
|
||||
name: 'marked_multiple_item_as_unread',
|
||||
args: [count]
|
||||
);
|
||||
}
|
||||
|
||||
String get an_error_occurred {
|
||||
return Intl.message(
|
||||
'Error! An error occurred. Please try again later.',
|
||||
name: 'an_error_occurred',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,8 @@ class PresentationEmail with EquatableMixin {
|
||||
|
||||
bool isUnReadEmail() => !(keywords?.containsKey(KeyWordIdentifier.emailSeen) == true);
|
||||
|
||||
bool isReadEmail() => keywords?.containsKey(KeyWordIdentifier.emailSeen) == true;
|
||||
|
||||
bool isFlaggedEmail() => keywords?.containsKey(KeyWordIdentifier.emailFlagged) == true;
|
||||
|
||||
@override
|
||||
|
||||
Reference in New Issue
Block a user