TF-185 [BUG] Fix can not display all parts of email which have multiple html part
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import 'package:core/core.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -8,6 +9,8 @@ class HtmlContentViewer extends StatefulWidget {
|
||||
|
||||
final String contentHtml;
|
||||
final int minHeight;
|
||||
final double widthContent;
|
||||
final Widget? loadingWidget;
|
||||
|
||||
/// Register this callback if you want a reference to the [InAppWebViewController].
|
||||
final void Function(InAppWebViewController controller)? onCreated;
|
||||
@@ -22,7 +25,9 @@ class HtmlContentViewer extends StatefulWidget {
|
||||
const HtmlContentViewer({
|
||||
Key? key,
|
||||
required this.contentHtml,
|
||||
required this.widthContent,
|
||||
this.minHeight = 100,
|
||||
this.loadingWidget,
|
||||
this.onCreated,
|
||||
this.onLoadStart,
|
||||
this.onLoadStop,
|
||||
@@ -39,6 +44,7 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
|
||||
double? _documentWidth = 1.0;
|
||||
String? _initialPageContent;
|
||||
late InAppWebViewController _webViewController;
|
||||
bool loading = true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -101,15 +107,33 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final size = MediaQuery.of(context).size;
|
||||
_documentWidth = size.width - 30;
|
||||
return SizedBox(
|
||||
height: _documentHeight,
|
||||
width: _documentWidth,
|
||||
child: _buildWebView(),
|
||||
_documentWidth = widget.widthContent;
|
||||
return Stack(
|
||||
alignment: AlignmentDirectional.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
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() {
|
||||
if (_initialPageContent == null || _initialPageContent?.isEmpty == true) {
|
||||
return Container();
|
||||
@@ -148,6 +172,9 @@ class _HtmlContentViewState extends State<HtmlContentViewer> {
|
||||
_documentHeight = (scrollHeight + 30.0);
|
||||
});
|
||||
}
|
||||
setState(() {
|
||||
loading = false;
|
||||
});
|
||||
if (widget.onLoadStop != null) {
|
||||
widget.onLoadStop!(controller, uri);
|
||||
}
|
||||
|
||||
@@ -214,7 +214,10 @@ class ComposerController extends BaseController {
|
||||
.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>';
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
import 'package:model/model.dart';
|
||||
|
||||
abstract class HtmlDataSource {
|
||||
Future<String> transformToHtml(EmailContent emailContent);
|
||||
Future<EmailContent> transformEmailContent(EmailContent emailContent);
|
||||
}
|
||||
@@ -9,9 +9,9 @@ class HtmlDataSourceImpl extends HtmlDataSource {
|
||||
HtmlDataSourceImpl(this._htmlAnalyzer);
|
||||
|
||||
@override
|
||||
Future<String> transformToHtml(EmailContent emailContent) {
|
||||
Future<EmailContent> transformEmailContent(EmailContent emailContent) {
|
||||
return Future.sync(() async {
|
||||
return await _htmlAnalyzer.transformToHtml(emailContent);
|
||||
return await _htmlAnalyzer.transformEmailContent(emailContent);
|
||||
}).catchError((error) {
|
||||
throw error;
|
||||
});
|
||||
|
||||
@@ -5,13 +5,14 @@ import 'package:model/model.dart';
|
||||
|
||||
class HtmlAnalyzer {
|
||||
|
||||
Future<String> transformToHtml(EmailContent emailContent) async {
|
||||
Future<EmailContent> transformEmailContent(EmailContent emailContent) async {
|
||||
switch(emailContent.type) {
|
||||
case EmailContentType.textHtml:
|
||||
final htmlTransform = HtmlTransform(emailContent.content);
|
||||
return htmlTransform.transformToHtml();
|
||||
final htmlContent = htmlTransform.transformToHtml();
|
||||
return EmailContent(emailContent.type, htmlContent);
|
||||
default:
|
||||
return emailContent.content;
|
||||
return emailContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,11 @@ class EmailRepositoryImpl extends EmailRepository {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<String> transformEmailContentToHtml(EmailContent emailContent) {
|
||||
return _htmlDataSource.transformToHtml(emailContent);
|
||||
Future<List<EmailContent>> transformEmailContent(List<EmailContent> emailContents) async {
|
||||
return await Future.wait(emailContents
|
||||
.map((emailContent) async {
|
||||
return await _htmlDataSource.transformEmailContent(emailContent);
|
||||
})
|
||||
.toList());
|
||||
}
|
||||
}
|
||||
@@ -35,5 +35,5 @@ abstract class EmailRepository {
|
||||
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';
|
||||
|
||||
class GetEmailContentSuccess extends UIState {
|
||||
final EmailContent emailContent;
|
||||
final List<EmailContent> emailContents;
|
||||
final List<Attachment> attachments;
|
||||
|
||||
GetEmailContentSuccess(this.emailContent, this.attachments);
|
||||
GetEmailContentSuccess(this.emailContents, this.attachments);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [emailContent, attachments];
|
||||
List<Object?> get props => [emailContents, attachments];
|
||||
}
|
||||
|
||||
class GetEmailContentFailure extends FeatureFailure {
|
||||
|
||||
@@ -17,15 +17,8 @@ class GetEmailContentInteractor {
|
||||
final email = await emailRepository.getEmailContent(accountId, emailId);
|
||||
|
||||
if (email.emailContentList.isNotEmpty) {
|
||||
final emailContent = email.emailContentList.first;
|
||||
if (emailContent.type == EmailContentType.textHtml) {
|
||||
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));
|
||||
}
|
||||
final newEmailContents = await emailRepository.transformEmailContent(email.emailContentList);
|
||||
yield Right<Failure, Success>(GetEmailContentSuccess(newEmailContents, email.allAttachments));
|
||||
} else {
|
||||
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/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/web_view_state.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/routes/app_routes.dart';
|
||||
@@ -49,7 +48,7 @@ class EmailController extends BaseController {
|
||||
|
||||
final emailAddressExpandMode = ExpandMode.COLLAPSE.obs;
|
||||
final attachmentsExpandMode = ExpandMode.COLLAPSE.obs;
|
||||
final emailContent = Rxn<EmailContent>();
|
||||
final emailContents = <EmailContent>[].obs;
|
||||
final attachments = <Attachment>[].obs;
|
||||
EmailId? _currentEmailId;
|
||||
|
||||
@@ -129,17 +128,14 @@ class EmailController extends BaseController {
|
||||
}
|
||||
|
||||
void _getEmailContentSuccess(GetEmailContentSuccess success) {
|
||||
emailContent.value = success.emailContent;
|
||||
emailContents.value = success.emailContents;
|
||||
attachments.value = success.attachments;
|
||||
if (emailContent.value != null && emailContent.value!.type == EmailContentType.textHtml) {
|
||||
dispatchState(Right(WebViewLoadingState()));
|
||||
}
|
||||
}
|
||||
|
||||
void _clearEmailContent() {
|
||||
toggleDisplayEmailAddressAction(expandMode: ExpandMode.COLLAPSE);
|
||||
attachmentsExpandMode.value = ExpandMode.COLLAPSE;
|
||||
emailContent.value = null;
|
||||
emailContents.clear();
|
||||
attachments.clear();
|
||||
}
|
||||
|
||||
@@ -357,7 +353,7 @@ class EmailController extends BaseController {
|
||||
arguments: ComposerArguments(
|
||||
emailActionType: emailActionType,
|
||||
presentationEmail: mailboxDashBoardController.selectedEmail.value!,
|
||||
emailContent: emailContent.value,
|
||||
emailContents: emailContents,
|
||||
attachments: attachments,
|
||||
mailboxRole: mailboxDashBoardController.selectedMailbox.value?.role,
|
||||
session: mailboxDashBoardController.sessionCurrent!,
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:core/core.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flutter/cupertino.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/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/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/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/sender_and_receiver_information_tile_builder.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
@@ -27,21 +27,17 @@ class EmailView extends GetView {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
backgroundColor: AppColor.primaryLightColor,
|
||||
body: SafeArea(
|
||||
right: false,
|
||||
left: false,
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
_buildAppBar(context),
|
||||
Expanded(child: _buildEmailBody(context)),
|
||||
_buildBottomBar(context),
|
||||
])
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
_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) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(left: 12, right: 12, top: 16, bottom: 16),
|
||||
@@ -143,9 +131,8 @@ class EmailView extends GetView {
|
||||
emailController.emailAddressExpandMode.value)
|
||||
.onOpenExpandAddressReceiverActionClick(() => emailController.toggleDisplayEmailAddressAction(expandMode: ExpandMode.EXPAND))
|
||||
.build()),
|
||||
_buildLoadingView(),
|
||||
_buildAttachments(context),
|
||||
_buildEmailContent(),
|
||||
_buildListEmailContent(),
|
||||
],
|
||||
)
|
||||
);
|
||||
@@ -155,8 +142,8 @@ class EmailView extends GetView {
|
||||
return Obx(() => emailController.viewState.value.fold(
|
||||
(failure) => SizedBox.shrink(),
|
||||
(success) {
|
||||
if (success is LoadingState || success is WebViewLoadingState) {
|
||||
return SizedBox.shrink();
|
||||
if (success is LoadingState) {
|
||||
return AttachmentsPlaceHolderLoading(responsiveUtils: responsiveUtils);
|
||||
} else {
|
||||
final attachments = emailController.attachments.attachmentsWithDispositionAttachment;
|
||||
return attachments.isNotEmpty
|
||||
@@ -272,28 +259,30 @@ class EmailView extends GetView {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildEmailContent() {
|
||||
return Obx(() {
|
||||
if (emailController.emailContent.value != null) {
|
||||
switch(emailController.emailContent.value!.type) {
|
||||
case EmailContentType.textHtml:
|
||||
return HtmlContentViewer(
|
||||
contentHtml: emailController.emailContent.value!.content,
|
||||
onLoadStart: (webController, uri) => emailController.dispatchState(Right(WebViewLoadingState())),
|
||||
onLoadStop: (webController, uri) => emailController.dispatchState(Right(WebViewLoadCompletedState())),
|
||||
mailtoDelegate: (uri) async {});
|
||||
case EmailContentType.textPlain:
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(top: 16),
|
||||
child: Text(
|
||||
emailController.emailContent.value!.content,
|
||||
style: TextStyle(fontSize: 14, color: AppColor.nameUserColor)));
|
||||
case EmailContentType.other:
|
||||
Widget _buildListEmailContent() {
|
||||
return Obx(() => emailController.viewState.value.fold(
|
||||
(failure) => SizedBox.shrink(),
|
||||
(success) {
|
||||
if (success is LoadingState) {
|
||||
return EmailContentPlaceHolderLoading(responsiveUtils: responsiveUtils);
|
||||
} else {
|
||||
if (emailController.emailContents.isNotEmpty) {
|
||||
return ListView.builder(
|
||||
primary: false,
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
key: Key('list_email_content'),
|
||||
itemCount: emailController.emailContents.length,
|
||||
itemBuilder: (context, index) =>
|
||||
EmailContentItemBuilder(
|
||||
context,
|
||||
emailController.emailContents[index],
|
||||
loadingWidget: EmailContentPlaceHolderLoading(responsiveUtils: responsiveUtils)
|
||||
).build());
|
||||
} else {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import 'package:model/model.dart';
|
||||
class ComposerArguments with EquatableMixin {
|
||||
final EmailActionType emailActionType;
|
||||
final PresentationEmail? presentationEmail;
|
||||
final EmailContent? emailContent;
|
||||
final List<EmailContent>? emailContents;
|
||||
final List<Attachment>? attachments;
|
||||
final Session session;
|
||||
final UserProfile userProfile;
|
||||
@@ -17,7 +17,7 @@ class ComposerArguments with EquatableMixin {
|
||||
ComposerArguments({
|
||||
this.emailActionType = EmailActionType.compose,
|
||||
this.presentationEmail,
|
||||
this.emailContent,
|
||||
this.emailContents,
|
||||
this.attachments,
|
||||
this.mailboxRole,
|
||||
required this.session,
|
||||
@@ -28,8 +28,7 @@ class ComposerArguments with EquatableMixin {
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
emailActionType,
|
||||
presentationEmail,
|
||||
emailContent,
|
||||
emailContents,
|
||||
attachments,
|
||||
mailboxRole,
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-52
@@ -41,7 +41,7 @@ class EmailContentPlaceHolderLoading extends StatefulWidget {
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_EmailContentPlaceHolderLoadingState createState() => _EmailContentPlaceHolderLoadingState();
|
||||
State<StatefulWidget> createState() => _EmailContentPlaceHolderLoadingState();
|
||||
}
|
||||
|
||||
class _EmailContentPlaceHolderLoadingState extends State<EmailContentPlaceHolderLoading> with SingleTickerProviderStateMixin {
|
||||
@@ -68,25 +68,11 @@ class _EmailContentPlaceHolderLoadingState extends State<EmailContentPlaceHolder
|
||||
animation: _animation,
|
||||
builder: (BuildContext context, Widget? child) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(top: 20),
|
||||
margin: EdgeInsets.only(top: 16),
|
||||
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),
|
||||
]),
|
||||
SizedBox(height: 16),
|
||||
Container(
|
||||
margin: EdgeInsets.only(right: 64),
|
||||
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))
|
||||
],
|
||||
))
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user