diff --git a/assets/images/ic_unread_status.svg b/assets/images/ic_unread_status.svg
new file mode 100644
index 000000000..bd8053fad
--- /dev/null
+++ b/assets/images/ic_unread_status.svg
@@ -0,0 +1,3 @@
+
diff --git a/core/lib/presentation/extensions/color_extension.dart b/core/lib/presentation/extensions/color_extension.dart
index 1a703c6ce..b2fac64cd 100644
--- a/core/lib/presentation/extensions/color_extension.dart
+++ b/core/lib/presentation/extensions/color_extension.dart
@@ -93,6 +93,7 @@ extension AppColor on Color {
static const colorTime = Color(0xFF92A1B4);
static const colorEmailAddressPrefix = Color(0xFF9AA7B6);
static const colorEmailAddressTag = Color(0x146D7885);
+ static const colorLineLeftEmailView = Color(0x2999A2AD);
static const mapGradientColor = [
[Color(0xFF21D4FD), Color(0xFFB721FF)],
diff --git a/core/lib/presentation/resources/image_paths.dart b/core/lib/presentation/resources/image_paths.dart
index ea2f20404..6c4cac104 100644
--- a/core/lib/presentation/resources/image_paths.dart
+++ b/core/lib/presentation/resources/image_paths.dart
@@ -65,6 +65,7 @@ class ImagePaths {
String get icDeleteEmailAddress => _getImagePath('ic_delete_email_address.svg');
String get icDeleteEmail => _getImagePath('ic_delete_email.svg');
String get icNewMessage => _getImagePath('ic_new_message.svg');
+ String get icUnreadStatus => _getImagePath('ic_unread_status.svg');
String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart
index c9d057eca..c02ae82c5 100644
--- a/lib/features/composer/presentation/composer_controller.dart
+++ b/lib/features/composer/presentation/composer_controller.dart
@@ -250,6 +250,9 @@ class ComposerController extends BaseController {
if (listToEmailAddress.isNotEmpty || listCcEmailAddress.isNotEmpty || listBccEmailAddress.isNotEmpty) {
isInitialRecipient.value = true;
}
+ } else if (arguments.emailAddress != null) {
+ listToEmailAddress.add(arguments.emailAddress!);
+ isInitialRecipient.value = true;
}
_updateStatusEmailSendButton();
}
@@ -265,6 +268,8 @@ class ComposerController extends BaseController {
case PrefixEmailAddress.bcc:
listBccEmailAddress = newListEmailAddress;
break;
+ default:
+ break;
}
_updateStatusEmailSendButton();
}
diff --git a/lib/features/email/presentation/email_controller.dart b/lib/features/email/presentation/email_controller.dart
index c29feeaaa..34a4462bc 100644
--- a/lib/features/email/presentation/email_controller.dart
+++ b/lib/features/email/presentation/email_controller.dart
@@ -3,9 +3,11 @@ import 'package:dartz/dartz.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
+import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/model.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
@@ -27,6 +29,8 @@ import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_star_email_
import 'package:tmail_ui_user/features/email/domain/usecases/mark_as_email_read_interactor.dart';
import 'package:tmail_ui_user/features/email/domain/usecases/move_to_mailbox_interactor.dart';
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
+import 'package:tmail_ui_user/features/email/presentation/widgets/email_address_bottom_sheet_builder.dart';
+import 'package:tmail_ui_user/features/email/presentation/widgets/email_address_dialog_builder.dart';
import 'package:tmail_ui_user/features/mailbox/presentation/model/mailbox_actions.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -38,6 +42,7 @@ class EmailController extends BaseController {
final mailboxDashBoardController = Get.find();
final responsiveUtils = Get.find();
+ final imagePaths = Get.find();
final GetEmailContentInteractor _getEmailContentInteractor;
final MarkAsEmailReadInteractor _markAsEmailReadInteractor;
@@ -398,7 +403,9 @@ class EmailController extends BaseController {
mailboxDashBoardController.dispatchState(Right(success));
}
- void handleEmailAction(PresentationEmail presentationEmail, EmailActionType actionType) {
+ void handleEmailAction(BuildContext context, PresentationEmail presentationEmail, EmailActionType actionType) {
+ popBack();
+
switch(actionType) {
case EmailActionType.markAsUnread:
markAsEmailRead(presentationEmail, ReadActions.markAsUnread);
@@ -413,6 +420,7 @@ class EmailController extends BaseController {
moveToMailboxAction(presentationEmail);
break;
case EmailActionType.delete:
+ _appToast.showToast(AppLocalizations.of(context).the_feature_is_under_development);
break;
default:
break;
@@ -440,6 +448,51 @@ class EmailController extends BaseController {
isDisplayFullEmailAddress.value = true;
}
+ void openEmailAddressDialog(BuildContext context, EmailAddress emailAddress) {
+ if (responsiveUtils.isMobile(context) || responsiveUtils.isMobileDevice(context)) {
+ (EmailAddressBottomSheetBuilder(context, imagePaths, emailAddress)
+ ..addOnCloseContextMenuAction(() => popBack())
+ ..addOnCopyEmailAddressAction((emailAddress) => copyEmailAddress(context, emailAddress))
+ ..addOnComposeEmailAction((emailAddress) => composeEmailFromEmailAddress(emailAddress)))
+ .show();
+ } else {
+ showDialog(
+ context: context,
+ barrierColor: AppColor.colorDefaultCupertinoActionSheet,
+ builder: (BuildContext context) => (EmailAddressDialogBuilder(context, imagePaths, emailAddress)
+ ..addOnCloseContextMenuAction(() => popBack())
+ ..addOnCopyEmailAddressAction((emailAddress) => copyEmailAddress(context, emailAddress))
+ ..addOnComposeEmailAction((emailAddress) => composeEmailFromEmailAddress(emailAddress)))
+ .build());
+ }
+ }
+
+ void copyEmailAddress(BuildContext context, EmailAddress emailAddress) {
+ popBack();
+
+ Clipboard.setData(ClipboardData(text: emailAddress.emailAddress)).then((_){
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(content: Text(AppLocalizations.of(context).email_address_copied_to_clipboard))
+ );
+ });
+ }
+
+ void composeEmailFromEmailAddress(EmailAddress emailAddress) {
+ popBack();
+
+ if (canComposeEmail()) {
+ push(
+ AppRoutes.COMPOSER,
+ arguments: ComposerArguments(
+ emailActionType: EmailActionType.composeFromEmailAddress,
+ emailAddress: emailAddress,
+ mailboxRole: mailboxDashBoardController.selectedMailbox.value?.role,
+ session: mailboxDashBoardController.sessionCurrent!,
+ userProfile: mailboxDashBoardController.userProfile.value!,
+ mapMailboxId: mailboxDashBoardController.mapDefaultMailboxId));
+ }
+ }
+
void closeMoreMenu() {
popBack();
}
@@ -457,18 +510,33 @@ class EmailController extends BaseController {
}
void pressEmailAction(EmailActionType emailActionType) {
+ if (emailActionType == EmailActionType.compose) {
+ composeEmailAction();
+ } else {
+ if (canComposeEmail()) {
+ push(
+ AppRoutes.COMPOSER,
+ arguments: ComposerArguments(
+ emailActionType: emailActionType,
+ presentationEmail: mailboxDashBoardController.selectedEmail.value!,
+ emailContents: emailContents,
+ attachments: attachments,
+ mailboxRole: mailboxDashBoardController.selectedMailbox.value?.role,
+ session: mailboxDashBoardController.sessionCurrent!,
+ userProfile: mailboxDashBoardController.userProfile.value!,
+ mapMailboxId: mailboxDashBoardController.mapDefaultMailboxId));
+ }
+ }
+ }
+
+ void composeEmailAction() {
if (canComposeEmail()) {
push(
- AppRoutes.COMPOSER,
- arguments: ComposerArguments(
- emailActionType: emailActionType,
- presentationEmail: mailboxDashBoardController.selectedEmail.value!,
- emailContents: emailContents,
- attachments: attachments,
- mailboxRole: mailboxDashBoardController.selectedMailbox.value?.role,
- session: mailboxDashBoardController.sessionCurrent!,
- userProfile: mailboxDashBoardController.userProfile.value!,
- mapMailboxId: mailboxDashBoardController.mapDefaultMailboxId));
+ AppRoutes.COMPOSER,
+ arguments: ComposerArguments(
+ session: mailboxDashBoardController.sessionCurrent!,
+ userProfile: mailboxDashBoardController.userProfile.value!,
+ mapMailboxId: mailboxDashBoardController.mapDefaultMailboxId));
}
}
}
\ No newline at end of file
diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart
index 8311a87be..0338c471a 100644
--- a/lib/features/email/presentation/email_view.dart
+++ b/lib/features/email/presentation/email_view.dart
@@ -31,21 +31,33 @@ class EmailView extends GetView {
@override
Widget build(BuildContext context) {
return Scaffold(
- backgroundColor: AppColor.primaryLightColor,
- body: SafeArea(
- right: responsiveUtils.isMobileDevice(context) && responsiveUtils.isLandscape(context),
- left: responsiveUtils.isMobileDevice(context) && responsiveUtils.isLandscape(context),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- _buildAppBar(context),
- _buildDivider(),
- Expanded(child: _buildEmailBody(context)),
- Divider(color: AppColor.colorDividerEmailView, height: 1),
- _buildBottomBar(context),
- ]
- )
- ));
+ backgroundColor: Colors.white,
+ body: Container(
+ padding: EdgeInsets.zero,
+ margin: EdgeInsets.zero,
+ decoration: !(responsiveUtils.isMobile(context) && responsiveUtils.isMobileDevice(context))
+ ? BoxDecoration(border: Border(left: BorderSide(color: AppColor.colorLineLeftEmailView, width: 1.0)))
+ : null,
+ child: SafeArea(
+ right: responsiveUtils.isMobileDevice(context) && responsiveUtils.isLandscape(context),
+ left: responsiveUtils.isMobileDevice(context) && responsiveUtils.isLandscape(context),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ _buildAppBar(context),
+ Obx(() => emailController.currentEmail != null
+ ? _buildDivider()
+ : SizedBox.shrink()),
+ Expanded(child: _buildEmailBody(context)),
+ Obx(() => emailController.currentEmail != null
+ ? Divider(color: AppColor.colorDividerEmailView, height: 1)
+ : SizedBox.shrink()),
+ _buildBottomBar(context),
+ ]
+ )
+ ),
+ )
+ );
}
Widget _buildDivider({EdgeInsets? edgeInsets}){
@@ -64,7 +76,7 @@ class EmailView extends GetView {
emailController.currentEmail,
emailController.currentMailbox)
..onBackActionClick(() => emailController.backToThreadView())
- ..addOnEmailActionClick((email, action) => emailController.handleEmailAction(email, action))
+ ..addOnEmailActionClick((email, action) => emailController.handleEmailAction(context, email, action))
..addOnMoreActionClick((email, position) => responsiveUtils.isMobileDevice(context)
? emailController.openMoreMenuEmailAction(
context,
@@ -235,20 +247,23 @@ class EmailView extends GetView {
...displayedEmailAddress.map((emailAddress) {
return Padding(
padding: EdgeInsets.only(left: 10),
- child: Chip(
- labelPadding: EdgeInsets.only(left: 8, right: 8, bottom: 2),
- label: Text('${emailAddress.emailAddress}', maxLines: 1, overflow: TextOverflow.ellipsis),
- labelStyle: TextStyle(color: AppColor.colorNameEmail, fontSize: 15, fontWeight: FontWeight.normal),
- backgroundColor: AppColor.colorEmailAddressTag,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(10),
- side: BorderSide(width: 0, color: AppColor.colorEmailAddressTag),
+ child: GestureDetector(
+ onTap: () => emailController.openEmailAddressDialog(context, emailAddress),
+ child: Chip(
+ labelPadding: EdgeInsets.only(left: 8, right: 8, bottom: 2),
+ label: Text('${emailAddress.asString()}', maxLines: 1, overflow: TextOverflow.ellipsis),
+ labelStyle: TextStyle(color: AppColor.colorNameEmail, fontSize: 15, fontWeight: FontWeight.normal),
+ backgroundColor: AppColor.colorEmailAddressTag,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(10),
+ side: BorderSide(width: 0, color: AppColor.colorEmailAddressTag),
+ ),
+ avatar: (AvatarBuilder()
+ ..text('${emailAddress.asString().characters.first.toUpperCase()}')
+ ..addTextStyle(TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.w600))
+ ..avatarColor(emailAddress.avatarColors))
+ .build(),
),
- avatar: (AvatarBuilder()
- ..text('${emailAddress.emailAddress.characters.first.toUpperCase()}')
- ..addTextStyle(TextStyle(fontSize: 12, color: Colors.white, fontWeight: FontWeight.w600))
- ..avatarColor(emailAddress.avatarColors))
- .build(),
)
);
}).toList(),
@@ -484,7 +499,7 @@ class EmailView extends GetView {
iconRightPadding: responsiveUtils.isMobile(context)
? EdgeInsets.only(right: 12)
: EdgeInsets.zero)
- ..onActionClick((email) => emailController.handleEmailAction(email, EmailActionType.markAsUnread)))
+ ..onActionClick((email) => emailController.handleEmailAction(context, email, EmailActionType.markAsUnread)))
.build();
}
diff --git a/lib/features/email/presentation/model/composer_arguments.dart b/lib/features/email/presentation/model/composer_arguments.dart
index 1cc49ea7c..8f323f726 100644
--- a/lib/features/email/presentation/model/composer_arguments.dart
+++ b/lib/features/email/presentation/model/composer_arguments.dart
@@ -1,6 +1,7 @@
import 'package:equatable/equatable.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
+import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
import 'package:model/model.dart';
@@ -8,6 +9,7 @@ class ComposerArguments with EquatableMixin {
final EmailActionType emailActionType;
final PresentationEmail? presentationEmail;
final List? emailContents;
+ final EmailAddress? emailAddress;
final List? attachments;
final Session session;
final UserProfile userProfile;
@@ -20,6 +22,7 @@ class ComposerArguments with EquatableMixin {
this.emailContents,
this.attachments,
this.mailboxRole,
+ this.emailAddress,
required this.session,
required this.userProfile,
required this.mapMailboxId,
@@ -31,6 +34,7 @@ class ComposerArguments with EquatableMixin {
emailContents,
attachments,
mailboxRole,
+ emailAddress,
session,
userProfile,
mapMailboxId,
diff --git a/lib/features/email/presentation/widgets/app_bar_mail_widget_builder.dart b/lib/features/email/presentation/widgets/app_bar_mail_widget_builder.dart
index e4e6b631d..5675ab258 100644
--- a/lib/features/email/presentation/widgets/app_bar_mail_widget_builder.dart
+++ b/lib/features/email/presentation/widgets/app_bar_mail_widget_builder.dart
@@ -99,7 +99,6 @@ class AppBarMailWidgetBuilder {
(_presentationEmail != null && _presentationEmail!.isFlaggedEmail())
? _imagePaths.icStar
: _imagePaths.icUnStar,
- color: AppColor.colorButton,
fit: BoxFit.fill),
onPressed: () {
if (_presentationEmail != null) {
diff --git a/lib/features/email/presentation/widgets/email_address_bottom_sheet_builder.dart b/lib/features/email/presentation/widgets/email_address_bottom_sheet_builder.dart
new file mode 100644
index 000000000..19ed3ae2b
--- /dev/null
+++ b/lib/features/email/presentation/widgets/email_address_bottom_sheet_builder.dart
@@ -0,0 +1,136 @@
+
+import 'package:core/core.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:get/get.dart';
+import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
+import 'package:model/model.dart';
+import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
+
+typedef OnCloseBottomSheetAction = void Function();
+typedef OnCopyEmailAddressBottomSheetAction = void Function(EmailAddress);
+typedef OnComposeEmailBottomSheetAction = void Function(EmailAddress);
+
+class EmailAddressBottomSheetBuilder {
+
+ final BuildContext _context;
+ final ImagePaths _imagePaths;
+ final EmailAddress _emailAddress;
+
+ OnCloseBottomSheetAction? _onCloseBottomSheetAction;
+ OnCopyEmailAddressBottomSheetAction? _onCopyEmailAddressAction;
+ OnComposeEmailBottomSheetAction? _onComposeEmailAction;
+
+ EmailAddressBottomSheetBuilder(
+ this._context,
+ this._imagePaths,
+ this._emailAddress
+ );
+
+ void addOnCloseContextMenuAction(OnCloseBottomSheetAction onCloseBottomSheetAction) {
+ _onCloseBottomSheetAction = onCloseBottomSheetAction;
+ }
+
+ void addOnCopyEmailAddressAction(OnCopyEmailAddressBottomSheetAction onCopyEmailAddressAction) {
+ _onCopyEmailAddressAction = onCopyEmailAddressAction;
+ }
+
+ void addOnComposeEmailAction(OnComposeEmailBottomSheetAction onComposeEmailAction) {
+ _onComposeEmailAction = onComposeEmailAction;
+ }
+
+ RoundedRectangleBorder _shape() {
+ return RoundedRectangleBorder(
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(20.0),
+ topRight: Radius.circular(20.0)));
+ }
+
+ BoxDecoration _decoration(BuildContext context) {
+ return BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.only(
+ topLeft: const Radius.circular(20.0),
+ topRight: const Radius.circular(20.0)));
+ }
+
+ void show() {
+ Get.bottomSheet(
+ GestureDetector(
+ onTap: () => _onCloseBottomSheetAction?.call(),
+ child: SingleChildScrollView(
+ child: Container(
+ margin: EdgeInsets.zero,
+ decoration: _decoration(_context),
+ child: SafeArea(child: GestureDetector(
+ onTap: () => {},
+ child: Column(
+ children: [
+ Align(
+ alignment: Alignment.centerRight,
+ child: IconButton(
+ padding: EdgeInsets.only(top: 16, right: 16),
+ onPressed: () => _onCloseBottomSheetAction?.call(),
+ icon: SvgPicture.asset(_imagePaths.icCloseMailbox, width: 24, height: 24, fit: BoxFit.fill))),
+ (AvatarBuilder()
+ ..text('${_emailAddress.asString().characters.first.toUpperCase()}')
+ ..size(64)
+ ..addTextStyle(TextStyle(fontWeight: FontWeight.w600, fontSize: 23, color: Colors.white))
+ ..avatarColor(_emailAddress.avatarColors))
+ .build(),
+ if (_emailAddress.displayName.isNotEmpty)
+ Padding(
+ padding: EdgeInsets.only(left: 16, right: 16, top: 16),
+ child: Text(
+ _emailAddress.asString(),
+ style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600, color: AppColor.colorNameEmail),
+ )),
+ Padding(
+ padding: EdgeInsets.only(left: 16, right: 16, top: _emailAddress.displayName.isNotEmpty ? 12 : 16),
+ child: Text(
+ _emailAddress.emailAddress,
+ style: TextStyle(fontSize: 17, fontWeight: FontWeight.normal, color: AppColor.colorMessageConfirmDialog),
+ )),
+ Material(
+ borderRadius: BorderRadius.circular(20),
+ color: Colors.transparent,
+ child: TextButton(
+ child: Text(
+ AppLocalizations.of(_context).copy_email_address,
+ style: TextStyle(fontSize: 13, color: AppColor.colorTextButton, fontWeight: FontWeight.normal),
+ ),
+ onPressed: () => _onCopyEmailAddressAction?.call(_emailAddress)
+ )
+ ),
+ SizedBox(height: _emailAddress.displayName.isNotEmpty ? 100 : 130),
+ Padding(
+ padding: EdgeInsets.only(left: 16, right: 16, bottom: 20),
+ child: SizedBox(
+ key: Key('compose_email_button'),
+ width: double.infinity,
+ height: 48,
+ child: ElevatedButton(
+ style: ButtonStyle(
+ foregroundColor: MaterialStateProperty.resolveWith((Set states) => Colors.white),
+ backgroundColor: MaterialStateProperty.resolveWith((Set states) => AppColor.colorTextButton),
+ shape: MaterialStateProperty.all(RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(10),
+ side: BorderSide(width: 0, color: AppColor.colorTextButton)))),
+ child: Text(AppLocalizations.of(_context).compose_email, style: TextStyle(fontSize: 16, color: Colors.white, fontWeight: FontWeight.w500)),
+ onPressed: () => _onComposeEmailAction?.call(_emailAddress)),
+ )
+ )
+ ],
+ ),
+ )),
+ ),
+ ),
+ ),
+ useRootNavigator: true,
+ shape: _shape(),
+ isScrollControlled: true,
+ enableDrag: false,
+ backgroundColor: Colors.transparent
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/features/email/presentation/widgets/email_address_dialog_builder.dart b/lib/features/email/presentation/widgets/email_address_dialog_builder.dart
new file mode 100644
index 000000000..b4f256629
--- /dev/null
+++ b/lib/features/email/presentation/widgets/email_address_dialog_builder.dart
@@ -0,0 +1,117 @@
+
+import 'package:core/core.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
+import 'package:model/model.dart';
+import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
+
+typedef OnCloseDialogAction = void Function();
+typedef OnCopyEmailAddressDialogAction = void Function(EmailAddress);
+typedef OnComposeEmailDialogAction = void Function(EmailAddress);
+
+class EmailAddressDialogBuilder {
+
+ final BuildContext _context;
+ final ImagePaths _imagePaths;
+ final EmailAddress _emailAddress;
+
+ OnCloseDialogAction? _onCloseDialogAction;
+ OnCopyEmailAddressDialogAction? _onCopyEmailAddressAction;
+ OnComposeEmailDialogAction? _onComposeEmailAction;
+
+ EmailAddressDialogBuilder(
+ this._context,
+ this._imagePaths,
+ this._emailAddress
+ );
+
+ void addOnCloseContextMenuAction(OnCloseDialogAction onCloseDialogAction) {
+ _onCloseDialogAction = onCloseDialogAction;
+ }
+
+ void addOnCopyEmailAddressAction(OnCopyEmailAddressDialogAction onCopyEmailAddressAction) {
+ _onCopyEmailAddressAction = onCopyEmailAddressAction;
+ }
+
+ void addOnComposeEmailAction(OnComposeEmailDialogAction onComposeEmailAction) {
+ _onComposeEmailAction = onComposeEmailAction;
+ }
+
+ Widget build() {
+ return Dialog(
+ shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16))),
+ insetPadding: EdgeInsets.symmetric(horizontal: 24.0, vertical: 16.0),
+ child: Container(
+ margin: EdgeInsets.zero,
+ padding: EdgeInsets.zero,
+ width: 400,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.all(Radius.circular(16))),
+ child: Wrap(
+ children: [
+ Align(
+ alignment: Alignment.centerRight,
+ child: IconButton(
+ padding: EdgeInsets.only(top: 16, right: 16),
+ onPressed: () => _onCloseDialogAction?.call(),
+ icon: SvgPicture.asset(_imagePaths.icCloseMailbox, width: 24, height: 24, fit: BoxFit.fill))),
+ Padding(padding: EdgeInsets.symmetric(horizontal: 16),
+ child: Center(child: (AvatarBuilder()
+ ..text('${_emailAddress.asString().characters.first.toUpperCase()}')
+ ..size(64)
+ ..addTextStyle(TextStyle(fontWeight: FontWeight.w600, fontSize: 23, color: Colors.white))
+ ..avatarColor(_emailAddress.avatarColors))
+ .build())),
+ if (_emailAddress.displayName.isNotEmpty)
+ Padding(
+ padding: EdgeInsets.only(left: 16, right: 16, top: 16),
+ child: Center(child: Text(
+ _emailAddress.asString(),
+ style: TextStyle(fontSize: 20, fontWeight: FontWeight.w600, color: AppColor.colorNameEmail),
+ ))
+ ),
+ Padding(
+ padding: EdgeInsets.only(left: 16, right: 16, top: _emailAddress.displayName.isNotEmpty ? 12 : 16),
+ child: Center(child: Text(
+ _emailAddress.emailAddress,
+ style: TextStyle(fontSize: 17, fontWeight: FontWeight.normal, color: AppColor.colorMessageConfirmDialog),
+ ))
+ ),
+ Padding(padding: EdgeInsets.symmetric(horizontal: 16),
+ child: Center(child: Material(
+ borderRadius: BorderRadius.circular(20),
+ color: Colors.transparent,
+ child: TextButton(
+ child: Text(
+ AppLocalizations.of(_context).copy_email_address,
+ style: TextStyle(fontSize: 13, color: AppColor.colorTextButton, fontWeight: FontWeight.normal),
+ ),
+ onPressed: () => _onCopyEmailAddressAction?.call(_emailAddress)
+ )
+ ))),
+ SizedBox(height: _emailAddress.displayName.isNotEmpty ? 100 : 130),
+ Padding(
+ padding: EdgeInsets.only(left: 16, right: 16, bottom: 20),
+ child: SizedBox(
+ key: Key('compose_email_button'),
+ width: double.infinity,
+ height: 48,
+ child: ElevatedButton(
+ style: ButtonStyle(
+ foregroundColor: MaterialStateProperty.resolveWith((Set states) => Colors.white),
+ backgroundColor: MaterialStateProperty.resolveWith((Set states) => AppColor.colorTextButton),
+ shape: MaterialStateProperty.all(RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(10),
+ side: BorderSide(width: 0, color: AppColor.colorTextButton)))),
+ child: Text(AppLocalizations.of(_context).compose_email, style: TextStyle(fontSize: 16, color: Colors.white, fontWeight: FontWeight.w500)),
+ onPressed: () => _onComposeEmailAction?.call(_emailAddress)),
+ )
+ )
+ ],
+ )
+ ),
+ );
+ }
+}
diff --git a/lib/features/email/presentation/widgets/sender_and_receiver_information_tile_builder.dart b/lib/features/email/presentation/widgets/sender_and_receiver_information_tile_builder.dart
deleted file mode 100644
index 13a01f7ee..000000000
--- a/lib/features/email/presentation/widgets/sender_and_receiver_information_tile_builder.dart
+++ /dev/null
@@ -1,209 +0,0 @@
-
-import 'package:core/core.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter_svg/flutter_svg.dart';
-import 'package:get/get.dart';
-import 'package:model/model.dart';
-import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
-
-typedef OnOpenExpandAddressReceiverActionClick = void Function();
-
-class SenderAndReceiverInformationTileBuilder {
-
- static const int LIMIT_ADDRESS_DISPLAY = 1;
-
- final ImagePaths _imagePaths;
- final BuildContext _context;
- final PresentationEmail? _presentationEmail;
- final ExpandMode _expandMode;
-
- OnOpenExpandAddressReceiverActionClick? _onOpenExpandAddressReceiverActionClick;
-
- SenderAndReceiverInformationTileBuilder(
- this._context,
- this._imagePaths,
- this._presentationEmail,
- this._expandMode,
- );
-
- SenderAndReceiverInformationTileBuilder onOpenExpandAddressReceiverActionClick(OnOpenExpandAddressReceiverActionClick onOpenExpandAddressReceiverActionClick) {
- _onOpenExpandAddressReceiverActionClick = onOpenExpandAddressReceiverActionClick;
- return this;
- }
-
- Widget build() {
- if (_presentationEmail == null) {
- return SizedBox.shrink();
- }
- return Theme(
- data: ThemeData(
- splashColor: Colors.transparent,
- highlightColor: Colors.transparent),
- child: MediaQuery(
- data: MediaQueryData(padding: EdgeInsets.zero),
- child: ListTile(
- contentPadding: EdgeInsets.zero,
- leading: Transform(
- transform: Matrix4.translationValues(0.0, 0.0, 0.0),
- child: (AvatarBuilder()
- ..text('${_presentationEmail!.getAvatarText()}')
- ..textColor(Colors.white)
- ..avatarColor(_presentationEmail?.avatarColors)
- ..size(GetPlatform.isWeb ? 48 : 56))
- // .iconStatus(_imagePaths.icOffline)
- .build()),
- title: Transform(
- transform: Matrix4.translationValues(0.0, 0.0, 0.0),
- child: Row(children: [
- Expanded(child: Text(
- '${_presentationEmail!.getSenderName()}',
- style: TextStyle(fontSize: 17, color: AppColor.colorNameEmail, fontWeight: FontWeight.w500),
- )),
- Padding(
- padding: EdgeInsets.only(left: 8),
- child: Text(
- '${_presentationEmail!.getReceivedAt(Localizations.localeOf(_context).toLanguageTag())}',
- maxLines: 1,
- overflow:TextOverflow.ellipsis,
- style: TextStyle(fontSize: 15, color: AppColor.colorContentEmail)))
- ])),
- subtitle: Transform(
- transform: Matrix4.translationValues(0.0, 0.0, 0.0),
- child: Row(children: [
- Expanded(child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- if (_presentationEmail!.to.numberEmailAddress() > 0) _buildAddressToReceiverWidget(),
- if (_presentationEmail!.cc.numberEmailAddress() > 0) _buildAddressCcReceiverWidget(),
- if (_presentationEmail!.bcc.numberEmailAddress() > 0) _buildAddressBccReceiverWidget(),
- ],
- )),
- if (_presentationEmail?.hasAttachment == true)
- Padding(
- padding: EdgeInsets.only(left: 8),
- child: (ButtonBuilder(_imagePaths.icAttachment)
- ..paddingIcon(EdgeInsets.zero)
- ..size(16))
- .build()),
- ]))
- )
- )
- );
- }
-
- Widget _buildExpandAddressWidget(String typeReceiver, String nameAddress) {
- return Row(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- '$typeReceiver: ',
- style: TextStyle(fontSize: 12, color: AppColor.baseTextColor, fontWeight: FontWeight.w500)),
- Expanded(child: Text(
- '$nameAddress',
- style: TextStyle(fontSize: 12, color: AppColor.baseTextColor, fontWeight: FontWeight.w500),
- ))
- ]);
- }
-
- Widget _buildCollapseAddressWidget(String typeReceiver, String nameAddress) {
- return Row(
- children: [
- Text(
- '$typeReceiver: $nameAddress',
- style: TextStyle(fontSize: 12, color: AppColor.baseTextColor, fontWeight: FontWeight.w500)),
- if (_expandMode == ExpandMode.COLLAPSE
- && _presentationEmail != null
- && _presentationEmail!.numberOfAllEmailAddress() > LIMIT_ADDRESS_DISPLAY)
- _buildButtonExpandAddress()
- ]);
- }
-
- Widget _buildAddressWidget(String typeReceiver, String nameAddress) {
- if (_expandMode == ExpandMode.EXPAND
- || (_presentationEmail != null && _presentationEmail!.numberOfAllEmailAddress() <= LIMIT_ADDRESS_DISPLAY)) {
- return Padding(
- padding: EdgeInsets.only(top: 6),
- child: _buildExpandAddressWidget(typeReceiver, nameAddress));
- } else {
- return Padding(
- padding: EdgeInsets.only(top: 6),
- child: _buildCollapseAddressWidget(typeReceiver, nameAddress));
- }
- }
-
- Widget _buildAddressToReceiverWidget() {
- return _buildAddressWidget(
- AppLocalizations.of(_context).to_email_address_prefix,
- _presentationEmail!.to.listEmailAddressToString(expandMode: _expandMode, limitAddress: LIMIT_ADDRESS_DISPLAY));
- }
-
- Widget _buildAddressCcReceiverWidget() {
- if (_presentationEmail!.to.numberEmailAddress() > 0) {
- if (_expandMode == ExpandMode.EXPAND) {
- return Padding(
- padding: EdgeInsets.only(top: 6),
- child: _buildExpandAddressWidget(AppLocalizations.of(_context).cc_email_address_prefix, _presentationEmail!.cc.listEmailAddressToString(expandMode: _expandMode, limitAddress: LIMIT_ADDRESS_DISPLAY)));
- } else {
- return SizedBox.shrink();
- }
- } else {
- return _buildAddressWidget(
- AppLocalizations.of(_context).cc_email_address_prefix,
- _presentationEmail!.cc.listEmailAddressToString(expandMode: _expandMode, limitAddress: LIMIT_ADDRESS_DISPLAY));
- }
- }
-
- Widget _buildAddressBccReceiverWidget() {
- if (_presentationEmail!.to.numberEmailAddress() > 0) {
- if (_expandMode == ExpandMode.EXPAND) {
- return Padding(
- padding: EdgeInsets.only(top: 6),
- child: _buildExpandAddressWidget(AppLocalizations.of(_context).bcc_email_address_prefix, _presentationEmail!.bcc.listEmailAddressToString(expandMode: _expandMode, limitAddress: LIMIT_ADDRESS_DISPLAY)));
- } else {
- return SizedBox.shrink();
- }
- } else {
- if (_presentationEmail!.cc.numberEmailAddress() > 0) {
- if (_expandMode == ExpandMode.EXPAND) {
- return Padding(
- padding: EdgeInsets.only(top: 6),
- child: _buildExpandAddressWidget(AppLocalizations.of(_context).bcc_email_address_prefix, _presentationEmail!.bcc.listEmailAddressToString(expandMode: _expandMode, limitAddress: LIMIT_ADDRESS_DISPLAY)));
- } else {
- return SizedBox.shrink();
- }
- } else {
- return _buildAddressWidget(
- AppLocalizations.of(_context).bcc_email_address_prefix,
- _presentationEmail!.bcc.listEmailAddressToString(expandMode: _expandMode, limitAddress: LIMIT_ADDRESS_DISPLAY));
- }
- }
- }
-
- String getRemainCountAddressReceiver() {
- if (_presentationEmail!.numberOfAllEmailAddress() - LIMIT_ADDRESS_DISPLAY >= 999) {
- return '999';
- }
- return '${_presentationEmail!.numberOfAllEmailAddress() - LIMIT_ADDRESS_DISPLAY}';
- }
-
- Widget _buildButtonExpandAddress() {
- return GestureDetector(
- onTap: () {
- if (_onOpenExpandAddressReceiverActionClick != null) {
- _onOpenExpandAddressReceiverActionClick!();
- }},
- child: Row(
- children: [
- SizedBox(width: 8),
- Text(
- '+${getRemainCountAddressReceiver()}',
- style: TextStyle(fontSize: 12, color: AppColor.baseTextColor, fontWeight: FontWeight.w500),
- ),
- SvgPicture.asset(_imagePaths.icMoreReceiver, width: 14, height: 14, fit: BoxFit.fill),
- ],
- ),
- );
- }
-}
\ No newline at end of file
diff --git a/lib/features/thread/presentation/widgets/email_tile_builder.dart b/lib/features/thread/presentation/widgets/email_tile_builder.dart
index 2803f1313..ff8882a69 100644
--- a/lib/features/thread/presentation/widgets/email_tile_builder.dart
+++ b/lib/features/thread/presentation/widgets/email_tile_builder.dart
@@ -81,7 +81,7 @@ class EmailTileBuilder {
if (_presentationEmail.isUnReadEmail())
Padding(
padding: EdgeInsets.only(right: 5),
- child: SvgPicture.asset(_imagePaths.icUnread, width: 9, height: 9, fit: BoxFit.fill)),
+ child: SvgPicture.asset(_imagePaths.icUnreadStatus, width: 9, height: 9, fit: BoxFit.fill)),
Expanded(
child: _searchStatus == SearchStatus.ACTIVE && _searchQuery != null && _searchQuery!.value.isNotEmpty
? RichTextBuilder(
diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart
index eebc6d68e..c256b2937 100644
--- a/lib/main/localizations/app_localizations.dart
+++ b/lib/main/localizations/app_localizations.dart
@@ -755,4 +755,22 @@ class AppLocalizations {
'Hide',
name: 'hide');
}
+
+ String get copy_email_address {
+ return Intl.message(
+ 'Copy email address',
+ name: 'copy_email_address');
+ }
+
+ String get compose_email {
+ return Intl.message(
+ 'Compose email',
+ name: 'compose_email');
+ }
+
+ String get email_address_copied_to_clipboard {
+ return Intl.message(
+ 'Email address copied to clipboard',
+ name: 'email_address_copied_to_clipboard');
+ }
}
\ No newline at end of file
diff --git a/model/lib/email/email_action_type.dart b/model/lib/email/email_action_type.dart
index 5fe47ad48..a6bfce7ac 100644
--- a/model/lib/email/email_action_type.dart
+++ b/model/lib/email/email_action_type.dart
@@ -13,4 +13,5 @@ enum EmailActionType {
markAsSpam,
delete,
edit,
+ composeFromEmailAddress
}
\ No newline at end of file