TF-185 [BUG] Fix can not display all parts of email which have multiple html part

This commit is contained in:
dab246
2021-10-15 16:14:41 +07:00
committed by Dat H. Pham
parent a6f2a23cec
commit ececc65a26
16 changed files with 282 additions and 154 deletions
@@ -1,3 +1,4 @@
import 'package:core/core.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -8,6 +9,8 @@ class HtmlContentViewer extends StatefulWidget {
final String contentHtml; final String contentHtml;
final int minHeight; final int minHeight;
final double widthContent;
final Widget? loadingWidget;
/// Register this callback if you want a reference to the [InAppWebViewController]. /// Register this callback if you want a reference to the [InAppWebViewController].
final void Function(InAppWebViewController controller)? onCreated; final void Function(InAppWebViewController controller)? onCreated;
@@ -22,7 +25,9 @@ class HtmlContentViewer extends StatefulWidget {
const HtmlContentViewer({ const HtmlContentViewer({
Key? key, Key? key,
required this.contentHtml, required this.contentHtml,
required this.widthContent,
this.minHeight = 100, this.minHeight = 100,
this.loadingWidget,
this.onCreated, this.onCreated,
this.onLoadStart, this.onLoadStart,
this.onLoadStop, this.onLoadStop,
@@ -39,6 +44,7 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
double? _documentWidth = 1.0; double? _documentWidth = 1.0;
String? _initialPageContent; String? _initialPageContent;
late InAppWebViewController _webViewController; late InAppWebViewController _webViewController;
bool loading = true;
@override @override
void initState() { void initState() {
@@ -101,15 +107,33 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final size = MediaQuery.of(context).size; _documentWidth = widget.widthContent;
_documentWidth = size.width - 30; return Stack(
return SizedBox( alignment: AlignmentDirectional.center,
height: _documentHeight, children: [
width: _documentWidth, SizedBox(
child: _buildWebView(), height: _documentHeight,
width: _documentWidth,
child: _buildWebView(),
),
if (loading) _buildLoadingView()
],
); );
} }
Widget _buildLoadingView() {
if (widget.loadingWidget != null) {
return widget.loadingWidget!;
} else {
return Padding(
padding: EdgeInsets.all(16),
child: SizedBox(
width: 30,
height: 30,
child: CircularProgressIndicator(color: AppColor.primaryColor)));
}
}
Widget _buildWebView() { Widget _buildWebView() {
if (_initialPageContent == null || _initialPageContent?.isEmpty == true) { if (_initialPageContent == null || _initialPageContent?.isEmpty == true) {
return Container(); return Container();
@@ -148,6 +172,9 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
_documentHeight = (scrollHeight + 30.0); _documentHeight = (scrollHeight + 30.0);
}); });
} }
setState(() {
loading = false;
});
if (widget.onLoadStop != null) { if (widget.onLoadStop != null) {
widget.onLoadStop!(controller, uri); widget.onLoadStop!(controller, uri);
} }
@@ -214,7 +214,10 @@ class ComposerController extends BaseController {
.addBlockTag('p', attribute: 'style=\"font-size:14px;font-style:italic;color:#182952;\"') .addBlockTag('p', attribute: 'style=\"font-size:14px;font-style:italic;color:#182952;\"')
: ''; : '';
final trustAsHtml = composerArguments.value?.emailContent?.content ?? ''; final trustAsHtml = composerArguments.value?.emailContents
?.map((emailContent) => emailContent.content)
.toList()
.join('</br>') ?? '';
final emailQuotedHtml = '</br></br></br>$headerEmailQuotedAsHtml${trustAsHtml.addBlockQuoteTag()}</br>'; final emailQuotedHtml = '</br></br></br>$headerEmailQuotedAsHtml${trustAsHtml.addBlockQuoteTag()}</br>';
@@ -2,5 +2,5 @@
import 'package:model/model.dart'; import 'package:model/model.dart';
abstract class HtmlDataSource { abstract class HtmlDataSource {
Future<String> transformToHtml(EmailContent emailContent); Future<EmailContent> transformEmailContent(EmailContent emailContent);
} }
@@ -9,9 +9,9 @@ class HtmlDataSourceImpl extends HtmlDataSource {
HtmlDataSourceImpl(this._htmlAnalyzer); HtmlDataSourceImpl(this._htmlAnalyzer);
@override @override
Future<String> transformToHtml(EmailContent emailContent) { Future<EmailContent> transformEmailContent(EmailContent emailContent) {
return Future.sync(() async { return Future.sync(() async {
return await _htmlAnalyzer.transformToHtml(emailContent); return await _htmlAnalyzer.transformEmailContent(emailContent);
}).catchError((error) { }).catchError((error) {
throw error; throw error;
}); });
@@ -5,13 +5,14 @@ import 'package:model/model.dart';
class HtmlAnalyzer { class HtmlAnalyzer {
Future<String> transformToHtml(EmailContent emailContent) async { Future<EmailContent> transformEmailContent(EmailContent emailContent) async {
switch(emailContent.type) { switch(emailContent.type) {
case EmailContentType.textHtml: case EmailContentType.textHtml:
final htmlTransform = HtmlTransform(emailContent.content); final htmlTransform = HtmlTransform(emailContent.content);
return htmlTransform.transformToHtml(); final htmlContent = htmlTransform.transformToHtml();
return EmailContent(emailContent.type, htmlContent);
default: default:
return emailContent.content; return emailContent;
} }
} }
} }
@@ -72,7 +72,11 @@ class EmailRepositoryImpl extends EmailRepository {
} }
@override @override
Future<String> transformEmailContentToHtml(EmailContent emailContent) { Future<List<EmailContent>> transformEmailContent(List<EmailContent> emailContents) async {
return _htmlDataSource.transformToHtml(emailContent); return await Future.wait(emailContents
.map((emailContent) async {
return await _htmlDataSource.transformEmailContent(emailContent);
})
.toList());
} }
} }
@@ -35,5 +35,5 @@ abstract class EmailRepository {
MarkStarAction markStarAction MarkStarAction markStarAction
); );
Future<String> transformEmailContentToHtml(EmailContent emailContent); Future<List<EmailContent>> transformEmailContent(List<EmailContent> emailContents);
} }
@@ -2,13 +2,13 @@ import 'package:core/core.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
class GetEmailContentSuccess extends UIState { class GetEmailContentSuccess extends UIState {
final EmailContent emailContent; final List<EmailContent> emailContents;
final List<Attachment> attachments; final List<Attachment> attachments;
GetEmailContentSuccess(this.emailContent, this.attachments); GetEmailContentSuccess(this.emailContents, this.attachments);
@override @override
List<Object?> get props => [emailContent, attachments]; List<Object?> get props => [emailContents, attachments];
} }
class GetEmailContentFailure extends FeatureFailure { class GetEmailContentFailure extends FeatureFailure {
@@ -17,15 +17,8 @@ class GetEmailContentInteractor {
final email = await emailRepository.getEmailContent(accountId, emailId); final email = await emailRepository.getEmailContent(accountId, emailId);
if (email.emailContentList.isNotEmpty) { if (email.emailContentList.isNotEmpty) {
final emailContent = email.emailContentList.first; final newEmailContents = await emailRepository.transformEmailContent(email.emailContentList);
if (emailContent.type == EmailContentType.textHtml) { yield Right<Failure, Success>(GetEmailContentSuccess(newEmailContents, email.allAttachments));
final contentHtml = await emailRepository.transformEmailContentToHtml(emailContent);
yield Right<Failure, Success>(GetEmailContentSuccess(
EmailContent(emailContent.type, contentHtml),
email.allAttachments));
} else {
yield Right<Failure, Success>(GetEmailContentSuccess(emailContent, email.allAttachments));
}
} else { } else {
yield Left(GetEmailContentFailure(null)); yield Left(GetEmailContentFailure(null));
} }
@@ -26,7 +26,6 @@ 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/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/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/model/composer_arguments.dart';
import 'package:tmail_ui_user/features/email/presentation/model/web_view_state.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart'; import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/mailbox_dashboard_controller.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart'; import 'package:tmail_ui_user/main/routes/app_routes.dart';
@@ -49,7 +48,7 @@ class EmailController extends BaseController {
final emailAddressExpandMode = ExpandMode.COLLAPSE.obs; final emailAddressExpandMode = ExpandMode.COLLAPSE.obs;
final attachmentsExpandMode = ExpandMode.COLLAPSE.obs; final attachmentsExpandMode = ExpandMode.COLLAPSE.obs;
final emailContent = Rxn<EmailContent>(); final emailContents = <EmailContent>[].obs;
final attachments = <Attachment>[].obs; final attachments = <Attachment>[].obs;
EmailId? _currentEmailId; EmailId? _currentEmailId;
@@ -129,17 +128,14 @@ class EmailController extends BaseController {
} }
void _getEmailContentSuccess(GetEmailContentSuccess success) { void _getEmailContentSuccess(GetEmailContentSuccess success) {
emailContent.value = success.emailContent; emailContents.value = success.emailContents;
attachments.value = success.attachments; attachments.value = success.attachments;
if (emailContent.value != null && emailContent.value!.type == EmailContentType.textHtml) {
dispatchState(Right(WebViewLoadingState()));
}
} }
void _clearEmailContent() { void _clearEmailContent() {
toggleDisplayEmailAddressAction(expandMode: ExpandMode.COLLAPSE); toggleDisplayEmailAddressAction(expandMode: ExpandMode.COLLAPSE);
attachmentsExpandMode.value = ExpandMode.COLLAPSE; attachmentsExpandMode.value = ExpandMode.COLLAPSE;
emailContent.value = null; emailContents.clear();
attachments.clear(); attachments.clear();
} }
@@ -357,7 +353,7 @@ class EmailController extends BaseController {
arguments: ComposerArguments( arguments: ComposerArguments(
emailActionType: emailActionType, emailActionType: emailActionType,
presentationEmail: mailboxDashBoardController.selectedEmail.value!, presentationEmail: mailboxDashBoardController.selectedEmail.value!,
emailContent: emailContent.value, emailContents: emailContents,
attachments: attachments, attachments: attachments,
mailboxRole: mailboxDashBoardController.selectedMailbox.value?.role, mailboxRole: mailboxDashBoardController.selectedMailbox.value?.role,
session: mailboxDashBoardController.sessionCurrent!, session: mailboxDashBoardController.sessionCurrent!,
+35 -46
View File
@@ -1,18 +1,18 @@
import 'dart:io'; import 'dart:io';
import 'package:core/core.dart'; import 'package:core/core.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:model/model.dart'; import 'package:model/model.dart';
import 'package:tmail_ui_user/features/email/presentation/email_controller.dart'; import 'package:tmail_ui_user/features/email/presentation/email_controller.dart';
import 'package:tmail_ui_user/features/email/presentation/model/web_view_state.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/app_bar_mail_widget_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/app_bar_mail_widget_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_file_tile_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_file_tile_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/attachments_place_holder_loading_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/bottom_bar_mail_widget_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/bottom_bar_mail_widget_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/extensions/list_attachment_extension.dart'; import 'package:tmail_ui_user/features/email/presentation/extensions/list_attachment_extension.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/email_content_item_builder.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/email_content_place_holder_loading_widget.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_content_place_holder_loading_widget.dart';
import 'package:tmail_ui_user/features/email/presentation/widgets/sender_and_receiver_information_tile_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/sender_and_receiver_information_tile_builder.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -27,21 +27,17 @@ class EmailView extends GetView {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: AppColor.primaryLightColor, backgroundColor: AppColor.primaryLightColor,
body: SafeArea( body: SafeArea(
right: false, right: false,
left: false, left: false,
child: Container( child: Column(
alignment: Alignment.center, mainAxisAlignment: MainAxisAlignment.center,
child: Column( children: [
mainAxisAlignment: MainAxisAlignment.center, _buildAppBar(context),
crossAxisAlignment: CrossAxisAlignment.center, Expanded(child: _buildEmailBody(context)),
children: [ _buildBottomBar(context),
_buildAppBar(context), ]
Expanded(child: _buildEmailBody(context)),
_buildBottomBar(context),
])
) )
)); ));
} }
@@ -116,14 +112,6 @@ class EmailView extends GetView {
)); ));
} }
Widget _buildLoadingView() {
return Obx(() => emailController.viewState.value.fold(
(failure) => SizedBox.shrink(),
(success) => success is LoadingState || success is WebViewLoadingState
? EmailContentPlaceHolderLoading(responsiveUtils: responsiveUtils)
: SizedBox.shrink()));
}
Widget _buildEmailMessage(BuildContext context) { Widget _buildEmailMessage(BuildContext context) {
return Container( return Container(
padding: EdgeInsets.only(left: 12, right: 12, top: 16, bottom: 16), padding: EdgeInsets.only(left: 12, right: 12, top: 16, bottom: 16),
@@ -143,9 +131,8 @@ class EmailView extends GetView {
emailController.emailAddressExpandMode.value) emailController.emailAddressExpandMode.value)
.onOpenExpandAddressReceiverActionClick(() => emailController.toggleDisplayEmailAddressAction(expandMode: ExpandMode.EXPAND)) .onOpenExpandAddressReceiverActionClick(() => emailController.toggleDisplayEmailAddressAction(expandMode: ExpandMode.EXPAND))
.build()), .build()),
_buildLoadingView(),
_buildAttachments(context), _buildAttachments(context),
_buildEmailContent(), _buildListEmailContent(),
], ],
) )
); );
@@ -155,8 +142,8 @@ class EmailView extends GetView {
return Obx(() => emailController.viewState.value.fold( return Obx(() => emailController.viewState.value.fold(
(failure) => SizedBox.shrink(), (failure) => SizedBox.shrink(),
(success) { (success) {
if (success is LoadingState || success is WebViewLoadingState) { if (success is LoadingState) {
return SizedBox.shrink(); return AttachmentsPlaceHolderLoading(responsiveUtils: responsiveUtils);
} else { } else {
final attachments = emailController.attachments.attachmentsWithDispositionAttachment; final attachments = emailController.attachments.attachmentsWithDispositionAttachment;
return attachments.isNotEmpty return attachments.isNotEmpty
@@ -272,28 +259,30 @@ class EmailView extends GetView {
); );
} }
Widget _buildEmailContent() { Widget _buildListEmailContent() {
return Obx(() { return Obx(() => emailController.viewState.value.fold(
if (emailController.emailContent.value != null) { (failure) => SizedBox.shrink(),
switch(emailController.emailContent.value!.type) { (success) {
case EmailContentType.textHtml: if (success is LoadingState) {
return HtmlContentViewer( return EmailContentPlaceHolderLoading(responsiveUtils: responsiveUtils);
contentHtml: emailController.emailContent.value!.content, } else {
onLoadStart: (webController, uri) => emailController.dispatchState(Right(WebViewLoadingState())), if (emailController.emailContents.isNotEmpty) {
onLoadStop: (webController, uri) => emailController.dispatchState(Right(WebViewLoadCompletedState())), return ListView.builder(
mailtoDelegate: (uri) async {}); primary: false,
case EmailContentType.textPlain: shrinkWrap: true,
return Padding( padding: EdgeInsets.only(top: 10),
padding: EdgeInsets.only(top: 16), key: Key('list_email_content'),
child: Text( itemCount: emailController.emailContents.length,
emailController.emailContent.value!.content, itemBuilder: (context, index) =>
style: TextStyle(fontSize: 14, color: AppColor.nameUserColor))); EmailContentItemBuilder(
case EmailContentType.other: context,
emailController.emailContents[index],
loadingWidget: EmailContentPlaceHolderLoading(responsiveUtils: responsiveUtils)
).build());
} else {
return SizedBox.shrink(); return SizedBox.shrink();
}
} }
} else { }));
return SizedBox.shrink();
}
});
} }
} }
@@ -7,7 +7,7 @@ import 'package:model/model.dart';
class ComposerArguments with EquatableMixin { class ComposerArguments with EquatableMixin {
final EmailActionType emailActionType; final EmailActionType emailActionType;
final PresentationEmail? presentationEmail; final PresentationEmail? presentationEmail;
final EmailContent? emailContent; final List<EmailContent>? emailContents;
final List<Attachment>? attachments; final List<Attachment>? attachments;
final Session session; final Session session;
final UserProfile userProfile; final UserProfile userProfile;
@@ -17,7 +17,7 @@ class ComposerArguments with EquatableMixin {
ComposerArguments({ ComposerArguments({
this.emailActionType = EmailActionType.compose, this.emailActionType = EmailActionType.compose,
this.presentationEmail, this.presentationEmail,
this.emailContent, this.emailContents,
this.attachments, this.attachments,
this.mailboxRole, this.mailboxRole,
required this.session, required this.session,
@@ -28,8 +28,7 @@ class ComposerArguments with EquatableMixin {
@override @override
List<Object?> get props => [ List<Object?> get props => [
emailActionType, emailActionType,
presentationEmail, emailContents,
emailContent,
attachments, attachments,
mailboxRole, mailboxRole,
session, session,
@@ -1,16 +0,0 @@
import 'package:core/core.dart';
class WebViewLoadingState extends UIState {
WebViewLoadingState();
@override
List<Object?> get props => [];
}
class WebViewLoadCompletedState extends UIState {
WebViewLoadCompletedState();
@override
List<Object?> get props => [];
}
@@ -0,0 +1,131 @@
import 'package:core/core.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
const List<Color> _defaultColors = [Color.fromRGBO(0, 0, 0, 0.1), Color(0x44CCCCCC), Color.fromRGBO(0, 0, 0, 0.1)];
Decoration _radiusBoxDecoration({
required Animation animation,
bool hasCustomColors = false,
AlignmentGeometry beginAlign = Alignment.topLeft,
AlignmentGeometry endAlign = Alignment.bottomRight,
List<Color> colors = _defaultColors,
double radius = 10.0
}) {
return BoxDecoration(
borderRadius: BorderRadius.circular(radius),
shape: BoxShape.rectangle,
gradient: LinearGradient(
begin: beginAlign,
end: endAlign,
colors: hasCustomColors
? colors.map((color) {
return color;
}).toList()
: [
Color.fromRGBO(0, 0, 0, 0.1),
Color(0x32E5E5E5),
Color.fromRGBO(0, 0, 0, 0.1),
],
stops: [animation.value - 2, animation.value, animation.value + 1]));
}
class AttachmentsPlaceHolderLoading extends StatefulWidget {
final ResponsiveUtils responsiveUtils;
const AttachmentsPlaceHolderLoading({
Key? key,
required this.responsiveUtils,
}) : super(key: key);
@override
State<StatefulWidget> createState() => _AttachmentsPlaceHolderLoadingState();
}
class _AttachmentsPlaceHolderLoadingState extends State<AttachmentsPlaceHolderLoading> with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_animationController = AnimationController(duration: Duration(seconds: 1), vsync: this)..repeat();
_animation = Tween<double>(begin: -2, end: 2)
.animate(CurvedAnimation(curve: Curves.easeInOutSine, parent: _animationController));
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animation,
builder: (BuildContext context, Widget? child) {
return Container(
margin: EdgeInsets.only(top: 20),
padding: EdgeInsets.zero,
color: Colors.transparent,
child: Column(
children: [
Row(children: [
_placeHolderAttachment(context),
SizedBox(width: 16),
_placeHolderAttachment(context),
if (!widget.responsiveUtils.isMobile(context))
SizedBox(width: 16),
if (!widget.responsiveUtils.isMobile(context))
_placeHolderAttachment(context),
if (widget.responsiveUtils.isTablet(context))
SizedBox(width: 16),
if (widget.responsiveUtils.isTablet(context))
_placeHolderAttachment(context),
]),
],
),
);
},
);
}
Widget _placeHolderAttachment(BuildContext context) {
double width = MediaQuery.of(context).size.width;
final percentAttachment = widget.responsiveUtils.isMobile(context)
? 0.4
: widget.responsiveUtils.isTablet(context) ? 0.22 : 0.14;
return Container(
height: 55,
width: width * percentAttachment,
margin: EdgeInsets.zero,
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16),
decoration: _radiusBoxDecoration(animation: _animation),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 24,
width: 24,
decoration: _radiusBoxDecoration(animation: _animation, radius: 12)),
SizedBox(width: 8),
Expanded(child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 5,
decoration: _radiusBoxDecoration(animation: _animation)),
SizedBox(height: 10),
Container(
height: 5,
decoration: _radiusBoxDecoration(animation: _animation))
],
))
]
)
);
}
}
@@ -0,0 +1,51 @@
import 'package:core/core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:model/model.dart';
class EmailContentItemBuilder {
final BuildContext _context;
final EmailContent _emailContent;
final Widget? loadingWidget;
EmailContentItemBuilder(
this._context,
this._emailContent,
{
this.loadingWidget
}
);
Widget build() {
return Theme(
data: ThemeData(
splashColor: Colors.transparent,
highlightColor: Colors.transparent),
child: MediaQuery(
data: MediaQueryData(padding: EdgeInsets.zero),
child: _buildItem()
)
);
}
Widget _buildItem() {
switch(_emailContent.type) {
case EmailContentType.textHtml:
return HtmlContentViewer(
widthContent: MediaQuery.of(_context).size.width,
contentHtml: _emailContent.content,
loadingWidget: loadingWidget,
mailtoDelegate: (uri) async {});
case EmailContentType.textPlain:
return Padding(
padding: EdgeInsets.zero,
child: Text(
_emailContent.content,
style: TextStyle(fontSize: 14, color: AppColor.nameUserColor)));
case EmailContentType.other:
return SizedBox.shrink();
}
}
}
@@ -41,7 +41,7 @@ class EmailContentPlaceHolderLoading extends StatefulWidget {
}) : super(key: key); }) : super(key: key);
@override @override
_EmailContentPlaceHolderLoadingState createState() => _EmailContentPlaceHolderLoadingState(); State<StatefulWidget> createState() => _EmailContentPlaceHolderLoadingState();
} }
class _EmailContentPlaceHolderLoadingState extends State<EmailContentPlaceHolderLoading> with SingleTickerProviderStateMixin { class _EmailContentPlaceHolderLoadingState extends State<EmailContentPlaceHolderLoading> with SingleTickerProviderStateMixin {
@@ -68,25 +68,11 @@ class _EmailContentPlaceHolderLoadingState extends State<EmailContentPlaceHolder
animation: _animation, animation: _animation,
builder: (BuildContext context, Widget? child) { builder: (BuildContext context, Widget? child) {
return Container( return Container(
margin: EdgeInsets.only(top: 20), margin: EdgeInsets.only(top: 16),
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
color: Colors.transparent, color: Colors.transparent,
child: Column( child: Column(
children: [ children: [
Row(children: [
_placeHolderAttachment(context),
SizedBox(width: 16),
_placeHolderAttachment(context),
if (!widget.responsiveUtils.isMobile(context))
SizedBox(width: 16),
if (!widget.responsiveUtils.isMobile(context))
_placeHolderAttachment(context),
if (widget.responsiveUtils.isTablet(context))
SizedBox(width: 16),
if (widget.responsiveUtils.isTablet(context))
_placeHolderAttachment(context),
]),
SizedBox(height: 16),
Container( Container(
margin: EdgeInsets.only(right: 64), margin: EdgeInsets.only(right: 64),
height: 10, height: 10,
@@ -106,40 +92,4 @@ class _EmailContentPlaceHolderLoadingState extends State<EmailContentPlaceHolder
}, },
); );
} }
Widget _placeHolderAttachment(BuildContext context) {
double width = MediaQuery.of(context).size.width;
final percentAttachment = widget.responsiveUtils.isMobile(context)
? 0.4
: widget.responsiveUtils.isTablet(context) ? 0.22 : 0.14;
return Container(
height: 55,
width: width * percentAttachment,
margin: EdgeInsets.zero,
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 16),
decoration: _radiusBoxDecoration(animation: _animation),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 24,
width: 24,
decoration: _radiusBoxDecoration(animation: _animation, radius: 12)),
SizedBox(width: 8),
Expanded(child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 5,
decoration: _radiusBoxDecoration(animation: _animation)),
SizedBox(height: 10),
Container(
height: 5,
decoration: _radiusBoxDecoration(animation: _animation))
],
))
]
)
);
}
} }