diff --git a/assets/images/ic_resend_email.svg b/assets/images/ic_resend_email.svg
new file mode 100644
index 000000000..8eb540ec1
--- /dev/null
+++ b/assets/images/ic_resend_email.svg
@@ -0,0 +1,4 @@
+
diff --git a/core/lib/presentation/resources/image_paths.dart b/core/lib/presentation/resources/image_paths.dart
index afc1fd8c8..c32296f86 100644
--- a/core/lib/presentation/resources/image_paths.dart
+++ b/core/lib/presentation/resources/image_paths.dart
@@ -185,6 +185,7 @@ class ImagePaths {
String get icAvatarPersonal => _getImagePath('ic_avatar_personal.svg');
String get icDialogOfflineMode => _getImagePath('ic_dialog_offline_mode.svg');
String get icMenuMailbox => _getImagePath('ic_menu_mailbox.svg');
+ String get icResendEmail => _getImagePath('ic_resend_email.svg');
String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
diff --git a/lib/features/composer/domain/extensions/list_sending_email_extension.dart b/lib/features/composer/domain/extensions/list_sending_email_extension.dart
new file mode 100644
index 000000000..faec960a4
--- /dev/null
+++ b/lib/features/composer/domain/extensions/list_sending_email_extension.dart
@@ -0,0 +1,14 @@
+import 'package:jmap_dart_client/jmap/core/id.dart';
+import 'package:jmap_dart_client/jmap/core/utc_date.dart';
+import 'package:jmap_dart_client/jmap/mail/email/email.dart';
+import 'package:model/model.dart';
+import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
+
+extension SendingEmailExtension on List {
+ List toPresentationEmailList() {
+ return map((sendingEmail) => sendingEmail.email.sendingEmailToPresentationEmail(
+ emailId: EmailId(Id(sendingEmail.sendingId)),
+ createAt: UTCDate(sendingEmail.createTime)
+ )).toList();
+ }
+}
\ No newline at end of file
diff --git a/lib/features/composer/domain/extensions/sending_email_extension.dart b/lib/features/composer/domain/extensions/sending_email_extension.dart
index 19926d695..38997cbd4 100644
--- a/lib/features/composer/domain/extensions/sending_email_extension.dart
+++ b/lib/features/composer/domain/extensions/sending_email_extension.dart
@@ -1,4 +1,3 @@
-
import 'package:model/extensions/email_extension.dart';
import 'package:model/extensions/email_id_extensions.dart';
import 'package:model/extensions/identity_id_extension.dart';
diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart
index c821be4ab..6ddbf23a6 100644
--- a/lib/features/composer/presentation/composer_controller.dart
+++ b/lib/features/composer/presentation/composer_controller.dart
@@ -235,7 +235,9 @@ class ComposerController extends BaseController {
@override
void onReady() async {
_initEmail();
- _getAllIdentities();
+ if (isNetworkConnectionAvailable) {
+ _getAllIdentities();
+ }
if (!BuildUtils.isWeb) {
Future.delayed(const Duration(milliseconds: 500), () =>
_checkContactPermission());
@@ -1125,8 +1127,9 @@ class ComposerController extends BaseController {
}
}
- if(arguments.emailContents != null && arguments.emailContents!.isNotEmpty) {
- emailContentsViewState.value = Right(GetEmailContentFromCacheSuccess(arguments.emailContents!, []));
+ if (arguments.emailContents != null && arguments.emailContents!.isNotEmpty) {
+ _emailContents = arguments.emailContents;
+ emailContentsViewState.value = Right(GetEmailContentSuccess(_emailContents!, [], [], arguments.presentationEmail?.toEmail()));
} else {
final session = mailboxDashBoardController.sessionCurrent;
final baseDownloadUrl = mailboxDashBoardController.sessionCurrent?.getDownloadUrl(jmapUrl: _dynamicUrlInterceptors.jmapUrl);
@@ -1162,11 +1165,9 @@ class ComposerController extends BaseController {
success.attachments.listAttachmentsDisplayedOutSide);
}
emailContentsViewState.value = Right(success);
- _emailContents = success.emailContents.asHtmlString;
+ _emailContents = success.emailContents;
}
- String? getEmailContentDraftsAsHtml() => _emailContents;
-
String getEmailAddressSender() {
final arguments = composerArguments.value;
if (arguments != null) {
diff --git a/lib/features/composer/presentation/composer_view.dart b/lib/features/composer/presentation/composer_view.dart
index 6fdf4de01..2bc48ddd3 100644
--- a/lib/features/composer/presentation/composer_view.dart
+++ b/lib/features/composer/presentation/composer_view.dart
@@ -21,7 +21,6 @@ import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:model/email/email_action_type.dart';
import 'package:model/email/prefix_email_address.dart';
-import 'package:model/extensions/list_email_content_extension.dart';
import 'package:model/mailbox/expand_mode.dart';
import 'package:rich_text_composer/rich_text_composer.dart';
import 'package:rich_text_composer/views/widgets/rich_text_keyboard_toolbar.dart';
@@ -628,7 +627,7 @@ class ComposerView extends GetWidget
child: loadingWidget,
);
} else if (success is GetEmailContentSuccess) {
- var contentHtml = success.emailContents.asHtmlString;
+ var contentHtml = success.emailContents;
if (contentHtml.isEmpty == true) {
contentHtml = HtmlExtension.editorStartTags;
}
diff --git a/lib/features/composer/presentation/composer_view_web.dart b/lib/features/composer/presentation/composer_view_web.dart
index ddeb6f829..f7f2caacf 100644
--- a/lib/features/composer/presentation/composer_view_web.dart
+++ b/lib/features/composer/presentation/composer_view_web.dart
@@ -21,7 +21,6 @@ import 'package:html_editor_enhanced/html_editor.dart';
import 'package:jmap_dart_client/jmap/identities/identity.dart';
import 'package:model/email/email_action_type.dart';
import 'package:model/email/prefix_email_address.dart';
-import 'package:model/extensions/list_email_content_extension.dart';
import 'package:model/mailbox/expand_mode.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
@@ -773,7 +772,7 @@ class ComposerView extends GetWidget
child: loadingWidget,
);
} else if (success is GetEmailContentSuccess) {
- var contentHtml = success.emailContents.asHtmlString;
+ var contentHtml = success.emailContents;
if (contentHtml.isEmpty == true) {
contentHtml = HtmlExtension.editorStartTags;
}
diff --git a/lib/features/email/domain/state/get_email_content_state.dart b/lib/features/email/domain/state/get_email_content_state.dart
index 20b0fb41c..0e19ba6bf 100644
--- a/lib/features/email/domain/state/get_email_content_state.dart
+++ b/lib/features/email/domain/state/get_email_content_state.dart
@@ -5,7 +5,7 @@ import 'package:model/model.dart';
class GetEmailContentLoading extends LoadingState {}
class GetEmailContentSuccess extends UIState {
- final List emailContents;
+ final String emailContents;
final List emailContentsDisplayed;
final List attachments;
final Email? emailCurrent;
diff --git a/lib/features/email/domain/usecases/get_email_content_interactor.dart b/lib/features/email/domain/usecases/get_email_content_interactor.dart
index f68ceb5e7..5e7ba1cd4 100644
--- a/lib/features/email/domain/usecases/get_email_content_interactor.dart
+++ b/lib/features/email/domain/usecases/get_email_content_interactor.dart
@@ -8,8 +8,7 @@ import 'package:dartz/dartz.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
-import 'package:model/extensions/email_extension.dart';
-import 'package:model/extensions/list_attachment_extension.dart';
+import 'package:model/model.dart';
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart';
@@ -68,15 +67,15 @@ class GetEmailContentInteractor {
: newEmailContents;
yield Right(GetEmailContentSuccess(
- newEmailContents,
+ newEmailContents.asHtmlString,
newEmailContentsDisplayed,
email.allAttachments,
email
));
} else if (email.allAttachments.isNotEmpty) {
- yield Right(GetEmailContentSuccess([], [], email.allAttachments, email));
+ yield Right(GetEmailContentSuccess("", [], email.allAttachments, email));
} else if (email.headers?.isNotEmpty == true) {
- yield Right(GetEmailContentSuccess([], [], [], email));
+ yield Right(GetEmailContentSuccess("", [], [], email));
} else {
yield Left(GetEmailContentFailure(null));
}
diff --git a/lib/features/email/presentation/controller/single_email_controller.dart b/lib/features/email/presentation/controller/single_email_controller.dart
index 67df14f29..82dcd0e2f 100644
--- a/lib/features/email/presentation/controller/single_email_controller.dart
+++ b/lib/features/email/presentation/controller/single_email_controller.dart
@@ -371,7 +371,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
emailSupervisorController.popEmailQueue(success.emailCurrent?.id);
emailSupervisorController.pushEmailQueue(EmailLoaded(
- success.emailContents.toList(),
+ success.emailContents,
success.emailContentsDisplayed.toList(),
success.attachments.toList(),
success.emailCurrent,
@@ -379,7 +379,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
if (success.emailCurrent?.id == currentEmail?.id) {
emailContents.value = success.emailContentsDisplayed.asHtmlString;
- initialEmailContents = success.emailContents.asHtmlString;
+ initialEmailContents = success.emailContents;
attachments.value = success.attachments;
if (!BuildUtils.isWeb) {
diff --git a/lib/features/email/presentation/model/email_loaded.dart b/lib/features/email/presentation/model/email_loaded.dart
index a35f15b1f..9dbdd7660 100644
--- a/lib/features/email/presentation/model/email_loaded.dart
+++ b/lib/features/email/presentation/model/email_loaded.dart
@@ -3,7 +3,7 @@ import 'package:jmap_dart_client/jmap/mail/email/email.dart';
import 'package:model/model.dart';
class EmailLoaded with EquatableMixin {
- final List emailContents;
+ final String emailContents;
final List emailContentsDisplayed;
final List attachments;
final Email? emailCurrent;
diff --git a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart
index e1af34905..569bc1939 100644
--- a/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart
+++ b/lib/features/mailbox_dashboard/presentation/mailbox_dashboard_view.dart
@@ -61,7 +61,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
children: [
SizedBox(
width: ResponsiveUtils.defaultSizeLeftMenuMobile,
- child: _buildScaffoldHaveDrawer(body: const SendingQueueView())),
+ child: _buildScaffoldHaveDrawer(body: SendingQueueView())),
Expanded(child: EmailView()),
],
);
@@ -70,7 +70,7 @@ class MailboxDashBoardView extends BaseMailboxDashBoardView {
desktop: bodyView,
tabletLarge: bodyView,
landscapeTablet: bodyView,
- mobile: _buildScaffoldHaveDrawer(body: const SendingQueueView()));
+ mobile: _buildScaffoldHaveDrawer(body: SendingQueueView()));
case DashboardRoutes.waiting:
return const Center(
child: SizedBox(
diff --git a/lib/features/sending_queue/presentation/model/sending_email_action_type.dart b/lib/features/sending_queue/presentation/model/sending_email_action_type.dart
index 4ca8e1834..ef240cc0c 100644
--- a/lib/features/sending_queue/presentation/model/sending_email_action_type.dart
+++ b/lib/features/sending_queue/presentation/model/sending_email_action_type.dart
@@ -4,12 +4,15 @@ import 'package:flutter/cupertino.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
enum SendingEmailActionType {
+ edit,
delete;
String getButtonTitle(BuildContext context) {
switch(this) {
case SendingEmailActionType.delete:
return AppLocalizations.of(context).delete;
+ case SendingEmailActionType.edit:
+ return AppLocalizations.of(context).edit;
}
}
@@ -17,6 +20,8 @@ enum SendingEmailActionType {
switch(this) {
case SendingEmailActionType.delete:
return 'button_delete_sending_email';
+ case SendingEmailActionType.edit:
+ return 'button_edit_sending_email';
}
}
@@ -24,6 +29,8 @@ enum SendingEmailActionType {
switch(this) {
case SendingEmailActionType.delete:
return AppColor.colorDeletePermanentlyButton;
+ case SendingEmailActionType.edit:
+ return AppColor.primaryColor;
}
}
@@ -31,6 +38,8 @@ enum SendingEmailActionType {
switch(this) {
case SendingEmailActionType.delete:
return AppColor.colorDeletePermanentlyButton;
+ case SendingEmailActionType.edit:
+ return AppColor.primaryColor;
}
}
}
\ No newline at end of file
diff --git a/lib/features/sending_queue/presentation/sending_queue_controller.dart b/lib/features/sending_queue/presentation/sending_queue_controller.dart
index c8abdd944..2cb82ac6c 100644
--- a/lib/features/sending_queue/presentation/sending_queue_controller.dart
+++ b/lib/features/sending_queue/presentation/sending_queue_controller.dart
@@ -8,10 +8,12 @@ import 'package:core/presentation/utils/app_toast.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
+import 'package:model/email/email_action_type.dart';
import 'package:model/mailbox/select_mode.dart';
import 'package:tmail_ui_user/features/base/base_controller.dart';
import 'package:tmail_ui_user/features/base/mixin/message_dialog_action_mixin.dart';
import 'package:tmail_ui_user/features/composer/domain/model/sending_email.dart';
+import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/features/offline_mode/scheduler/worker_state.dart';
import 'package:tmail_ui_user/features/sending_queue/presentation/utils/sending_queue_isolate_manager.dart';
@@ -103,6 +105,9 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
case SendingEmailActionType.delete:
_deleteSendingEmailAction(context, listSendingEmails);
break;
+ case SendingEmailActionType.edit:
+ _editSendingEmailAction(listSendingEmails.first);
+ break;
}
}
@@ -168,6 +173,17 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
}
}
+ void _editSendingEmailAction(SendingEmail sendingEmail) {
+ final arguments = ComposerArguments(
+ emailActionType: EmailActionType.edit,
+ presentationEmail: sendingEmail.presentationEmail,
+ mailboxRole: dashboardController?.selectedMailbox.value?.role,
+ emailContents: sendingEmail.email.subject,
+ );
+
+ dashboardController?.goToComposer(arguments);
+ }
+
void _handleDeleteSendingEmailFailure() {
selectionState.value = SelectMode.INACTIVE;
}
@@ -196,4 +212,55 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
_sendingQueueIsolateManager?.release();
super.onClose();
}
+
+ //
+ // void pressEmailAction(
+ // BuildContext context,
+ // EmailActionType actionType,
+ // PresentationEmail selectedEmail,
+ // {PresentationMailbox? mailboxContain}
+ // ) {
+ // switch(actionType) {
+ // case EmailActionType.edit:
+ // editEmail(selectedEmail);
+ // break;
+ // case EmailActionType.selection:
+ // selectEmail(context, selectedEmail);
+ // break;
+ // default:
+ // break;
+ // }
+ // }
+ //
+ // void pressEmailSelectionAction(
+ // BuildContext context,
+ // EmailActionType actionType,
+ // List selectionEmail
+ // ) {
+ // switch(actionType) {
+ // case EmailActionType.edit:
+ // editEmail(selectionEmail.first);
+ // break;
+ // default:
+ // break;
+ // }
+ // }
+
+ // bool isSelectionEnabled() => currentSelectMode.value == SelectMode.ACTIVE;
+ //
+ // bool? _isUnSelectedAll() {
+ // return dashboardController?.sendingEmailsInCurrentMailbox.every((email) => email.selectMode == SelectMode.INACTIVE);
+ // }
+ //
+ // void cancelSelectEmail() {
+ // final newEmailList = dashboardController?.sendingEmailsInCurrentMailbox
+ // .map((email) => email.toSelectedEmail(selectMode: SelectMode.INACTIVE))
+ // .toList();
+ // updateEmailList(newEmailList);
+ // currentSelectMode.value = SelectMode.INACTIVE;
+ // listEmailSelected.clear();
+ // }
+
+ // List get listEmailSelected => dashboardController?.sendingEmailsInCurrentMailbox.listEmailSelected ?? [];
+
}
\ No newline at end of file
diff --git a/lib/features/sending_queue/presentation/widgets/bottom_bar_sending_queue_widget.dart b/lib/features/sending_queue/presentation/widgets/bottom_bar_sending_queue_widget.dart
index 2504f43f2..6f3753acb 100644
--- a/lib/features/sending_queue/presentation/widgets/bottom_bar_sending_queue_widget.dart
+++ b/lib/features/sending_queue/presentation/widgets/bottom_bar_sending_queue_widget.dart
@@ -35,6 +35,15 @@ class BottomBarSendingQueueWidget extends StatelessWidget {
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
+ Expanded(child: (ButtonBuilder(imagePaths.icEdit)
+ ..key(Key(SendingEmailActionType.edit.getButtonKey()))
+ ..iconColor(SendingEmailActionType.edit.getButtonIconColor())
+ ..padding(const EdgeInsets.all(8))
+ ..radiusSplash(8)
+ ..textStyle(TextStyle(fontSize: 12, color: SendingEmailActionType.edit.getButtonTitleColor()))
+ ..onPressActionClick(() => onHandleSendingEmailActionType?.call(SendingEmailActionType.edit, listSendingEmails))
+ ..text(SendingEmailActionType.edit.getButtonTitle(context), isVertical: true)
+ ).build()),
Expanded(child: (ButtonBuilder(imagePaths.icDeleteComposer)
..key(Key(SendingEmailActionType.delete.getButtonKey()))
..iconColor(SendingEmailActionType.delete.getButtonIconColor())
diff --git a/model/lib/email/email_action_type.dart b/model/lib/email/email_action_type.dart
index 161ee58fb..860db4769 100644
--- a/model/lib/email/email_action_type.dart
+++ b/model/lib/email/email_action_type.dart
@@ -17,5 +17,6 @@ enum EmailActionType {
selection,
moveToSpam,
unSpam,
- openInNewTab
+ openInNewTab,
+ resend
}
\ No newline at end of file
diff --git a/model/lib/email/presentation_email.dart b/model/lib/email/presentation_email.dart
index 3cf8a3f55..e491ae02a 100644
--- a/model/lib/email/presentation_email.dart
+++ b/model/lib/email/presentation_email.dart
@@ -1,6 +1,8 @@
+import 'package:core/domain/extensions/datetime_extension.dart';
import 'package:core/presentation/extensions/string_extension.dart';
import 'package:equatable/equatable.dart';
+import 'package:intl/intl.dart';
import 'package:jmap_dart_client/jmap/core/unsigned_int.dart';
import 'package:jmap_dart_client/jmap/core/utc_date.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
@@ -101,6 +103,10 @@ class PresentationEmail with EquatableMixin {
bool get pushNotificationActivated => !isDraft && !hasRead;
+ String getCreateTimeAt(String newLocale) {
+ return DateFormat(sentAt?.value.toPattern(), newLocale).format(sentAt?.value ?? DateTime.now());
+ }
+
@override
List