TF-3334 Remove Email/get of mark as read & mark as star action

This commit is contained in:
dab246
2024-12-19 00:50:13 +07:00
committed by Dat H. Pham
parent 75231636e2
commit eb51e9b3b1
27 changed files with 419 additions and 345 deletions
@@ -43,7 +43,12 @@ abstract class EmailDataSource {
} }
); );
Future<List<Email>> markAsRead(Session session, AccountId accountId, List<Email> emails, ReadActions readActions); Future<List<EmailId>> markAsRead(
Session session,
AccountId accountId,
List<EmailId> emailIds,
ReadActions readActions,
);
Future<List<DownloadTaskId>> downloadAttachments( Future<List<DownloadTaskId>> downloadAttachments(
List<Attachment> attachments, List<Attachment> attachments,
@@ -72,10 +77,10 @@ abstract class EmailDataSource {
Future<List<EmailId>> moveToMailbox(Session session, AccountId accountId, MoveToMailboxRequest moveRequest); Future<List<EmailId>> moveToMailbox(Session session, AccountId accountId, MoveToMailboxRequest moveRequest);
Future<List<Email>> markAsStar( Future<List<EmailId>> markAsStar(
Session session, Session session,
AccountId accountId, AccountId accountId,
List<Email> emails, List<EmailId> emailIds,
MarkStarAction markStarAction MarkStarAction markStarAction
); );
@@ -144,7 +149,7 @@ abstract class EmailDataSource {
Future<EmailRecoveryAction> getRestoredDeletedMessage(EmailRecoveryActionId emailRecoveryActionId); Future<EmailRecoveryAction> getRestoredDeletedMessage(EmailRecoveryActionId emailRecoveryActionId);
Future<Email> storeEventAttendanceStatus( Future<void> storeEventAttendanceStatus(
Session session, Session session,
AccountId accountId, AccountId accountId,
EmailId emailId, EmailId emailId,
@@ -75,14 +75,14 @@ class EmailDataSourceImpl extends EmailDataSource {
} }
@override @override
Future<List<Email>> markAsRead( Future<List<EmailId>> markAsRead(
Session session, Session session,
AccountId accountId, AccountId accountId,
List<Email> emails, List<EmailId> emailIds,
ReadActions readActions ReadActions readActions,
) { ) {
return Future.sync(() async { return Future.sync(() async {
return await emailAPI.markAsRead(session, accountId, emails, readActions); return await emailAPI.markAsRead(session, accountId, emailIds, readActions);
}).catchError(_exceptionThrower.throwException); }).catchError(_exceptionThrower.throwException);
} }
@@ -119,9 +119,19 @@ class EmailDataSourceImpl extends EmailDataSource {
} }
@override @override
Future<List<Email>> markAsStar(Session session, AccountId accountId, List<Email> emails, MarkStarAction markStarAction) { Future<List<EmailId>> markAsStar(
Session session,
AccountId accountId,
List<EmailId> emailIds,
MarkStarAction markStarAction,
) {
return Future.sync(() async { return Future.sync(() async {
return await emailAPI.markAsStar(session, accountId, emails, markStarAction); return await emailAPI.markAsStar(
session,
accountId,
emailIds,
markStarAction,
);
}).catchError(_exceptionThrower.throwException); }).catchError(_exceptionThrower.throwException);
} }
@@ -318,7 +328,7 @@ class EmailDataSourceImpl extends EmailDataSource {
} }
@override @override
Future<Email> storeEventAttendanceStatus( Future<void> storeEventAttendanceStatus(
Session session, Session session,
AccountId accountId, AccountId accountId,
EmailId emailId, EmailId emailId,
@@ -120,12 +120,17 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
} }
@override @override
Future<List<Email>> markAsRead(Session session, AccountId accountId, List<Email> emails, ReadActions readActions) { Future<List<EmailId>> markAsRead(
Session session,
AccountId accountId,
List<EmailId> emailIds,
ReadActions readActions,
) {
throw UnimplementedError(); throw UnimplementedError();
} }
@override @override
Future<List<Email>> markAsStar(Session session, AccountId accountId, List<Email> emails, MarkStarAction markStarAction) { Future<List<EmailId>> markAsStar(Session session, AccountId accountId, List<EmailId> emailIds, MarkStarAction markStarAction) {
throw UnimplementedError(); throw UnimplementedError();
} }
+52 -55
View File
@@ -44,13 +44,11 @@ import 'package:model/account/authentication_type.dart';
import 'package:model/download/download_task_id.dart'; import 'package:model/download/download_task_id.dart';
import 'package:model/email/attachment.dart'; import 'package:model/email/attachment.dart';
import 'package:model/email/email_action_type.dart'; import 'package:model/email/email_action_type.dart';
import 'package:model/email/email_property.dart';
import 'package:model/email/mark_star_action.dart'; import 'package:model/email/mark_star_action.dart';
import 'package:model/email/read_actions.dart'; import 'package:model/email/read_actions.dart';
import 'package:model/extensions/email_extension.dart'; import 'package:model/extensions/email_extension.dart';
import 'package:model/extensions/email_id_extensions.dart'; import 'package:model/extensions/email_id_extensions.dart';
import 'package:model/extensions/keyword_identifier_extension.dart'; import 'package:model/extensions/keyword_identifier_extension.dart';
import 'package:model/extensions/list_email_extension.dart';
import 'package:model/extensions/list_email_id_extension.dart'; import 'package:model/extensions/list_email_id_extension.dart';
import 'package:model/extensions/mailbox_id_extension.dart'; import 'package:model/extensions/mailbox_id_extension.dart';
import 'package:model/extensions/session_extension.dart'; import 'package:model/extensions/session_extension.dart';
@@ -239,24 +237,18 @@ class EmailAPI with HandleSetErrorMixin {
} }
} }
Future<List<Email>> markAsRead( Future<List<EmailId>> markAsRead(
Session session, Session session,
AccountId accountId, AccountId accountId,
List<Email> emails, List<EmailId> emailIds,
ReadActions readActions ReadActions readActions,
) async { ) async {
final setEmailMethod = SetEmailMethod(accountId) final setEmailMethod = SetEmailMethod(accountId)
..addUpdates(emails.listEmailIds.generateMapUpdateObjectMarkAsRead(readActions)); ..addUpdates(emailIds.generateMapUpdateObjectMarkAsRead(readActions));
final getEmailMethod = GetEmailMethod(accountId)
..addIds(emails.listEmailIds.toIds().toSet())
..addProperties(Properties({EmailProperty.keywords}));
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation()); final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
requestBuilder.invocation(setEmailMethod); final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
final getEmailInvocation = requestBuilder.invocation(getEmailMethod);
final capabilities = setEmailMethod.requiredCapabilities final capabilities = setEmailMethod.requiredCapabilities
.toCapabilitiesSupportTeamMailboxes(session, accountId); .toCapabilitiesSupportTeamMailboxes(session, accountId);
@@ -266,15 +258,22 @@ class EmailAPI with HandleSetErrorMixin {
.build() .build()
.execute(); .execute();
final getEmailResponse = response.parse<GetEmailResponse>( final setEmailResponse = response.parse<SetEmailResponse>(
getEmailInvocation.methodCallId, setEmailInvocation.methodCallId,
GetEmailResponse.deserialize); SetEmailResponse.deserialize,
);
return Future.sync(() async { final emailIdUpdated = setEmailResponse?.updated
return getEmailResponse!.list; ?.keys
}).catchError((error) { .map((id) => EmailId(id))
throw error; .toList() ?? [];
}); final mapErrors = handleSetResponse([setEmailResponse]);
if (emailIdUpdated.isNotEmpty) {
return emailIdUpdated;
} else {
throw SetMethodException(mapErrors);
}
} }
Future<List<DownloadTaskId>> downloadAttachments( Future<List<DownloadTaskId>> downloadAttachments(
@@ -449,24 +448,18 @@ class EmailAPI with HandleSetErrorMixin {
return listEmailIdRequest.where((emailId) => listUpdated.expand((e) => e).toList().contains(emailId.id)).toList(); return listEmailIdRequest.where((emailId) => listUpdated.expand((e) => e).toList().contains(emailId.id)).toList();
} }
Future<List<Email>> markAsStar( Future<List<EmailId>> markAsStar(
Session session, Session session,
AccountId accountId, AccountId accountId,
List<Email> emails, List<EmailId> emailIds,
MarkStarAction markStarAction MarkStarAction markStarAction
) async { ) async {
final setEmailMethod = SetEmailMethod(accountId) final setEmailMethod = SetEmailMethod(accountId)
..addUpdates(emails.listEmailIds.generateMapUpdateObjectMarkAsStar(markStarAction)); ..addUpdates(emailIds.generateMapUpdateObjectMarkAsStar(markStarAction));
final getEmailMethod = GetEmailMethod(accountId)
..addIds(emails.listEmailIds.toIds().toSet())
..addProperties(Properties({EmailProperty.keywords}));
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation()); final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
requestBuilder.invocation(setEmailMethod); final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
final getEmailInvocation = requestBuilder.invocation(getEmailMethod);
final capabilities = setEmailMethod.requiredCapabilities final capabilities = setEmailMethod.requiredCapabilities
.toCapabilitiesSupportTeamMailboxes(session, accountId); .toCapabilitiesSupportTeamMailboxes(session, accountId);
@@ -476,15 +469,22 @@ class EmailAPI with HandleSetErrorMixin {
.build() .build()
.execute(); .execute();
final getEmailResponse = response.parse<GetEmailResponse>( final setEmailResponse = response.parse<SetEmailResponse>(
getEmailInvocation.methodCallId, setEmailInvocation.methodCallId,
GetEmailResponse.deserialize); SetEmailResponse.deserialize,
);
return Future.sync(() async { final emailIdUpdated = setEmailResponse?.updated
return getEmailResponse!.list; ?.keys
}).catchError((error) { .map((id) => EmailId(id))
throw error; .toList() ?? [];
}); final mapErrors = handleSetResponse([setEmailResponse]);
if (emailIdUpdated.isNotEmpty) {
return emailIdUpdated;
} else {
throw SetMethodException(mapErrors);
}
} }
Future<Email> saveEmailAsDrafts( Future<Email> saveEmailAsDrafts(
@@ -756,7 +756,7 @@ class EmailAPI with HandleSetErrorMixin {
} }
} }
Future<Email> storeEventAttendanceStatus( Future<void> storeEventAttendanceStatus(
Session session, Session session,
AccountId accountId, AccountId accountId,
EmailId emailId, EmailId emailId,
@@ -765,15 +765,9 @@ class EmailAPI with HandleSetErrorMixin {
final setEmailMethod = SetEmailMethod(accountId) final setEmailMethod = SetEmailMethod(accountId)
..addUpdates(emailId.generateMapUpdateObjectEventAttendanceStatus(eventActionType)); ..addUpdates(emailId.generateMapUpdateObjectEventAttendanceStatus(eventActionType));
final getEmailMethod = GetEmailMethod(accountId)
..addIds({emailId.id})
..addProperties(Properties({EmailProperty.keywords}));
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation()); final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
requestBuilder.invocation(setEmailMethod); final setEmailInvocation = requestBuilder.invocation(setEmailMethod);
final getEmailInvocation = requestBuilder.invocation(getEmailMethod);
final capabilities = setEmailMethod.requiredCapabilities final capabilities = setEmailMethod.requiredCapabilities
.toCapabilitiesSupportTeamMailboxes(session, accountId); .toCapabilitiesSupportTeamMailboxes(session, accountId);
@@ -783,16 +777,19 @@ class EmailAPI with HandleSetErrorMixin {
.build() .build()
.execute(); .execute();
final getEmailResponse = response.parse<GetEmailResponse>( final setEmailResponse = response.parse<SetEmailResponse>(
getEmailInvocation.methodCallId, setEmailInvocation.methodCallId,
GetEmailResponse.deserialize); SetEmailResponse.deserialize,
);
final listEmails = getEmailResponse?.list ?? []; final emailIdUpdated = setEmailResponse?.updated
?.keys
.map((id) => EmailId(id))
.toList() ?? [];
final mapErrors = handleSetResponse([setEmailResponse]);
if (listEmails.isNotEmpty) { if (emailIdUpdated.isEmpty) {
return listEmails.first; throw SetMethodException(mapErrors);
} else {
throw NotFoundEmailException();
} }
} }
} }
@@ -83,13 +83,18 @@ class EmailRepositoryImpl extends EmailRepository {
} }
@override @override
Future<List<Email>> markAsRead( Future<List<EmailId>> markAsRead(
Session session, Session session,
AccountId accountId, AccountId accountId,
List<Email> emails, List<EmailId> emailIds,
ReadActions readActions ReadActions readActions,
) { ) {
return emailDataSource[DataSourceType.network]!.markAsRead(session, accountId, emails, readActions); return emailDataSource[DataSourceType.network]!.markAsRead(
session,
accountId,
emailIds,
readActions,
);
} }
@override @override
@@ -124,13 +129,18 @@ class EmailRepositoryImpl extends EmailRepository {
} }
@override @override
Future<List<Email>> markAsStar( Future<List<EmailId>> markAsStar(
Session session, Session session,
AccountId accountId, AccountId accountId,
List<Email> emails, List<EmailId> emailIds,
MarkStarAction markStarAction MarkStarAction markStarAction
) { ) {
return emailDataSource[DataSourceType.network]!.markAsStar(session, accountId, emails, markStarAction); return emailDataSource[DataSourceType.network]!.markAsStar(
session,
accountId,
emailIds,
markStarAction,
);
} }
@override @override
@@ -303,7 +313,7 @@ class EmailRepositoryImpl extends EmailRepository {
} }
@override @override
Future<Email> storeEventAttendanceStatus( Future<void> storeEventAttendanceStatus(
Session session, Session session,
AccountId accountId, AccountId accountId,
EmailId emailId, EmailId emailId,
@@ -2,6 +2,7 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:jmap_dart_client/jmap/core/patch_object.dart'; import 'package:jmap_dart_client/jmap/core/patch_object.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:model/extensions/keyword_identifier_extension.dart'; import 'package:model/extensions/keyword_identifier_extension.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -61,6 +62,31 @@ enum EventActionType {
return ''; return '';
} }
} }
Map<KeyWordIdentifier, bool> getMapKeywords() {
switch(this) {
case EventActionType.yes:
return {
KeyWordIdentifierExtension.acceptedEventAttendance: true,
KeyWordIdentifierExtension.tentativelyAcceptedEventAttendance: false,
KeyWordIdentifierExtension.rejectedEventAttendance: false,
};
case EventActionType.maybe:
return {
KeyWordIdentifierExtension.acceptedEventAttendance: false,
KeyWordIdentifierExtension.tentativelyAcceptedEventAttendance: true,
KeyWordIdentifierExtension.rejectedEventAttendance: false,
};
case EventActionType.no:
return {
KeyWordIdentifierExtension.acceptedEventAttendance: false,
KeyWordIdentifierExtension.tentativelyAcceptedEventAttendance: false,
KeyWordIdentifierExtension.rejectedEventAttendance: true,
};
case EventActionType.mailToAttendees:
return {};
}
}
} }
class EventAction with EquatableMixin { class EventAction with EquatableMixin {
@@ -45,7 +45,12 @@ abstract class EmailRepository {
} }
); );
Future<List<Email>> markAsRead(Session session, AccountId accountId, List<Email> emails, ReadActions readActions); Future<List<EmailId>> markAsRead(
Session session,
AccountId accountId,
List<EmailId> emailIds,
ReadActions readActions,
);
Future<List<DownloadTaskId>> downloadAttachments( Future<List<DownloadTaskId>> downloadAttachments(
List<Attachment> attachments, List<Attachment> attachments,
@@ -74,10 +79,10 @@ abstract class EmailRepository {
Future<List<EmailId>> moveToMailbox(Session session, AccountId accountId, MoveToMailboxRequest moveRequest); Future<List<EmailId>> moveToMailbox(Session session, AccountId accountId, MoveToMailboxRequest moveRequest);
Future<List<Email>> markAsStar( Future<List<EmailId>> markAsStar(
Session session, Session session,
AccountId accountId, AccountId accountId,
List<Email> emails, List<EmailId> emailIds,
MarkStarAction markStarAction MarkStarAction markStarAction
); );
@@ -147,7 +152,7 @@ abstract class EmailRepository {
Future<void> printEmail(EmailPrint emailPrint); Future<void> printEmail(EmailPrint emailPrint);
Future<Email> storeEventAttendanceStatus( Future<void> storeEventAttendanceStatus(
Session session, Session session,
AccountId accountId, AccountId accountId,
EmailId emailId, EmailId emailId,
@@ -7,12 +7,12 @@ import 'package:tmail_ui_user/features/base/state/ui_action_state.dart';
import 'package:tmail_ui_user/features/email/domain/model/mark_read_action.dart'; import 'package:tmail_ui_user/features/email/domain/model/mark_read_action.dart';
class MarkAsEmailReadSuccess extends UIActionState { class MarkAsEmailReadSuccess extends UIActionState {
final Email updatedEmail; final EmailId emailId;
final ReadActions readActions; final ReadActions readActions;
final MarkReadAction markReadAction; final MarkReadAction markReadAction;
MarkAsEmailReadSuccess( MarkAsEmailReadSuccess(
this.updatedEmail, this.emailId,
this.readActions, this.readActions,
this.markReadAction, this.markReadAction,
{ {
@@ -22,7 +22,7 @@ class MarkAsEmailReadSuccess extends UIActionState {
) : super(currentEmailState, currentMailboxState); ) : super(currentEmailState, currentMailboxState);
@override @override
List<Object?> get props => [updatedEmail, readActions, markReadAction, ...super.props]; List<Object?> get props => [emailId, readActions, markReadAction, ...super.props];
} }
class MarkAsEmailReadFailure extends FeatureFailure { class MarkAsEmailReadFailure extends FeatureFailure {
@@ -1,15 +1,12 @@
import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/failure.dart';
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:model/email/mark_star_action.dart';
import 'package:model/model.dart';
import 'package:tmail_ui_user/features/base/state/ui_action_state.dart'; import 'package:tmail_ui_user/features/base/state/ui_action_state.dart';
class MarkAsStarEmailSuccess extends UIActionState { class MarkAsStarEmailSuccess extends UIActionState {
final Email updatedEmail;
final MarkStarAction markStarAction; final MarkStarAction markStarAction;
MarkAsStarEmailSuccess( MarkAsStarEmailSuccess(
this.updatedEmail,
this.markStarAction, this.markStarAction,
{ {
jmap.State? currentEmailState, jmap.State? currentEmailState,
@@ -18,7 +15,7 @@ class MarkAsStarEmailSuccess extends UIActionState {
) : super(currentEmailState, currentMailboxState); ) : super(currentEmailState, currentMailboxState);
@override @override
List<Object?> get props => [updatedEmail, markStarAction, ...super.props]; List<Object?> get props => [markStarAction, ...super.props];
} }
class MarkAsStarEmailFailure extends FeatureFailure { class MarkAsStarEmailFailure extends FeatureFailure {
@@ -1,7 +1,6 @@
import 'package:core/presentation/state/failure.dart'; import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart'; import 'package:core/presentation/state/success.dart';
import 'package:jmap_dart_client/jmap/core/state.dart' as jmap; import 'package:jmap_dart_client/jmap/core/state.dart' as jmap;
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:tmail_ui_user/features/base/state/ui_action_state.dart'; import 'package:tmail_ui_user/features/base/state/ui_action_state.dart';
import 'package:tmail_ui_user/features/email/domain/model/event_action.dart'; import 'package:tmail_ui_user/features/email/domain/model/event_action.dart';
@@ -10,11 +9,9 @@ class StoreEventAttendanceStatusLoading extends LoadingState {}
class StoreEventAttendanceStatusSuccess extends UIActionState { class StoreEventAttendanceStatusSuccess extends UIActionState {
final EventActionType eventActionType; final EventActionType eventActionType;
final Email updatedEmail;
StoreEventAttendanceStatusSuccess( StoreEventAttendanceStatusSuccess(
this.eventActionType, this.eventActionType,
this.updatedEmail,
{ {
jmap.State? currentEmailState, jmap.State? currentEmailState,
jmap.State? currentMailboxState, jmap.State? currentMailboxState,
@@ -24,7 +21,6 @@ class StoreEventAttendanceStatusSuccess extends UIActionState {
@override @override
List<Object?> get props => [ List<Object?> get props => [
eventActionType, eventActionType,
updatedEmail,
...super.props]; ...super.props];
} }
@@ -1,9 +1,10 @@
import 'package:core/core.dart'; import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/account_id.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/core/session/session.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:model/model.dart'; import 'package:model/email/read_actions.dart';
import 'package:tmail_ui_user/features/email/domain/model/mark_read_action.dart'; import 'package:tmail_ui_user/features/email/domain/model/mark_read_action.dart';
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart'; import 'package:tmail_ui_user/features/email/domain/repository/email_repository.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_read_state.dart';
@@ -15,7 +16,13 @@ class MarkAsEmailReadInteractor {
MarkAsEmailReadInteractor(this._emailRepository, this._mailboxRepository); MarkAsEmailReadInteractor(this._emailRepository, this._mailboxRepository);
Stream<Either<Failure, Success>> execute(Session session, AccountId accountId, Email email, ReadActions readAction, MarkReadAction markReadAction) async* { Stream<Either<Failure, Success>> execute(
Session session,
AccountId accountId,
EmailId emailId,
ReadActions readAction,
MarkReadAction markReadAction,
) async* {
try { try {
final listState = await Future.wait([ final listState = await Future.wait([
_mailboxRepository.getMailboxState( session,accountId), _mailboxRepository.getMailboxState( session,accountId),
@@ -25,18 +32,20 @@ class MarkAsEmailReadInteractor {
final currentMailboxState = listState.first; final currentMailboxState = listState.first;
final currentEmailState = listState.last; final currentEmailState = listState.last;
final result = await _emailRepository.markAsRead(session, accountId, [email], readAction); final result = await _emailRepository.markAsRead(
if (result.isNotEmpty) { session,
final updatedEmail = email.updatedEmail(newKeywords: result.first.keywords); accountId,
yield Right(MarkAsEmailReadSuccess( [emailId],
updatedEmail, readAction,
readAction, );
markReadAction,
currentEmailState: currentEmailState, yield Right(MarkAsEmailReadSuccess(
currentMailboxState: currentMailboxState)); result.first,
} else { readAction,
yield Left(MarkAsEmailReadFailure(readAction)); markReadAction,
} currentEmailState: currentEmailState,
currentMailboxState: currentMailboxState,
));
} catch (e) { } catch (e) {
yield Left(MarkAsEmailReadFailure(readAction, exception: e)); yield Left(MarkAsEmailReadFailure(readAction, exception: e));
} }
@@ -1,4 +1,5 @@
import 'package:core/core.dart'; import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/account_id.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/core/session/session.dart';
@@ -12,19 +13,24 @@ class MarkAsStarEmailInteractor {
MarkAsStarEmailInteractor(this.emailRepository); MarkAsStarEmailInteractor(this.emailRepository);
Stream<Either<Failure, Success>> execute(Session session, AccountId accountId, Email email, MarkStarAction markStarAction) async* { Stream<Either<Failure, Success>> execute(
Session session,
AccountId accountId,
EmailId emailId,
MarkStarAction markStarAction,
) async* {
try { try {
final currentEmailState = await emailRepository.getEmailState(session, accountId); final currentEmailState = await emailRepository.getEmailState(session, accountId);
final result = await emailRepository.markAsStar(session, accountId, [email], markStarAction); await emailRepository.markAsStar(
if (result.isNotEmpty) { session,
final updatedEmail = email.updatedEmail(newKeywords: result.first.keywords); accountId,
yield Right(MarkAsStarEmailSuccess( [emailId],
updatedEmail, markStarAction,
markStarAction, );
currentEmailState: currentEmailState)); yield Right(MarkAsStarEmailSuccess(
} else { markStarAction,
yield Left(MarkAsStarEmailFailure(markStarAction)); currentEmailState: currentEmailState,
} ));
} catch (e) { } catch (e) {
yield Left(MarkAsStarEmailFailure(markStarAction, exception: e)); yield Left(MarkAsStarEmailFailure(markStarAction, exception: e));
} }
@@ -24,7 +24,7 @@ class StoreEventAttendanceStatusInteractor {
final currentEmailState = await _emailRepository.getEmailState(session, accountId); final currentEmailState = await _emailRepository.getEmailState(session, accountId);
final updatedEmail = await _emailRepository.storeEventAttendanceStatus( await _emailRepository.storeEventAttendanceStatus(
session, session,
accountId, accountId,
emailId, emailId,
@@ -32,7 +32,6 @@ class StoreEventAttendanceStatusInteractor {
yield Right(StoreEventAttendanceStatusSuccess( yield Right(StoreEventAttendanceStatusSuccess(
eventActionType, eventActionType,
updatedEmail,
currentEmailState: currentEmailState)); currentEmailState: currentEmailState));
} catch (e) { } catch (e) {
yield Left(StoreEventAttendanceStatusFailure(exception: e)); yield Left(StoreEventAttendanceStatusFailure(exception: e));
@@ -23,6 +23,7 @@ import 'package:jmap_dart_client/jmap/mail/calendar/properties/attendee/calendar
import 'package:jmap_dart_client/jmap/mail/calendar/properties/calendar_organizer.dart'; import 'package:jmap_dart_client/jmap/mail/calendar/properties/calendar_organizer.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:jmap_dart_client/jmap/mdn/disposition.dart'; import 'package:jmap_dart_client/jmap/mdn/disposition.dart';
import 'package:jmap_dart_client/jmap/mdn/mdn.dart'; import 'package:jmap_dart_client/jmap/mdn/mdn.dart';
import 'package:model/email/eml_attachment.dart'; import 'package:model/email/eml_attachment.dart';
@@ -62,6 +63,7 @@ import 'package:tmail_ui_user/features/email/domain/state/send_receipt_to_sender
import 'package:tmail_ui_user/features/email/domain/state/store_event_attendance_status_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/store_event_attendance_status_state.dart';
import 'package:tmail_ui_user/features/email/domain/state/unsubscribe_email_state.dart'; import 'package:tmail_ui_user/features/email/domain/state/unsubscribe_email_state.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/calendar_event_accept_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/calendar_event_accept_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/maybe_calendar_event_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/maybe_calendar_event_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/calendar_event_reject_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/calendar_event_reject_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/download_attachment_for_web_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/download_attachment_for_web_interactor.dart';
@@ -69,7 +71,6 @@ import 'package:tmail_ui_user/features/email/domain/usecases/download_attachment
import 'package:tmail_ui_user/features/email/domain/usecases/export_attachment_interactor.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/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/domain/usecases/mark_as_email_read_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_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_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/parse_calendar_event_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/parse_calendar_event_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/print_email_interactor.dart'; import 'package:tmail_ui_user/features/email/domain/usecases/print_email_interactor.dart';
@@ -169,6 +170,10 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
CalendarEvent? get calendarEvent => blobCalendarEvent.value?.calendarEventList.firstOrNull; CalendarEvent? get calendarEvent => blobCalendarEvent.value?.calendarEventList.firstOrNull;
Id? get _displayingEventBlobId => blobCalendarEvent.value?.blobId; Id? get _displayingEventBlobId => blobCalendarEvent.value?.blobId;
AccountId? get accountId => mailboxDashBoardController.accountId.value;
Session? get session => mailboxDashBoardController.sessionCurrent;
SingleEmailController( SingleEmailController(
this._getEmailContentInteractor, this._getEmailContentInteractor,
this._markAsEmailReadInteractor, this._markAsEmailReadInteractor,
@@ -206,7 +211,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} else if (success is GetEmailContentFromCacheSuccess) { } else if (success is GetEmailContentFromCacheSuccess) {
_getEmailContentOfflineSuccess(success); _getEmailContentOfflineSuccess(success);
} else if (success is MarkAsEmailReadSuccess) { } else if (success is MarkAsEmailReadSuccess) {
_markAsEmailReadSuccess(success); _handleMarkAsEmailReadCompleted(success.readActions);
} else if (success is ExportAttachmentSuccess) { } else if (success is ExportAttachmentSuccess) {
_exportAttachmentSuccessAction(success); _exportAttachmentSuccessAction(success);
} else if (success is MoveToMailboxSuccess) { } else if (success is MoveToMailboxSuccess) {
@@ -244,7 +249,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
void handleFailureViewState(Failure failure) { void handleFailureViewState(Failure failure) {
super.handleFailureViewState(failure); super.handleFailureViewState(failure);
if (failure is MarkAsEmailReadFailure) { if (failure is MarkAsEmailReadFailure) {
_markAsEmailReadFailure(failure); _handleMarkAsEmailReadCompleted(failure.readActions);
} else if (failure is DownloadAttachmentsFailure) { } else if (failure is DownloadAttachmentsFailure) {
_downloadAttachmentsFailure(failure); _downloadAttachmentsFailure(failure);
} else if (failure is ExportAttachmentFailure) { } else if (failure is ExportAttachmentFailure) {
@@ -267,7 +272,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
ever(mailboxDashBoardController.accountId, (accountId) { ever(mailboxDashBoardController.accountId, (accountId) {
if (accountId is AccountId) { if (accountId is AccountId) {
_injectAndGetInteractorBindings( _injectAndGetInteractorBindings(
mailboxDashBoardController.sessionCurrent, session,
accountId accountId
); );
} }
@@ -421,10 +426,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
void _getAllIdentities() { void _getAllIdentities() {
final accountId = mailboxDashBoardController.accountId.value;
final session = mailboxDashBoardController.sessionCurrent;
if (accountId != null && session != null) { if (accountId != null && session != null) {
consumeState(_getAllIdentitiesInteractor.execute(session, accountId)); consumeState(_getAllIdentitiesInteractor.execute(session!, accountId!));
} }
} }
@@ -477,17 +480,15 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
) )
))); )));
} else { } else {
final session = mailboxDashBoardController.sessionCurrent;
final accountId = mailboxDashBoardController.accountId.value;
if (session != null && accountId != null) { if (session != null && accountId != null) {
final baseDownloadUrl = mailboxDashBoardController.sessionCurrent?.getDownloadUrl(jmapUrl: dynamicUrlInterceptors.jmapUrl) ?? ''; final baseDownloadUrl = session!.getDownloadUrl(jmapUrl: dynamicUrlInterceptors.jmapUrl);
TransformConfiguration transformConfiguration = PlatformInfo.isWeb TransformConfiguration transformConfiguration = PlatformInfo.isWeb
? TransformConfiguration.forPreviewEmailOnWeb() ? TransformConfiguration.forPreviewEmailOnWeb()
: TransformConfiguration.forPreviewEmail(); : TransformConfiguration.forPreviewEmail();
consumeState(_getEmailContentInteractor.execute( consumeState(_getEmailContentInteractor.execute(
session, session!,
accountId, accountId!,
emailId, emailId,
baseDownloadUrl, baseDownloadUrl,
transformConfiguration transformConfiguration
@@ -585,8 +586,8 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
); );
_storeOpenedEmailAction( _storeOpenedEmailAction(
mailboxDashBoardController.sessionCurrent, session,
mailboxDashBoardController.accountId.value, accountId,
detailedEmail detailedEmail
); );
} }
@@ -647,27 +648,24 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
} }
void markAsEmailRead(PresentationEmail presentationEmail, ReadActions readActions, MarkReadAction markReadAction) async { void markAsEmailRead(
final accountId = mailboxDashBoardController.accountId.value; PresentationEmail presentationEmail,
final session = mailboxDashBoardController.sessionCurrent; ReadActions readActions,
MarkReadAction markReadAction,
) {
if (accountId != null && session != null) { if (accountId != null && session != null) {
consumeState(_markAsEmailReadInteractor.execute(session, accountId, presentationEmail.toEmail(), readActions, markReadAction)); consumeState(_markAsEmailReadInteractor.execute(
session!,
accountId!,
presentationEmail.id!,
readActions,
markReadAction,
));
} }
} }
void _markAsEmailReadSuccess(Success success) { void _handleMarkAsEmailReadCompleted(ReadActions readActions) {
log('SingleEmailController::_markAsEmailReadSuccess(): $success'); if (readActions == ReadActions.markAsUnread) {
mailboxDashBoardController.dispatchState(Right(success));
if (success is MarkAsEmailReadSuccess
&& success.readActions == ReadActions.markAsUnread) {
closeEmailView(context: currentContext);
}
}
void _markAsEmailReadFailure(Failure failure) {
if (failure is MarkAsEmailReadFailure
&& failure.readActions == ReadActions.markAsUnread) {
closeEmailView(context: currentContext); closeEmailView(context: currentContext);
} }
} }
@@ -711,11 +709,16 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
} }
void _downloadAttachmentsAction(List<Attachment> attachments) async { void _downloadAttachmentsAction(List<Attachment> attachments) {
final accountId = mailboxDashBoardController.accountId.value; if (accountId != null && session != null) {
if (accountId != null && mailboxDashBoardController.sessionCurrent != null) { final baseDownloadUrl = session!.getDownloadUrl(
final baseDownloadUrl = mailboxDashBoardController.sessionCurrent!.getDownloadUrl(jmapUrl: dynamicUrlInterceptors.jmapUrl); jmapUrl: dynamicUrlInterceptors.jmapUrl,
consumeState(_downloadAttachmentsInteractor.execute(attachments, accountId, baseDownloadUrl)); );
consumeState(_downloadAttachmentsInteractor.execute(
attachments,
accountId!,
baseDownloadUrl,
));
} }
} }
@@ -760,11 +763,17 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
} }
void _exportAttachmentAction(Attachment attachment, CancelToken cancelToken) async { void _exportAttachmentAction(Attachment attachment, CancelToken cancelToken) {
final accountId = mailboxDashBoardController.accountId.value; if (accountId != null && session != null) {
if (accountId != null && mailboxDashBoardController.sessionCurrent != null) { final baseDownloadUrl = session!.getDownloadUrl(
final baseDownloadUrl = mailboxDashBoardController.sessionCurrent!.getDownloadUrl(jmapUrl: dynamicUrlInterceptors.jmapUrl); jmapUrl: dynamicUrlInterceptors.jmapUrl,
consumeState(_exportAttachmentInteractor.execute(attachment, accountId, baseDownloadUrl, cancelToken)); );
consumeState(_exportAttachmentInteractor.execute(
attachment,
accountId!,
baseDownloadUrl,
cancelToken,
));
} }
} }
@@ -807,15 +816,15 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
void downloadAttachmentForWeb(Attachment attachment) { void downloadAttachmentForWeb(Attachment attachment) {
final accountId = mailboxDashBoardController.accountId.value;
final session = mailboxDashBoardController.sessionCurrent;
if (accountId != null && session != null) { if (accountId != null && session != null) {
final baseDownloadUrl = session.getDownloadUrl(jmapUrl: dynamicUrlInterceptors.jmapUrl); final baseDownloadUrl = session!.getDownloadUrl(
jmapUrl: dynamicUrlInterceptors.jmapUrl,
);
final generateTaskId = DownloadTaskId(uuid.v4()); final generateTaskId = DownloadTaskId(uuid.v4());
consumeState(_downloadAttachmentForWebInteractor.execute( consumeState(_downloadAttachmentForWebInteractor.execute(
generateTaskId, generateTaskId,
attachment, attachment,
accountId, accountId!,
baseDownloadUrl, baseDownloadUrl,
_downloadProgressStateController)); _downloadProgressStateController));
} else { } else {
@@ -876,12 +885,10 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
void moveToMailbox(BuildContext context, PresentationEmail email) async { void moveToMailbox(BuildContext context, PresentationEmail email) async {
final currentMailbox = getMailboxContain(email); final currentMailbox = getMailboxContain(email);
final accountId = mailboxDashBoardController.accountId.value;
final session = mailboxDashBoardController.sessionCurrent;
if (currentMailbox != null && accountId != null) { if (currentMailbox != null && accountId != null) {
final arguments = DestinationPickerArguments( final arguments = DestinationPickerArguments(
accountId, accountId!,
MailboxActions.moveEmail, MailboxActions.moveEmail,
session, session,
mailboxIdSelected: currentMailbox.mailboxId mailboxIdSelected: currentMailbox.mailboxId
@@ -893,13 +900,13 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
if (destinationMailbox != null && if (destinationMailbox != null &&
destinationMailbox is PresentationMailbox && destinationMailbox is PresentationMailbox &&
mailboxDashBoardController.sessionCurrent != null && session != null &&
context.mounted context.mounted
) { ) {
_dispatchMoveToAction( _dispatchMoveToAction(
context, context,
accountId, accountId!,
mailboxDashBoardController.sessionCurrent!, session!,
email, email,
currentMailbox, currentMailbox,
destinationMailbox); destinationMailbox);
@@ -978,24 +985,20 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
void _revertedToOriginalMailbox(MoveToMailboxRequest newMoveRequest) { void _revertedToOriginalMailbox(MoveToMailboxRequest newMoveRequest) {
final accountId = mailboxDashBoardController.accountId.value;
final session = mailboxDashBoardController.sessionCurrent;
if (accountId != null && session != null) { if (accountId != null && session != null) {
_moveToMailbox(currentContext!, session, accountId, newMoveRequest); _moveToMailbox(currentContext!, session!, accountId!, newMoveRequest);
} }
} }
void moveToTrash(BuildContext context, PresentationEmail email) async { void moveToTrash(BuildContext context, PresentationEmail email) {
final session = mailboxDashBoardController.sessionCurrent;
final accountId = mailboxDashBoardController.accountId.value;
final trashMailboxId = mailboxDashBoardController.getMailboxIdByRole(PresentationMailbox.roleTrash); final trashMailboxId = mailboxDashBoardController.getMailboxIdByRole(PresentationMailbox.roleTrash);
final currentMailbox = getMailboxContain(email); final currentMailbox = getMailboxContain(email);
if (session != null && accountId != null && currentMailbox != null && trashMailboxId != null) { if (session != null && accountId != null && currentMailbox != null && trashMailboxId != null) {
_moveToTrashAction( _moveToTrashAction(
context, context,
session, session!,
accountId, accountId!,
MoveToMailboxRequest( MoveToMailboxRequest(
{currentMailbox.id: [email.id!]}, {currentMailbox.id: [email.id!]},
trashMailboxId, trashMailboxId,
@@ -1015,17 +1018,15 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
mailboxDashBoardController.moveToMailbox(session, accountId, moveRequest); mailboxDashBoardController.moveToMailbox(session, accountId, moveRequest);
} }
void moveToSpam(BuildContext context, PresentationEmail email) async { void moveToSpam(BuildContext context, PresentationEmail email) {
final session = mailboxDashBoardController.sessionCurrent;
final accountId = mailboxDashBoardController.accountId.value;
final spamMailboxId = mailboxDashBoardController.spamMailboxId; final spamMailboxId = mailboxDashBoardController.spamMailboxId;
final currentMailbox = getMailboxContain(email); final currentMailbox = getMailboxContain(email);
if (session != null && accountId != null && currentMailbox != null && spamMailboxId != null) { if (session != null && accountId != null && currentMailbox != null && spamMailboxId != null) {
_moveToSpamAction( _moveToSpamAction(
context, context,
session, session!,
accountId, accountId!,
MoveToMailboxRequest( MoveToMailboxRequest(
{currentMailbox.id: [email.id!]}, {currentMailbox.id: [email.id!]},
spamMailboxId, spamMailboxId,
@@ -1035,17 +1036,15 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
} }
void unSpam(BuildContext context, PresentationEmail email) async { void unSpam(BuildContext context, PresentationEmail email) {
final session = mailboxDashBoardController.sessionCurrent;
final accountId = mailboxDashBoardController.accountId.value;
final spamMailboxId = mailboxDashBoardController.spamMailboxId; final spamMailboxId = mailboxDashBoardController.spamMailboxId;
final inboxMailboxId = mailboxDashBoardController.getMailboxIdByRole(PresentationMailbox.roleInbox); final inboxMailboxId = mailboxDashBoardController.getMailboxIdByRole(PresentationMailbox.roleInbox);
if (session != null && accountId != null && spamMailboxId != null && inboxMailboxId != null) { if (session != null && accountId != null && spamMailboxId != null && inboxMailboxId != null) {
_moveToSpamAction( _moveToSpamAction(
context, context,
session, session!,
accountId, accountId!,
MoveToMailboxRequest( MoveToMailboxRequest(
{spamMailboxId: [email.id!]}, {spamMailboxId: [email.id!]},
inboxMailboxId, inboxMailboxId,
@@ -1065,18 +1064,25 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
mailboxDashBoardController.moveToMailbox(session, accountId, moveRequest); mailboxDashBoardController.moveToMailbox(session, accountId, moveRequest);
} }
void markAsStarEmail(PresentationEmail presentationEmail, MarkStarAction markStarAction) async { void markAsStarEmail(
final accountId = mailboxDashBoardController.accountId.value; PresentationEmail presentationEmail,
final session = mailboxDashBoardController.sessionCurrent; MarkStarAction markStarAction,
) {
if (accountId != null && session != null) { if (accountId != null && session != null) {
consumeState(_markAsStarEmailInteractor.execute(session, accountId, presentationEmail.toEmail(), markStarAction)); consumeState(_markAsStarEmailInteractor.execute(
session!,
accountId!,
presentationEmail.id!,
markStarAction,
));
} }
} }
void _markAsEmailStarSuccess(MarkAsStarEmailSuccess success) { void _markAsEmailStarSuccess(MarkAsStarEmailSuccess success) {
final selectedEmail = mailboxDashBoardController.selectedEmail.value; final newEmail = currentEmail?.updateKeywords({
mailboxDashBoardController.setSelectedEmail(selectedEmail?.updateKeywords(success.updatedEmail.keywords)); KeyWordIdentifier.emailFlagged: true,
mailboxDashBoardController.dispatchState(Right(success)); });
mailboxDashBoardController.setSelectedEmail(newEmail);
} }
void handleEmailAction(BuildContext context, PresentationEmail presentationEmail, EmailActionType actionType) { void handleEmailAction(BuildContext context, PresentationEmail presentationEmail, EmailActionType actionType) {
@@ -1210,8 +1216,6 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
void _handleSendReceiptToSenderAction(BuildContext context) { void _handleSendReceiptToSenderAction(BuildContext context) {
final accountId = mailboxDashBoardController.accountId.value;
final session = mailboxDashBoardController.sessionCurrent;
if (accountId == null || session == null) { if (accountId == null || session == null) {
return; return;
} }
@@ -1237,7 +1241,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
return; return;
} }
final receiverEmailAddress = _getReceiverEmailAddress(currentEmail!) ?? session.username.value; final receiverEmailAddress = _getReceiverEmailAddress(currentEmail!) ?? session!.username.value;
log('SingleEmailController::_handleSendReceiptToSenderAction():receiverEmailAddress: $receiverEmailAddress'); log('SingleEmailController::_handleSendReceiptToSenderAction():receiverEmailAddress: $receiverEmailAddress');
final mdnToSender = _generateMDN(context, currentEmail!, receiverEmailAddress); final mdnToSender = _generateMDN(context, currentEmail!, receiverEmailAddress);
final sendReceiptRequest = SendReceiptToSenderRequest( final sendReceiptRequest = SendReceiptToSenderRequest(
@@ -1246,7 +1250,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
sendId: Id(uuid.v1())); sendId: Id(uuid.v1()));
log('SingleEmailController::_handleSendReceiptToSenderAction(): sendReceiptRequest: $sendReceiptRequest'); log('SingleEmailController::_handleSendReceiptToSenderAction(): sendReceiptRequest: $sendReceiptRequest');
consumeState(_sendReceiptToSenderInteractor!.execute(accountId, sendReceiptRequest)); consumeState(_sendReceiptToSenderInteractor!.execute(accountId!, sendReceiptRequest));
} }
String? _getReceiverEmailAddress(PresentationEmail presentationEmail) { String? _getReceiverEmailAddress(PresentationEmail presentationEmail) {
@@ -1395,12 +1399,10 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
void quickCreatingRule(BuildContext context, EmailAddress emailAddress) async { void quickCreatingRule(BuildContext context, EmailAddress emailAddress) async {
popBack(); popBack();
final accountId = mailboxDashBoardController.accountId.value;
final session = mailboxDashBoardController.sessionCurrent;
if (accountId != null && session != null) { if (accountId != null && session != null) {
final arguments = RulesFilterCreatorArguments( final arguments = RulesFilterCreatorArguments(
accountId, accountId!,
session, session!,
emailAddress: emailAddress); emailAddress: emailAddress);
final newRuleFilterRequest = PlatformInfo.isWeb final newRuleFilterRequest = PlatformInfo.isWeb
@@ -1408,7 +1410,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
: await push(AppRoutes.rulesFilterCreator, arguments: arguments); : await push(AppRoutes.rulesFilterCreator, arguments: arguments);
if (newRuleFilterRequest is CreateNewEmailRuleFilterRequest) { if (newRuleFilterRequest is CreateNewEmailRuleFilterRequest) {
_createNewRuleFilterAction(accountId, newRuleFilterRequest); _createNewRuleFilterAction(accountId!, newRuleFilterRequest);
} }
} }
} }
@@ -1460,11 +1462,9 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
bool get _isCalendarEventSupported { bool get _isCalendarEventSupported {
final accountId = mailboxDashBoardController.accountId.value;
final session = mailboxDashBoardController.sessionCurrent;
return session != null && return session != null &&
accountId != null && accountId != null &&
CapabilityIdentifier.jamesCalendarEvent.isSupported(session, accountId); CapabilityIdentifier.jamesCalendarEvent.isSupported(session!, accountId!);
} }
@visibleForTesting @visibleForTesting
@@ -1690,21 +1690,21 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
void _acceptCalendarEventAction(EmailId emailId) { void _acceptCalendarEventAction(EmailId emailId) {
if (_acceptCalendarEventInteractor == null if (_acceptCalendarEventInteractor == null
|| _displayingEventBlobId == null || _displayingEventBlobId == null
|| mailboxDashBoardController.accountId.value == null || accountId == null
|| mailboxDashBoardController.sessionCurrent == null || session == null
|| mailboxDashBoardController.sessionCurrent || session!.validateCalendarEventCapability(accountId!).isAvailable == false
!.validateCalendarEventCapability(mailboxDashBoardController.accountId.value!)
.isAvailable == false
) { ) {
consumeState(Stream.value(Left(CalendarEventAcceptFailure()))); consumeState(Stream.value(Left(CalendarEventAcceptFailure())));
} else { } else {
consumeState(_acceptCalendarEventInteractor!.execute( consumeState(_acceptCalendarEventInteractor!.execute(
mailboxDashBoardController.accountId.value!, accountId!,
{_displayingEventBlobId!}, {_displayingEventBlobId!},
emailId, emailId,
mailboxDashBoardController.sessionCurrent!.getLanguageForCalendarEvent( session!.getLanguageForCalendarEvent(
LocalizationService.getLocaleFromLanguage(), LocalizationService.getLocaleFromLanguage(),
mailboxDashBoardController.accountId.value!))); accountId!,
),
));
} }
} }
@@ -1768,10 +1768,10 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
} }
void _showToastMessageEventAttendanceSuccess(StoreEventAttendanceStatusSuccess success) { void _showToastMessageEventAttendanceSuccess(StoreEventAttendanceStatusSuccess success) {
final selectedEmail = mailboxDashBoardController.selectedEmail.value; final newEmail = currentEmail?.updateKeywords(
final newEmail = selectedEmail?.updateKeywords(success.updatedEmail.keywords); success.eventActionType.getMapKeywords(),
);
mailboxDashBoardController.setSelectedEmail(newEmail); mailboxDashBoardController.setSelectedEmail(newEmail);
mailboxDashBoardController.dispatchState(Right(success));
if (currentOverlayContext == null || currentContext == null) { if (currentOverlayContext == null || currentContext == null) {
return; return;
@@ -38,7 +38,7 @@ abstract class MailboxDataSource {
Future<bool> moveMailbox(Session session, AccountId accountId, MoveMailboxRequest request); Future<bool> moveMailbox(Session session, AccountId accountId, MoveMailboxRequest request);
Future<List<Email>> markAsMailboxRead( Future<List<EmailId>> markAsMailboxRead(
Session session, Session session,
AccountId accountId, AccountId accountId,
MailboxId mailboxId, MailboxId mailboxId,
@@ -78,7 +78,7 @@ class MailboxCacheDataSourceImpl extends MailboxDataSource {
} }
@override @override
Future<List<Email>> markAsMailboxRead( Future<List<EmailId>> markAsMailboxRead(
Session session, Session session,
AccountId accountId, AccountId accountId,
MailboxId mailboxId, MailboxId mailboxId,
@@ -87,7 +87,7 @@ class MailboxDataSourceImpl extends MailboxDataSource {
} }
@override @override
Future<List<Email>> markAsMailboxRead( Future<List<EmailId>> markAsMailboxRead(
Session session, Session session,
AccountId accountId, AccountId accountId,
MailboxId mailboxId, MailboxId mailboxId,
@@ -19,6 +19,7 @@ import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/email/email_property.dart'; import 'package:model/email/email_property.dart';
import 'package:model/email/read_actions.dart'; import 'package:model/email/read_actions.dart';
import 'package:model/extensions/list_email_extension.dart';
import 'package:tmail_ui_user/features/base/isolate/background_isolate_binary_messenger/background_isolate_binary_messenger.dart'; import 'package:tmail_ui_user/features/base/isolate/background_isolate_binary_messenger/background_isolate_binary_messenger.dart';
import 'package:tmail_ui_user/features/caching/config/hive_cache_config.dart'; import 'package:tmail_ui_user/features/caching/config/hive_cache_config.dart';
import 'package:tmail_ui_user/features/email/data/network/email_api.dart'; import 'package:tmail_ui_user/features/email/data/network/email_api.dart';
@@ -37,7 +38,7 @@ class MailboxIsolateWorker {
MailboxIsolateWorker(this._threadApi, this._emailApi, this._isolateExecutor); MailboxIsolateWorker(this._threadApi, this._emailApi, this._isolateExecutor);
Future<List<Email>> markAsMailboxRead( Future<List<EmailId>> markAsMailboxRead(
Session session, Session session,
AccountId accountId, AccountId accountId,
MailboxId mailboxId, MailboxId mailboxId,
@@ -80,7 +81,7 @@ class MailboxIsolateWorker {
} }
} }
static Future<List<Email>> _handleMarkAsMailboxReadAction( static Future<List<EmailId>> _handleMarkAsMailboxReadAction(
MailboxMarkAsReadArguments args, MailboxMarkAsReadArguments args,
TypeSendPort sendPort TypeSendPort sendPort
) async { ) async {
@@ -88,7 +89,7 @@ class MailboxIsolateWorker {
BackgroundIsolateBinaryMessenger.ensureInitialized(rootIsolateToken); BackgroundIsolateBinaryMessenger.ensureInitialized(rootIsolateToken);
await HiveCacheConfig.instance.setUp(); await HiveCacheConfig.instance.setUp();
List<Email> emailListCompleted = List.empty(growable: true); List<EmailId> emailIdsCompleted = List.empty(growable: true);
try { try {
bool mailboxHasEmails = true; bool mailboxHasEmails = true;
UTCDate? lastReceivedDate; UTCDate? lastReceivedDate;
@@ -134,29 +135,29 @@ class MailboxIsolateWorker {
final result = await args.emailAPI.markAsRead( final result = await args.emailAPI.markAsRead(
args.session, args.session,
args.accountId, args.accountId,
listEmailUnread, listEmailUnread.listEmailIds,
ReadActions.markAsRead); ReadActions.markAsRead);
log('MailboxIsolateWorker::_handleMarkAsMailboxRead(): MARK_READ: ${result.length}'); log('MailboxIsolateWorker::_handleMarkAsMailboxRead(): MARK_READ: ${result.length}');
emailListCompleted.addAll(result); emailIdsCompleted.addAll(result);
sendPort.send(emailListCompleted); sendPort.send(emailIdsCompleted);
} }
} }
} catch (e) { } catch (e) {
log('MailboxIsolateWorker::_handleMarkAsMailboxRead(): ERROR: $e'); log('MailboxIsolateWorker::_handleMarkAsMailboxRead(): ERROR: $e');
} }
log('MailboxIsolateWorker::_handleMarkAsMailboxRead(): TOTAL_READ: ${emailListCompleted.length}'); log('MailboxIsolateWorker::_handleMarkAsMailboxRead(): TOTAL_READ: ${emailIdsCompleted.length}');
return emailListCompleted; return emailIdsCompleted;
} }
Future<List<Email>> _handleMarkAsMailboxReadActionOnWeb( Future<List<EmailId>> _handleMarkAsMailboxReadActionOnWeb(
Session session, Session session,
AccountId accountId, AccountId accountId,
MailboxId mailboxId, MailboxId mailboxId,
int totalEmailUnread, int totalEmailUnread,
StreamController<Either<Failure, Success>> onProgressController StreamController<Either<Failure, Success>> onProgressController
) async { ) async {
List<Email> emailListCompleted = List.empty(growable: true); List<EmailId> emailIdsCompleted = List.empty(growable: true);
try { try {
bool mailboxHasEmails = true; bool mailboxHasEmails = true;
UTCDate? lastReceivedDate; UTCDate? lastReceivedDate;
@@ -199,20 +200,25 @@ class MailboxIsolateWorker {
lastEmailId = listEmailUnread.last.id; lastEmailId = listEmailUnread.last.id;
lastReceivedDate = listEmailUnread.last.receivedAt; lastReceivedDate = listEmailUnread.last.receivedAt;
final result = await _emailApi.markAsRead(session, accountId, listEmailUnread, ReadActions.markAsRead); final result = await _emailApi.markAsRead(
session,
accountId,
listEmailUnread.listEmailIds,
ReadActions.markAsRead,
);
log('MailboxIsolateWorker::_handleMarkAsMailboxReadActionOnWeb(): MARK_READ: ${result.length}'); log('MailboxIsolateWorker::_handleMarkAsMailboxReadActionOnWeb(): MARK_READ: ${result.length}');
emailListCompleted.addAll(result); emailIdsCompleted.addAll(result);
onProgressController.add(Right(UpdatingMarkAsMailboxReadState( onProgressController.add(Right(UpdatingMarkAsMailboxReadState(
mailboxId: mailboxId, mailboxId: mailboxId,
totalUnread: totalEmailUnread, totalUnread: totalEmailUnread,
countRead: emailListCompleted.length))); countRead: emailIdsCompleted.length)));
} }
} }
} catch (e) { } catch (e) {
log('MailboxIsolateWorker::_handleMarkAsMailboxReadActionOnWeb(): ERROR: $e'); log('MailboxIsolateWorker::_handleMarkAsMailboxReadActionOnWeb(): ERROR: $e');
} }
log('MailboxIsolateWorker::_handleMarkAsMailboxReadActionOnWeb(): TOTAL_READ: ${emailListCompleted.length}'); log('MailboxIsolateWorker::_handleMarkAsMailboxReadActionOnWeb(): TOTAL_READ: ${emailIdsCompleted.length}');
return emailListCompleted; return emailIdsCompleted;
} }
} }
@@ -216,7 +216,7 @@ class MailboxRepositoryImpl extends MailboxRepository {
} }
@override @override
Future<List<Email>> markAsMailboxRead( Future<List<EmailId>> markAsMailboxRead(
Session session, Session session,
AccountId accountId, AccountId accountId,
MailboxId mailboxId, MailboxId mailboxId,
@@ -31,7 +31,7 @@ abstract class MailboxRepository {
Future<bool> renameMailbox(Session session, AccountId accountId, RenameMailboxRequest request); Future<bool> renameMailbox(Session session, AccountId accountId, RenameMailboxRequest request);
Future<List<Email>> markAsMailboxRead( Future<List<EmailId>> markAsMailboxRead(
Session session, Session session,
AccountId accountId, AccountId accountId,
MailboxId mailboxId, MailboxId mailboxId,
@@ -362,12 +362,20 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
} }
} else if (success is UpdateVacationSuccess) { } else if (success is UpdateVacationSuccess) {
_handleUpdateVacationSuccess(success); _handleUpdateVacationSuccess(success);
} else if (success is MarkAsMultipleEmailReadAllSuccess || } else if (success is MarkAsMultipleEmailReadAllSuccess) {
success is MarkAsMultipleEmailReadHasSomeEmailFailure) { _markAsReadSelectedMultipleEmailSuccess(success.readActions);
_markAsReadSelectedMultipleEmailSuccess(success); } else if (success is MarkAsMultipleEmailReadHasSomeEmailFailure) {
} else if (success is MarkAsStarMultipleEmailAllSuccess || _markAsReadSelectedMultipleEmailSuccess(success.readActions);
success is MarkAsStarMultipleEmailHasSomeEmailFailure) { } else if (success is MarkAsStarMultipleEmailAllSuccess) {
_markAsStarMultipleEmailSuccess(success); _markAsStarMultipleEmailSuccess(
success.markStarAction,
success.countMarkStarSuccess,
);
} else if (success is MarkAsStarMultipleEmailHasSomeEmailFailure) {
_markAsStarMultipleEmailSuccess(
success.markStarAction,
success.countMarkStarSuccess,
);
} else if (success is MoveMultipleEmailToMailboxAllSuccess || } else if (success is MoveMultipleEmailToMailboxAllSuccess ||
success is MoveMultipleEmailToMailboxHasSomeEmailFailure) { success is MoveMultipleEmailToMailboxHasSomeEmailFailure) {
_moveSelectedMultipleEmailToMailboxSuccess(success); _moveSelectedMultipleEmailToMailboxSuccess(success);
@@ -867,14 +875,19 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
} }
} }
void markAsEmailRead(PresentationEmail presentationEmail, ReadActions readActions, MarkReadAction markReadAction) async { void markAsEmailRead(
EmailId emailId,
ReadActions readActions,
MarkReadAction markReadAction,
) {
if (accountId.value != null && sessionCurrent != null) { if (accountId.value != null && sessionCurrent != null) {
consumeState(_markAsEmailReadInteractor.execute( consumeState(_markAsEmailReadInteractor.execute(
sessionCurrent!, sessionCurrent!,
accountId.value!, accountId.value!,
presentationEmail.toEmail(), emailId,
readActions, readActions,
markReadAction)); markReadAction,
));
} }
} }
@@ -883,35 +896,34 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
consumeState(_markAsStarEmailInteractor.execute( consumeState(_markAsStarEmailInteractor.execute(
sessionCurrent!, sessionCurrent!,
accountId.value!, accountId.value!,
presentationEmail.toEmail(), presentationEmail.id!,
action)); action));
} }
} }
void markAsReadSelectedMultipleEmail(List<PresentationEmail> listPresentationEmail, ReadActions readActions) { void markAsReadSelectedMultipleEmail(List<PresentationEmail> listPresentationEmail, ReadActions readActions) {
final listEmail = listPresentationEmail final listEmailNeedMarkAsRead = listPresentationEmail
.map((presentationEmail) => presentationEmail.toEmail()) .where((email) {
.toList(); if (readActions == ReadActions.markAsUnread) {
log('MailboxDashBoardController::markAsReadSelectedMultipleEmail(): listEmail: ${listEmail.length}'); return email.hasRead;
} else {
return !email.hasRead;
}
})
.toList();
if (accountId.value != null && sessionCurrent != null) { if (accountId.value != null && sessionCurrent != null) {
consumeState(_markAsMultipleEmailReadInteractor.execute( consumeState(_markAsMultipleEmailReadInteractor.execute(
sessionCurrent!, sessionCurrent!,
accountId.value!, accountId.value!,
listEmail, listEmailNeedMarkAsRead.listEmailIds,
readActions)); readActions,
));
} }
} }
void _markAsReadSelectedMultipleEmailSuccess(Success success) { void _markAsReadSelectedMultipleEmailSuccess(ReadActions readActions) {
ReadActions? readActions; if (currentContext != null && currentOverlayContext != null) {
if (success is MarkAsMultipleEmailReadAllSuccess) {
readActions = success.readActions;
} else if (success is MarkAsMultipleEmailReadHasSomeEmailFailure) {
readActions = success.readActions;
}
if (readActions != null && currentContext != null && currentOverlayContext != null) {
final message = readActions == ReadActions.markAsUnread final message = readActions == ReadActions.markAsUnread
? AppLocalizations.of(currentContext!).marked_message_toast(AppLocalizations.of(currentContext!).unread) ? AppLocalizations.of(currentContext!).marked_message_toast(AppLocalizations.of(currentContext!).unread)
: AppLocalizations.of(currentContext!).marked_message_toast(AppLocalizations.of(currentContext!).read); : AppLocalizations.of(currentContext!).marked_message_toast(AppLocalizations.of(currentContext!).read);
@@ -926,30 +938,24 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
} }
} }
void _markAsReadEmailSuccess(Success success) { void _markAsReadEmailSuccess(MarkAsEmailReadSuccess success) {
ReadActions? readActions; if (currentContext != null &&
MarkReadAction? markReadAction; currentOverlayContext != null &&
PresentationEmail? presentationEmail; success.markReadAction == MarkReadAction.swipeOnThread) {
final message = success.readActions == ReadActions.markAsUnread
if (success is MarkAsEmailReadSuccess) {
readActions = success.readActions;
markReadAction = success.markReadAction;
presentationEmail = success.updatedEmail.toPresentationEmail();
}
if (readActions != null && currentContext != null && currentOverlayContext != null && markReadAction == MarkReadAction.swipeOnThread) {
final message = readActions == ReadActions.markAsUnread
? AppLocalizations.of(currentContext!).markedSingleMessageToast(AppLocalizations.of(currentContext!).unread.toLowerCase()) ? AppLocalizations.of(currentContext!).markedSingleMessageToast(AppLocalizations.of(currentContext!).unread.toLowerCase())
: AppLocalizations.of(currentContext!).markedSingleMessageToast(AppLocalizations.of(currentContext!).read.toLowerCase()); : AppLocalizations.of(currentContext!).markedSingleMessageToast(AppLocalizations.of(currentContext!).read.toLowerCase());
final undoAction = readActions == ReadActions.markAsUnread ? ReadActions.markAsRead : ReadActions.markAsUnread; final undoAction = success.readActions == ReadActions.markAsUnread
? ReadActions.markAsRead
: ReadActions.markAsUnread;
appToast.showToastMessage( appToast.showToastMessage(
currentOverlayContext!, currentOverlayContext!,
message, message,
actionName: AppLocalizations.of(currentContext!).undo, actionName: AppLocalizations.of(currentContext!).undo,
onActionClick: () { onActionClick: () {
markAsEmailRead(presentationEmail!, undoAction, MarkReadAction.undo); markAsEmailRead(success.emailId, undoAction, MarkReadAction.undo);
}, },
leadingSVGIcon: imagePaths.icToastSuccessMessage, leadingSVGIcon: imagePaths.icToastSuccessMessage,
backgroundColor: AppColor.toastSuccessBackgroundColor, backgroundColor: AppColor.toastSuccessBackgroundColor,
@@ -960,43 +966,42 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
} }
void markAsStarSelectedMultipleEmail(List<PresentationEmail> listPresentationEmail, MarkStarAction markStarAction) { void markAsStarSelectedMultipleEmail(List<PresentationEmail> listPresentationEmail, MarkStarAction markStarAction) {
final listEmail = listPresentationEmail
.map((presentationEmail) => presentationEmail.toEmail())
.toList();
if (accountId.value != null && sessionCurrent != null) { if (accountId.value != null && sessionCurrent != null) {
final listEmailIds = listPresentationEmail
.where((email) {
if (markStarAction == MarkStarAction.unMarkStar) {
return email.hasStarred;
} else {
return !email.hasStarred;
}
})
.toList()
.listEmailIds;
consumeState(_markAsStarMultipleEmailInteractor.execute( consumeState(_markAsStarMultipleEmailInteractor.execute(
sessionCurrent!, sessionCurrent!,
accountId.value!, accountId.value!,
listEmail, listEmailIds,
markStarAction)); markStarAction));
} }
} }
void _markAsStarMultipleEmailSuccess(Success success) { void _markAsStarMultipleEmailSuccess(
MarkStarAction? markStarAction; MarkStarAction markStarAction,
int countMarkStarSuccess = 0; int countMarkStarSuccess,
) {
if (success is MarkAsStarMultipleEmailAllSuccess) { if (currentOverlayContext != null && currentContext != null) {
markStarAction = success.markStarAction;
countMarkStarSuccess = success.countMarkStarSuccess;
} else if (success is MarkAsStarMultipleEmailHasSomeEmailFailure) {
markStarAction = success.markStarAction;
countMarkStarSuccess = success.countMarkStarSuccess;
}
if (markStarAction != null) {
final message = markStarAction == MarkStarAction.unMarkStar final message = markStarAction == MarkStarAction.unMarkStar
? AppLocalizations.of(currentContext!).marked_unstar_multiple_item(countMarkStarSuccess) ? AppLocalizations.of(currentContext!).marked_unstar_multiple_item(countMarkStarSuccess)
: AppLocalizations.of(currentContext!).marked_star_multiple_item(countMarkStarSuccess); : AppLocalizations.of(currentContext!).marked_star_multiple_item(countMarkStarSuccess);
if (currentOverlayContext != null && currentContext != null) { appToast.showToastMessage(
appToast.showToastMessage( currentOverlayContext!,
currentOverlayContext!, message,
message, leadingSVGIcon: markStarAction == MarkStarAction.unMarkStar
leadingSVGIcon: markStarAction == MarkStarAction.unMarkStar ? imagePaths.icUnStar
? imagePaths.icUnStar : imagePaths.icStar,
: imagePaths.icStar); );
}
} }
} }
@@ -17,7 +17,7 @@ class MarkAsMultipleEmailReadInteractor {
Stream<Either<Failure, Success>> execute( Stream<Either<Failure, Success>> execute(
Session session, Session session,
AccountId accountId, AccountId accountId,
List<Email> emails, List<EmailId> emailIds,
ReadActions readAction ReadActions readAction
) async* { ) async* {
try { try {
@@ -31,25 +31,24 @@ class MarkAsMultipleEmailReadInteractor {
final currentMailboxState = listState.first; final currentMailboxState = listState.first;
final currentEmailState = listState.last; final currentEmailState = listState.last;
final listEmailNeedMarkAsRead = emails final result = await _emailRepository.markAsRead(
.where((email) => readAction == ReadActions.markAsUnread ? email.hasRead : !email.hasRead) session,
.toList(); accountId,
emailIds,
readAction,
);
final result = await _emailRepository.markAsRead(session, accountId, listEmailNeedMarkAsRead, readAction); if (emailIds.length == result.length) {
if (listEmailNeedMarkAsRead.length == result.length) {
final countMarkAsReadSuccess = emails.length;
yield Right(MarkAsMultipleEmailReadAllSuccess( yield Right(MarkAsMultipleEmailReadAllSuccess(
countMarkAsReadSuccess, result.length,
readAction, readAction,
currentEmailState: currentEmailState, currentEmailState: currentEmailState,
currentMailboxState: currentMailboxState)); currentMailboxState: currentMailboxState));
} else if (result.isEmpty) { } else if (result.isEmpty) {
yield Left(MarkAsMultipleEmailReadAllFailure(readAction)); yield Left(MarkAsMultipleEmailReadAllFailure(readAction));
} else { } else {
final countMarkAsReadSuccess = emails.length - (listEmailNeedMarkAsRead.length - result.length);
yield Right(MarkAsMultipleEmailReadHasSomeEmailFailure( yield Right(MarkAsMultipleEmailReadHasSomeEmailFailure(
countMarkAsReadSuccess, result.length,
readAction, readAction,
currentEmailState: currentEmailState, currentEmailState: currentEmailState,
currentMailboxState: currentMailboxState)); currentMailboxState: currentMailboxState));
@@ -1,4 +1,5 @@
import 'package:core/core.dart'; import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/account_id.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/core/session/session.dart';
@@ -15,7 +16,7 @@ class MarkAsStarMultipleEmailInteractor {
Stream<Either<Failure, Success>> execute( Stream<Either<Failure, Success>> execute(
Session session, Session session,
AccountId accountId, AccountId accountId,
List<Email> emails, List<EmailId> emailIds,
MarkStarAction markStarAction MarkStarAction markStarAction
) async* { ) async* {
try { try {
@@ -23,24 +24,18 @@ class MarkAsStarMultipleEmailInteractor {
final currentEmailState = await _emailRepository.getEmailState(session, accountId); final currentEmailState = await _emailRepository.getEmailState(session, accountId);
final listEmailNeedMarkStar = emails final result = await _emailRepository.markAsStar(session, accountId, emailIds, markStarAction);
.where((email) => markStarAction == MarkStarAction.unMarkStar ? email.hasStarred : !email.hasStarred)
.toList();
final result = await _emailRepository.markAsStar(session, accountId, listEmailNeedMarkStar, markStarAction); if (emailIds.length == result.length) {
if (listEmailNeedMarkStar.length == result.length) {
final countMarkStarSuccess = emails.length;
yield Right(MarkAsStarMultipleEmailAllSuccess( yield Right(MarkAsStarMultipleEmailAllSuccess(
countMarkStarSuccess, emailIds.length,
markStarAction, markStarAction,
currentEmailState: currentEmailState)); currentEmailState: currentEmailState));
} else if (result.isEmpty) { } else if (result.isEmpty) {
yield Left(MarkAsStarMultipleEmailAllFailure(markStarAction)); yield Left(MarkAsStarMultipleEmailAllFailure(markStarAction));
} else { } else {
final countMarkStarSuccess = emails.length - (listEmailNeedMarkStar.length - result.length);
yield Right(MarkAsStarMultipleEmailHasSomeEmailFailure( yield Right(MarkAsStarMultipleEmailHasSomeEmailFailure(
countMarkStarSuccess, result.length,
markStarAction, markStarAction,
currentEmailState: currentEmailState)); currentEmailState: currentEmailState));
} }
@@ -224,8 +224,16 @@ mixin EmailActionController {
mailboxDashBoardController.deleteEmailPermanently(email); mailboxDashBoardController.deleteEmailPermanently(email);
} }
void markAsEmailRead(PresentationEmail presentationEmail, ReadActions readActions, MarkReadAction markReadAction) async { void markAsEmailRead(
mailboxDashBoardController.markAsEmailRead(presentationEmail, readActions, markReadAction); PresentationEmail presentationEmail,
ReadActions readActions,
MarkReadAction markReadAction,
) {
mailboxDashBoardController.markAsEmailRead(
presentationEmail.id!,
readActions,
markReadAction,
);
} }
void markAsStarEmail(PresentationEmail presentationEmail, MarkStarAction action) { void markAsStarEmail(PresentationEmail presentationEmail, MarkStarAction action) {
@@ -217,11 +217,14 @@ extension PresentationEmailExtension on PresentationEmail {
..searchSnippetPreview = searchSnippetPreview; ..searchSnippetPreview = searchSnippetPreview;
} }
PresentationEmail updateKeywords(Map<KeyWordIdentifier, bool>? newKeywords) { PresentationEmail updateKeywords(Map<KeyWordIdentifier, bool> newKeywords) {
final combinedMap = {...(keywords ?? {}), ...newKeywords};
combinedMap.removeWhere((key, value) => !value);
log('PresentationEmailExtension::updateKeywords:combinedMap = $combinedMap');
return PresentationEmail( return PresentationEmail(
id: this.id, id: this.id,
blobId: blobId, blobId: blobId,
keywords: newKeywords, keywords: combinedMap,
size: size, size: size,
receivedAt: receivedAt, receivedAt: receivedAt,
hasAttachment: hasAttachment, hasAttachment: hasAttachment,
@@ -60,7 +60,6 @@ void main() {
Right(StoreEventAttendanceStatusLoading()), Right(StoreEventAttendanceStatusLoading()),
Right(StoreEventAttendanceStatusSuccess( Right(StoreEventAttendanceStatusSuccess(
eventActionType, eventActionType,
updatedEmail,
currentEmailState: currentEmailState)), currentEmailState: currentEmailState)),
]), ]),
); );
@@ -4,22 +4,22 @@ import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/utils/app_toast.dart'; import 'package:core/presentation/utils/app_toast.dart';
import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/utils/application_manager.dart'; import 'package:core/utils/application_manager.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart' hide State;
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/core/id.dart'; import 'package:jmap_dart_client/jmap/core/id.dart';
import 'package:jmap_dart_client/jmap/core/state.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart'; import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart'; import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart'; import 'package:jmap_dart_client/jmap/mail/email/keyword_identifier.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart'; import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:mockito/annotations.dart'; import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import 'package:model/email/mark_star_action.dart';
import 'package:model/email/presentation_email.dart'; import 'package:model/email/presentation_email.dart';
import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:model/mailbox/select_mode.dart'; import 'package:model/mailbox/select_mode.dart';
import 'package:tmail_ui_user/features/caching/caching_manager.dart'; import 'package:tmail_ui_user/features/caching/caching_manager.dart';
import 'package:tmail_ui_user/features/email/domain/state/mark_as_email_star_state.dart'; import 'package:tmail_ui_user/features/email/presentation/action/email_ui_action.dart';
import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart'; import 'package:tmail_ui_user/features/email/presentation/utils/email_utils.dart';
import 'package:tmail_ui_user/features/login/data/network/interceptors/authorization_interceptors.dart'; import 'package:tmail_ui_user/features/login/data/network/interceptors/authorization_interceptors.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/delete_authority_oidc_interactor.dart'; import 'package:tmail_ui_user/features/login/domain/usecases/delete_authority_oidc_interactor.dart';
@@ -266,10 +266,6 @@ void main() {
'AND `mailboxDashBoardController.emailsInCurrentMailbox` should not be cleared', 'AND `mailboxDashBoardController.emailsInCurrentMailbox` should not be cleared',
() async { () async {
// Arrange // Arrange
final updatedEmail = Email(
id: EmailId(Id('email1')),
keywords: {KeyWordIdentifier.emailFlagged: true}
);
final emailList = [ final emailList = [
PresentationEmail( PresentationEmail(
id: EmailId(Id('email1')), id: EmailId(Id('email1')),
@@ -308,10 +304,8 @@ void main() {
// Act // Act
threadController.onInit(); threadController.onInit();
final markAsStarEmailSuccess = MarkAsStarEmailSuccess( mockMailboxDashBoardController.emailUIAction.value =
updatedEmail, RefreshChangeEmailAction(State('new-state'));
MarkStarAction.markStar);
mockMailboxDashBoardController.viewState.value = Right(markAsStarEmailSuccess);
await untilCalled(mockSearchEmailInteractor.execute( await untilCalled(mockSearchEmailInteractor.execute(
any, any,