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
@@ -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),
],
),
);
}
}