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-2] TF-2646 Enable selection all emails in search #2843

Open
wants to merge 24 commits into
base: tf-2646-enable-selection-all-emails-in-mailbox
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b0d7cfc
TF-2646 Show banner select all emails when selection enabled
dab246 Apr 25, 2024
c959111
TF-2646 Perform action enable selection all email & clear selection
dab246 Apr 25, 2024
4e49a50
TF-2646 Validate to show selection emails banner
dab246 Apr 25, 2024
b96fe1e
TF-2646 Show more button & popup menu more action
dab246 Apr 25, 2024
0c5f7a3
TF-2646 Show confirm dialog when make to bulk action with selection e…
dab246 Apr 26, 2024
91da9ec
TF-2646 Handle mark as all read for selection emails
dab246 Apr 29, 2024
f895a86
TF-2646 Handle mark all as unread for selection emails
dab246 Apr 29, 2024
17a7014
TF-2646 Handle move all to folder for selection emails
dab246 Apr 29, 2024
f57a5ae
TF-2646 Handle move all to trash for selection emails
dab246 Apr 29, 2024
3317335
TF-2646 Handle delete all permanently for selection emails
dab246 Apr 29, 2024
48e4fdf
TF-2646 Handle mark all as starred for selection emails
dab246 Apr 29, 2024
cb1b524
TF-2646 Handle mark all as Spam/UnSpam for selection emails
dab246 Apr 29, 2024
4a55897
TF-2646 Disable selection all email when toggle select item or load m…
dab246 Apr 29, 2024
a8d8b70
TF-2646 Show the top bar thread button only when the email list is lo…
dab246 Apr 29, 2024
4b62188
TF-2646 Add dependency `package_info_plus` direct main to avoid warni…
dab246 May 2, 2024
316ff13
TF-2646 Show selection all email banner when search enabled
dab246 Apr 29, 2024
cb12b69
TF-2646 Handle mark all as read for search emails
dab246 Dec 11, 2024
a6a213c
TF-2646 Handle mark all as unread for search emails
dab246 May 1, 2024
e79c801
TF-2646 Handle mark all as starred for search emails
dab246 May 1, 2024
5362bd6
TF-2646 Handle move all email searched to folder
dab246 Dec 11, 2024
5948dc6
TF-2646 Handle move all email searched to Trash
dab246 May 1, 2024
6630c32
TF-2646 Handle mark all email searched as Spam
dab246 May 1, 2024
8cd2977
TF-2646 Show `Move all` & `Mark all as Spam` action for selection all…
dab246 May 2, 2024
a2031ff
TF-2646 Fix build failed unit test
dab246 May 1, 2024
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
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

import 'package:flutter_test/flutter_test.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_receive_time_type.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/domain/model/email_receive_time_type.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/model/search/email_sort_order_type.dart';
import 'package:tmail_ui_user/features/search/email/presentation/search_email_view.dart';
import 'package:tmail_ui_user/features/thread/presentation/widgets/email_tile_builder.dart';
Expand Down
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
132 changes: 128 additions & 4 deletions 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 @@ -413,9 +448,12 @@ class EmailAPI with HandleSetErrorMixin {
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
final currentSetEmailInvocations = currentExecuteList.map((currentItem) {

final moveProperties = (moveRequest.moveAction == MoveAction.moving && moveRequest.emailActionType == EmailActionType.moveToSpam)
? currentItem.value.generateMapUpdateObjectMoveToSpam(currentItem.key, moveRequest.destinationMailboxId)
: currentItem.value.generateMapUpdateObjectMoveToMailbox(currentItem.key, moveRequest.destinationMailboxId);
final moveProperties = currentItem.value.generateMapUpdateObjectMoveToMailbox(
currentItem.key,
moveRequest.destinationMailboxId,
isDestinationSpamMailbox: moveRequest.moveAction == MoveAction.moving
&& moveRequest.emailActionType == EmailActionType.moveToSpam
);

return SetEmailMethod(accountId)
..addUpdates(moveProperties);
Expand Down Expand Up @@ -795,4 +833,90 @@ class EmailAPI with HandleSetErrorMixin {
throw NotFoundEmailException();
}
}

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

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);
}
}

Future<List<EmailId>> moveAllEmailsToFolderByEmail(
Session session,
AccountId accountId,
MailboxId destinationMailboxId,
List<Email> listEmail,
{
bool isDestinationSpamMailbox = false
}
) async {
final moveProperties = listEmail.generateMapUpdateObjectMoveToMailbox(
destinationMailboxId,
isDestinationSpamMailbox: isDestinationSpamMailbox);

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