TF-313 Apply new ui for email address detail

This commit is contained in:
dab246
2022-03-09 19:27:45 +07:00
committed by Dat H. Pham
parent a59ef34df4
commit 17499e70db
14 changed files with 411 additions and 252 deletions
+3
View File
@@ -0,0 +1,3 @@
<svg width="9" height="10" viewBox="0 0 9 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="4.5" cy="5" r="4.5" fill="#007AFF"/>
</svg>

After

Width:  |  Height:  |  Size: 150 B

@@ -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)],
@@ -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;
@@ -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();
}
@@ -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<MailboxDashBoardController>();
final responsiveUtils = Get.find<ResponsiveUtils>();
final imagePaths = Get.find<ImagePaths>();
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));
}
}
}
+45 -30
View File
@@ -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();
}
@@ -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<EmailContent>? emailContents;
final EmailAddress? emailAddress;
final List<Attachment>? 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,
@@ -99,7 +99,6 @@ class AppBarMailWidgetBuilder {
(_presentationEmail != null && _presentationEmail!.isFlaggedEmail())
? _imagePaths.icStar
: _imagePaths.icUnStar,
color: AppColor.colorButton,
fit: BoxFit.fill),
onPressed: () {
if (_presentationEmail != null) {
@@ -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<Color>((Set<MaterialState> states) => Colors.white),
backgroundColor: MaterialStateProperty.resolveWith<Color>((Set<MaterialState> 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
);
}
}
@@ -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<Color>((Set<MaterialState> states) => Colors.white),
backgroundColor: MaterialStateProperty.resolveWith<Color>((Set<MaterialState> 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)),
)
)
],
)
),
);
}
}
@@ -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),
],
),
);
}
}
@@ -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(
@@ -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');
}
}
+1
View File
@@ -13,4 +13,5 @@ enum EmailActionType {
markAsSpam,
delete,
edit,
composeFromEmailAddress
}