From 5a009f13e7612b64bda8872f03845eaadcb42587 Mon Sep 17 00:00:00 2001 From: dab246 Date: Mon, 28 Mar 2022 16:19:03 +0700 Subject: [PATCH] TF-335 Open links in another tab in email detail view on browser --- .../html_content_viewer_on_web_widget.dart | 52 +++++++++---- .../email/presentation/email_view.dart | 75 ++++++++++++------- .../widgets/email_content_item_builder.dart | 9 +-- 3 files changed, 87 insertions(+), 49 deletions(-) diff --git a/core/lib/presentation/views/html_viewer/html_content_viewer_on_web_widget.dart b/core/lib/presentation/views/html_viewer/html_content_viewer_on_web_widget.dart index f7d35749e..d907fb18e 100644 --- a/core/lib/presentation/views/html_viewer/html_content_viewer_on_web_widget.dart +++ b/core/lib/presentation/views/html_viewer/html_content_viewer_on_web_widget.dart @@ -1,14 +1,13 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:math'; +import 'dart:math' as math; import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/views/html_viewer/html_viewer_controller_for_web.dart'; +import 'package:core/utils/app_logger.dart'; import 'package:flutter/material.dart'; -import 'package:pointer_interceptor/pointer_interceptor.dart'; import 'package:universal_html/html.dart' as html; import 'package:core/presentation/utils/shims/dart_ui.dart' as ui; -import 'package:core/utils/app_logger.dart' as logger; class HtmlContentViewerOnWeb extends StatefulWidget { @@ -55,7 +54,7 @@ class _HtmlContentViewerOnWebState extends State { } String _getRandString(int len) { - var random = Random.secure(); + var random = math.Random.secure(); var values = List.generate(len, (i) => random.nextInt(255)); return base64UrlEncode(values); } @@ -64,6 +63,7 @@ class _HtmlContentViewerOnWebState extends State { final htmlScripts = ''' '''; @@ -102,7 +123,9 @@ class _HtmlContentViewerOnWebState extends State { min-height: ${minHeight}px; min-width: ${minWidth}px; color: #000000; - font-family: verdana; + font-family: Inter; + font-size: 16px; + font-style: normal; } table { width: 100%; @@ -137,6 +160,8 @@ class _HtmlContentViewerOnWebState extends State { ..srcdoc = _htmlData ?? '' ..style.border = 'none' ..style.overflow = 'hidden' + ..style.width = '100%' + ..style.height = '100%' ..onLoad.listen((event) async { final dataGetHeight = {'type': 'toIframe: getHeight', 'view' : createdViewId}; final dataGetWidth = {'type': 'toIframe: getWidth', 'view' : createdViewId}; @@ -145,9 +170,6 @@ class _HtmlContentViewerOnWebState extends State { final jsonGetHeight = jsonEncoder.convert(dataGetHeight); final jsonGetWidth = jsonEncoder.convert(dataGetWidth); - logger.log('HtmlContentViewerOnWeb() | onLoad | jsonGetHeight: $jsonGetHeight'); - logger.log('HtmlContentViewerOnWeb() | onLoad | jsonGetWidth: $jsonGetWidth'); - html.window.postMessage(jsonGetHeight, '*'); html.window.postMessage(jsonGetWidth, '*'); @@ -155,7 +177,6 @@ class _HtmlContentViewerOnWebState extends State { var data = json.decode(event.data); if (data['type'] != null && data['type'].contains('toDart: htmlHeight') && data['view'] == createdViewId) { final docHeight = data['height'] ?? actualHeight; - logger.log('HtmlContentViewerOnWeb() | onMessage | docHeight: $docHeight'); if (docHeight != null && mounted) { final scrollHeightWithBuffer = docHeight + 30.0; if (scrollHeightWithBuffer > minHeight) { @@ -174,7 +195,6 @@ class _HtmlContentViewerOnWebState extends State { if (data['type'] != null && data['type'].contains('toDart: htmlWidth') && data['view'] == createdViewId) { final docWidth = data['width'] ?? actualWidth; - logger.log('HtmlContentViewerOnWeb() | onMessage | docWidth: $docWidth'); if (docWidth != null && mounted) { if (docWidth > minWidth) { setState(() { @@ -192,6 +212,14 @@ class _HtmlContentViewerOnWebState extends State { curve: Curves.easeIn); } } + + if (data['type'] != null && data['type'].contains('toDart: OpenLink') && data['view'] == createdViewId) { + final link = data['url']; + if (link != null && mounted) { + log('_HtmlContentViewerOnWebState::_setUpWeb(): OpenLink: $link'); + html.window.open('$link', '_blank'); + } + } }); }); @@ -214,10 +242,6 @@ class _HtmlContentViewerOnWebState extends State { width: actualWidth, child: _buildWebView(), ), - PointerInterceptor(child: SizedBox( - height: actualHeight, - width: actualWidth, - )), if (_isLoading) _buildLoadingView() ], ); diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index cdf9ab8c9..2e96d9080 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -15,7 +15,6 @@ import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_fil 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/email_action_cupertino_action_sheet_action_builder.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/mailbox_dashboard/presentation/user_setting_popup_menu_mixin.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; @@ -156,19 +155,27 @@ class EmailView extends GetView with UserSettingPopupMenuMixin { color: Colors.white, margin: EdgeInsets.zero, alignment: Alignment.topCenter, - child: Obx(() => emailController.currentEmail != null - ? SingleChildScrollView( - physics : ClampingScrollPhysics(), - child: Container( - margin: EdgeInsets.zero, - width: double.infinity, - alignment: Alignment.center, - padding: EdgeInsets.zero, - color: Colors.white, - child: _buildEmailMessage(context) - )) - : Center(child: _buildEmailEmpty(context)) - ) + child: Obx(() { + if (emailController.currentEmail != null) { + if (kIsWeb) { + return _buildEmailMessage(context); + } else { + return SingleChildScrollView( + physics : ClampingScrollPhysics(), + child: Container( + margin: EdgeInsets.zero, + width: double.infinity, + alignment: Alignment.center, + padding: EdgeInsets.zero, + color: Colors.white, + child: _buildEmailMessage(context) + ) + ); + } + } else { + return Center(child: _buildEmailEmpty(context)); + } + }) ); } @@ -184,6 +191,9 @@ class EmailView extends GetView with UserSettingPopupMenuMixin { padding: EdgeInsets.only(right: 16), child: SelectableText( '${emailController.mailboxDashBoardController.selectedEmail.value?.getEmailTitle()}', + maxLines: 3, + minLines: 1, + cursorColor: AppColor.colorTextButton, style: TextStyle( fontSize: 20, color: AppColor.colorNameEmail, @@ -193,15 +203,12 @@ class EmailView extends GetView with UserSettingPopupMenuMixin { Widget _buildEmailMessage(BuildContext context) { return Container( - padding: EdgeInsets.only(bottom: 16, left: 16, right: 16, top: 10), + padding: EdgeInsets.only(left: 16, right: 16, top: 10), alignment: Alignment.center, color: Colors.white, child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { return Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, children: [ Row( crossAxisAlignment: CrossAxisAlignment.end, @@ -220,7 +227,10 @@ class EmailView extends GetView with UserSettingPopupMenuMixin { : SizedBox.shrink()), _buildDivider(edgeInsets: EdgeInsets.only(top: 8)), _buildAttachments(context), - _buildListEmailContent(context, constraints), + if (kIsWeb) + Expanded(child: _buildEmailContent(context, constraints)) + else + _buildEmailContent(context, constraints), ], ); }) @@ -502,7 +512,7 @@ class EmailView extends GetView with UserSettingPopupMenuMixin { ); } - Widget _buildListEmailContent(BuildContext context, BoxConstraints constraints) { + Widget _buildEmailContent(BuildContext context, BoxConstraints constraints) { return Obx(() => emailController.viewState.value.fold( (failure) => SizedBox.shrink(), (success) { @@ -510,14 +520,23 @@ class EmailView extends GetView with UserSettingPopupMenuMixin { return EmailContentPlaceHolderLoading(responsiveUtils: responsiveUtils); } else { if (emailController.emailContents.isNotEmpty) { - return Column(children: [ - ...emailController.emailContents.map((content) => EmailContentItemBuilder( - context, - content, - constraints, - loadingWidget: EmailContentPlaceHolderLoading(responsiveUtils: responsiveUtils) - ).build()).toList(), - ]); + final allEmailContents = emailController.emailContents + .map((emailContent) => emailContent.asHtml) + .toList() + .join('
'); + + if (kIsWeb) { + return HtmlContentViewerOnWeb( + widthContent: constraints.maxWidth, + heightContent: MediaQuery.of(context).size.height, + contentHtml: allEmailContents, + controller: HtmlViewerControllerForWeb()); + } else { + return HtmlContentViewer( + widthContent: MediaQuery.of(context).size.width, + contentHtml: allEmailContents, + loadingWidget: EmailContentPlaceHolderLoading(responsiveUtils: responsiveUtils)); + } } else { return SizedBox.shrink(); } diff --git a/lib/features/email/presentation/widgets/email_content_item_builder.dart b/lib/features/email/presentation/widgets/email_content_item_builder.dart index 4ba10367e..3dab7825b 100644 --- a/lib/features/email/presentation/widgets/email_content_item_builder.dart +++ b/lib/features/email/presentation/widgets/email_content_item_builder.dart @@ -33,19 +33,14 @@ class EmailContentItemBuilder { } Widget _buildItem() { - log('EmailContentItemBuilder() | maxWidth: ${_constraints.maxWidth}'); - log('EmailContentItemBuilder() | heightScreen: ${MediaQuery.of(_context).size.height}'); switch(_emailContent.type) { case EmailContentType.textHtml: if (kIsWeb) { - return SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: HtmlContentViewerOnWeb( + return HtmlContentViewerOnWeb( widthContent: _constraints.maxWidth, heightContent: MediaQuery.of(_context).size.height, contentHtml: _emailContent.content, - controller: HtmlViewerControllerForWeb()), - ); + controller: HtmlViewerControllerForWeb()); } else { return HtmlContentViewer( widthContent: MediaQuery.of(_context).size.width,