Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PART-1] TF-2646 Enable selection all emails in mailbox #2842

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions contact/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -659,8 +659,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: main
resolved-ref: bb4ffba9e3aba2cbb60c1173663abf975b521199
ref: add-reference-destroy-property
resolved-ref: "1700754235ac124a55f90c38b81c2bfc661fc3b8"
url: "https://github.com/linagora/jmap-dart-client.git"
source: git
version: "0.3.0"
Expand Down
2 changes: 1 addition & 1 deletion contact/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ dependencies:
jmap_dart_client:
git:
url: https://github.com/linagora/jmap-dart-client.git
ref: main
ref: add-reference-destroy-property

### Dependencies from pub.dev ###
equatable: 2.0.5
Expand Down
1 change: 0 additions & 1 deletion core/lib/presentation/resources/assets_paths.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
class AssetsPaths {
static const images = 'assets/images/';
static const icons = 'assets/icons/';
static const configurationImages = 'configurations/icons/';
}
4 changes: 2 additions & 2 deletions email_recovery/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: main
resolved-ref: bb4ffba9e3aba2cbb60c1173663abf975b521199
ref: add-reference-destroy-property
resolved-ref: "1700754235ac124a55f90c38b81c2bfc661fc3b8"
url: "https://github.com/linagora/jmap-dart-client.git"
source: git
version: "0.3.0"
Expand Down
2 changes: 1 addition & 1 deletion email_recovery/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ dependencies:
jmap_dart_client:
git:
url: https://github.com/linagora/jmap-dart-client.git
ref: main
ref: add-reference-destroy-property

### Dependencies from pub.dev ###
equatable: 2.0.5
Expand Down
4 changes: 2 additions & 2 deletions fcm/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: main
resolved-ref: bb4ffba9e3aba2cbb60c1173663abf975b521199
ref: add-reference-destroy-property
resolved-ref: "1700754235ac124a55f90c38b81c2bfc661fc3b8"
url: "https://github.com/linagora/jmap-dart-client.git"
source: git
version: "0.3.0"
Expand Down
2 changes: 1 addition & 1 deletion fcm/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ dependencies:
jmap_dart_client:
git:
url: https://github.com/linagora/jmap-dart-client.git
ref: main
ref: add-reference-destroy-property

### Dependencies from pub.dev ###
equatable: 2.0.5
Expand Down
4 changes: 2 additions & 2 deletions forward/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: main
resolved-ref: bb4ffba9e3aba2cbb60c1173663abf975b521199
ref: add-reference-destroy-property
resolved-ref: "1700754235ac124a55f90c38b81c2bfc661fc3b8"
url: "https://github.com/linagora/jmap-dart-client.git"
source: git
version: "0.3.0"
Expand Down
2 changes: 1 addition & 1 deletion forward/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ dependencies:
jmap_dart_client:
git:
url: https://github.com/linagora/jmap-dart-client.git
ref: main
ref: add-reference-destroy-property

### Dependencies from pub.dev ###
equatable: 2.0.5
Expand Down
37 changes: 37 additions & 0 deletions lib/features/base/mixin/email_action_handler_mixin.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

import 'dart:ui';

import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_mixin.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';

mixin EmailActionHandlerMixin implements MessageDialogActionMixin{
Future<void> showConfirmDialogWhenMakeToActionForSelectionAllEmails({
required ImagePaths imagePaths,
required int totalEmails,
required String folderName,
required VoidCallback onConfirmAction,
}) async {
if (currentContext == null) return;

final appLocalizations = AppLocalizations.of(currentContext!);

await showConfirmDialogAction(
currentContext!,
appLocalizations.messageConfirmationDialogWhenMakeToActionForSelectionAllEmailsInMailbox(
totalEmails,
folderName,
),
appLocalizations.ok,
title: appLocalizations.confirmBulkAction,
icon: SvgPicture.asset(
imagePaths.icQuotasWarning,
colorFilter: AppColor.colorBackgroundQuotasWarning.asFilter(),
),
onConfirmAction: onConfirmAction,
);
}
}
3 changes: 1 addition & 2 deletions lib/features/base/mixin/mailbox_action_handler_mixin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,13 @@ mixin MailboxActionHandlerMixin {
final session = dashboardController.sessionCurrent;
final accountId = dashboardController.accountId.value;
final mailboxId = presentationMailbox.id;
final countEmailsUnread = presentationMailbox.unreadEmails?.value.value ?? 0;
if (session != null && accountId != null) {
dashboardController.markAsReadMailbox(
session,
accountId,
mailboxId,
presentationMailbox.getDisplayName(context),
countEmailsUnread.toInt()
presentationMailbox.countUnreadEmails
);

onCallbackAction?.call(context);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/extensions/html_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:flutter/cupertino.dart';
Expand Down Expand Up @@ -129,6 +130,7 @@ extension EmailActionTypeExtension on EmailActionType {
String getIcon(ImagePaths imagePaths) {
switch(this) {
case EmailActionType.markAsUnread:
case EmailActionType.markAllAsUnread:
return imagePaths.icUnreadEmail;
case EmailActionType.unSpam:
return imagePaths.icNotSpam;
Expand All @@ -142,6 +144,16 @@ extension EmailActionTypeExtension on EmailActionType {
return imagePaths.icMailboxArchived;
case EmailActionType.downloadMessageAsEML:
return imagePaths.icDownloadAttachment;
case EmailActionType.markAsRead:
case EmailActionType.markAllAsRead:
return imagePaths.icRead;
case EmailActionType.moveToMailbox:
case EmailActionType.moveAll:
return imagePaths.icMove;
case EmailActionType.moveToTrash:
case EmailActionType.moveAllToTrash:
case EmailActionType.deleteAllPermanently:
return imagePaths.icDeleteComposer;
default:
return '';
}
Expand All @@ -163,8 +175,33 @@ extension EmailActionTypeExtension on EmailActionType {
return AppLocalizations.of(context).archiveMessage;
case EmailActionType.downloadMessageAsEML:
return AppLocalizations.of(context).downloadMessageAsEML;
case EmailActionType.markAsRead:
return AppLocalizations.of(context).mark_as_read;
case EmailActionType.moveToMailbox:
return AppLocalizations.of(context).move;
case EmailActionType.moveToTrash:
return AppLocalizations.of(context).move_to_trash;
case EmailActionType.markAllAsRead:
return AppLocalizations.of(context).mark_all_as_read;
case EmailActionType.markAllAsUnread:
return AppLocalizations.of(context).markAllAsUnread;
case EmailActionType.moveAll:
return AppLocalizations.of(context).moveAll;
case EmailActionType.moveAllToTrash:
return AppLocalizations.of(context).moveAllToTrash;
case EmailActionType.deleteAllPermanently:
return AppLocalizations.of(context).deleteAllPermanently;
default:
return '';
}
}

Color getIconColor() {
switch(this) {
case EmailActionType.deleteAllPermanently:
return AppColor.colorDeletePermanentlyButton;
default:
return AppColor.primaryColor;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class EmailDataSourceImpl extends EmailDataSource {
ReadActions readActions
) {
return Future.sync(() async {
return await emailAPI.markAsRead(session, accountId, emails, readActions);
return await emailAPI.markAsReadAndGetResult(session, accountId, emails, readActions);
}).catchError(_exceptionThrower.throwException);
}

Expand Down
80 changes: 79 additions & 1 deletion lib/features/email/data/network/email_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ class EmailAPI with HandleSetErrorMixin {
}
}

Future<List<Email>> markAsRead(
Future<List<Email>> markAsReadAndGetResult(
Session session,
AccountId accountId,
List<Email> emails,
Expand Down Expand Up @@ -277,6 +277,41 @@ class EmailAPI with HandleSetErrorMixin {
});
}

Future<List<EmailId>> markAsRead(
Session session,
AccountId accountId,
List<Email> emails,
ReadActions readActions
) async {
final setEmailMethod = SetEmailMethod(accountId)
..addUpdates(emails.listEmailIds.generateMapUpdateObjectMarkAsRead(readActions));

final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);

final capabilities = setEmailMethod.requiredCapabilities
.toCapabilitiesSupportTeamMailboxes(session, accountId);

final response = await (requestBuilder..usings(capabilities))
.build()
.execute();

final setEmailResponse = response.parse<SetEmailResponse>(
setEmailInvocation.methodCallId,
SetEmailResponse.deserialize
);

final listIdUpdated = setEmailResponse?.updated?.keys.toList();
final mapErrors = handleSetResponse([setEmailResponse]);

if (listIdUpdated != null && mapErrors.isEmpty) {
final listEmailIdUpdated = listIdUpdated.map((id) => EmailId(id)).toList();
return listEmailIdUpdated;
} else {
throw SetMethodException(mapErrors);
}
}

Future<List<DownloadTaskId>> downloadAttachments(
List<Attachment> attachments,
AccountId accountId,
Expand Down Expand Up @@ -795,4 +830,47 @@ class EmailAPI with HandleSetErrorMixin {
throw NotFoundEmailException();
}
}

Future<List<EmailId>> moveSelectionAllEmailsToFolder(
Session session,
AccountId accountId,
MailboxId currentMailboxId,
MailboxId destinationMailboxId,
List<EmailId> listEmailId,
{
bool isDestinationSpamMailbox = false
}
) async {
final moveProperties = isDestinationSpamMailbox
? listEmailId.generateMapUpdateObjectMoveToSpam(currentMailboxId, destinationMailboxId)
: listEmailId.generateMapUpdateObjectMoveToMailbox(currentMailboxId, destinationMailboxId);

final setEmailMethod = SetEmailMethod(accountId)
..addUpdates(moveProperties);

final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
final setEmailInvocation = requestBuilder.invocation(setEmailMethod);

final capabilities = setEmailMethod.requiredCapabilities
.toCapabilitiesSupportTeamMailboxes(session, accountId);

final response = await (requestBuilder..usings(capabilities))
.build()
.execute();

final setEmailResponse = response.parse<SetEmailResponse>(
setEmailInvocation.methodCallId,
SetEmailResponse.deserialize
);

final listIdUpdated = setEmailResponse?.updated?.keys.toList();
final mapErrors = handleSetResponse([setEmailResponse]);

if (listIdUpdated != null && mapErrors.isEmpty) {
final listEmailIdUpdated = listIdUpdated.map((id) => EmailId(id)).toList();
return listEmailIdUpdated;
} else {
throw SetMethodException(mapErrors);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ abstract class MailboxDataSource {

Future<bool> moveMailbox(Session session, AccountId accountId, MoveMailboxRequest request);

Future<List<Email>> markAsMailboxRead(
Future<List<EmailId>> markAsMailboxRead(
Session session,
AccountId accountId,
MailboxId mailboxId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class MailboxCacheDataSourceImpl extends MailboxDataSource {
}

@override
Future<List<Email>> markAsMailboxRead(
Future<List<EmailId>> markAsMailboxRead(
Session session,
AccountId accountId,
MailboxId mailboxId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class MailboxDataSourceImpl extends MailboxDataSource {
}

@override
Future<List<Email>> markAsMailboxRead(
Future<List<EmailId>> markAsMailboxRead(
Session session,
AccountId accountId,
MailboxId mailboxId,
Expand Down
Loading
Loading