From 8100e886d7ec14bd5369e5ff0d086186b7d63ab2 Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 9 Jul 2025 16:06:22 +0700 Subject: [PATCH] Support vertical scrolling email view when cursor is over calendar event description Signed-off-by: dab246 --- .../utils/html_transformer/sanitize_url.dart | 1 - core/lib/utils/string_convert.dart | 1 - .../email/presentation/email_view.dart | 169 ++++++++++-------- ...vent_description_detail_widget_styles.dart | 1 - .../calendar_event_detail_widget.dart | 3 - .../event_body_content_widget.dart | 40 +---- 6 files changed, 105 insertions(+), 110 deletions(-) diff --git a/core/lib/presentation/utils/html_transformer/sanitize_url.dart b/core/lib/presentation/utils/html_transformer/sanitize_url.dart index 4fba06903..af1c4d12c 100644 --- a/core/lib/presentation/utils/html_transformer/sanitize_url.dart +++ b/core/lib/presentation/utils/html_transformer/sanitize_url.dart @@ -14,7 +14,6 @@ class SanitizeUrl { String process(String inputText) { try { - log('SanitizeUrl::process:inputText = $inputText'); var originalUrl = Uri.decodeFull(inputText); if (GetUtils.isURL(originalUrl)) { originalUrl = !originalUrl.startsWith(_protocolIdentifierRegex) diff --git a/core/lib/utils/string_convert.dart b/core/lib/utils/string_convert.dart index 9fdaee664..6c980354b 100644 --- a/core/lib/utils/string_convert.dart +++ b/core/lib/utils/string_convert.dart @@ -113,7 +113,6 @@ class StringConvert { try { final emailDocument = parse(content); final contentOriginal = emailDocument.body?.innerHtml ?? content; - log('StringConvert::getContentOriginal:contentOriginal = $contentOriginal'); return contentOriginal; } catch (e) { logError('StringConvert::getContentOriginal:Exception = $e'); diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index 2d3c92127..bf28d07ce 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -139,76 +139,12 @@ class EmailView extends GetWidget { OptionalExpanded( expandedEnabled: !isInsideThreadDetailView, child: LayoutBuilder(builder: (context, constraints) { - if (PlatformInfo.isMobile) { - return OptionalScroll( - scrollEnabled: !isInsideThreadDetailView, - child: Container( - width: double.infinity, - alignment: Alignment.center, - color: Colors.white, - child: Obx( - () => _buildEmailMessage( - context: context, - presentationEmail: currentEmail, - calendarEvent: controller.calendarEvent, - bodyConstraints: constraints, - ), - ), - ), - ); - } else { - return Obx(() { - final calendarEvent = controller.calendarEvent; - if (currentEmail.hasCalendarEvent && calendarEvent != null) { - return Padding( - padding: const EdgeInsetsDirectional.symmetric( - horizontal: 4, - ), - child: OptionalScroll( - scrollEnabled: !isInsideThreadDetailView, - child: Container( - width: double.infinity, - alignment: Alignment.center, - color: Colors.white, - child: _buildEmailMessage( - context: context, - presentationEmail: currentEmail, - calendarEvent: calendarEvent, - emailAddressSender: currentEmail.listEmailAddressSender.getListAddress(), - bodyConstraints: constraints, - ), - ), - ), - ); - } else { - return Stack( - children: [ - OptionalScroll( - scrollEnabled: !isInsideThreadDetailView, - scrollPhysics : const ClampingScrollPhysics(), - child: _buildEmailMessage( - context: context, - presentationEmail: currentEmail, - bodyConstraints: constraints, - ), - ), - Obx(() { - if (controller.mailboxDashBoardController.isDisplayedOverlayViewOnIFrame) { - return PointerInterceptor( - child: SizedBox( - width: constraints.maxWidth, - height: constraints.maxHeight, - ), - ); - } else { - return const SizedBox.shrink(); - } - }), - ], - ); - } - }); - } + return _buildBodyWidget( + context, + currentEmail, + constraints, + scrollController: scrollController, + ); }), ), Obx(() { @@ -291,6 +227,7 @@ class EmailView extends GetWidget { required BoxConstraints bodyConstraints, CalendarEvent? calendarEvent, List? emailAddressSender, + ScrollController? scrollController, }) { return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -398,7 +335,6 @@ class EmailView extends GetWidget { Obx(() => CalendarEventDetailWidget( calendarEvent: calendarEvent, emailContent: controller.currentEmailLoaded.value?.htmlContent ?? '', - isDraggableAppActive: controller.mailboxDashBoardController.isAttachmentDraggableAppActive, onMailtoDelegateAction: controller.openMailToLink, presentationEmail: controller.currentEmail, scrollController: scrollController, @@ -554,4 +490,95 @@ class EmailView extends GetWidget { return usernameEvent.isNotEmpty && titleEvent.isNotEmpty; } + + Widget _buildMobileBodyWidget( + BuildContext context, + PresentationEmail currentEmail, + BoxConstraints constraints, + ) { + return OptionalScroll( + scrollEnabled: !isInsideThreadDetailView, + child: Container( + width: double.infinity, + alignment: Alignment.center, + color: Colors.white, + child: Obx(() => _buildEmailMessage( + context: context, + presentationEmail: currentEmail, + calendarEvent: controller.calendarEvent, + bodyConstraints: constraints, + )) + ) + ); + } + + Widget _buildWebBodyWidget( + BuildContext context, + PresentationEmail currentEmail, + BoxConstraints constraints, { + required ScrollController? scrollController + }) { + return Obx(() { + final calendarEvent = controller.calendarEvent; + + final emailContentWidget = Stack( + children: [ + OptionalScroll( + scrollEnabled: !isInsideThreadDetailView, + scrollPhysics : const ClampingScrollPhysics(), + child: _buildEmailMessage( + context: context, + presentationEmail: currentEmail, + bodyConstraints: constraints, + scrollController: scrollController, + calendarEvent: calendarEvent, + emailAddressSender: currentEmail.listEmailAddressSender.getListAddress(), + ), + ), + Obx(() { + if (controller.mailboxDashBoardController.isDisplayedOverlayViewOnIFrame) { + return Positioned.fill( + child: PointerInterceptor( + child: const SizedBox.expand(), + ), + ); + } else { + return const SizedBox.shrink(); + } + }), + ], + ); + + if (calendarEvent != null) { + return Padding( + padding: const EdgeInsetsDirectional.symmetric(horizontal: 4), + child: emailContentWidget, + ); + } else { + return emailContentWidget; + } + }); + } + + Widget _buildBodyWidget( + BuildContext context, + PresentationEmail currentEmail, + BoxConstraints constraints, { + required ScrollController? scrollController, + }) { + if (PlatformInfo.isWeb) { + return _buildWebBodyWidget( + context, + currentEmail, + constraints, + scrollController: scrollController, + ); + } else { + return _buildMobileBodyWidget( + context, + currentEmail, + constraints, + ); + } + } } \ No newline at end of file diff --git a/lib/features/email/presentation/styles/event_description_detail_widget_styles.dart b/lib/features/email/presentation/styles/event_description_detail_widget_styles.dart index c2dba45a2..35133683a 100644 --- a/lib/features/email/presentation/styles/event_description_detail_widget_styles.dart +++ b/lib/features/email/presentation/styles/event_description_detail_widget_styles.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; class EventDescriptionDetailWidgetStyles { static const double textSize = 16; - static const double maxHeight = 200; static const double borderRadius = 16; static const double contentPadding = 16; static const double quotedPadding = 8; diff --git a/lib/features/email/presentation/widgets/calendar_event/calendar_event_detail_widget.dart b/lib/features/email/presentation/widgets/calendar_event/calendar_event_detail_widget.dart index cbdd7bf22..c952befdc 100644 --- a/lib/features/email/presentation/widgets/calendar_event/calendar_event_detail_widget.dart +++ b/lib/features/email/presentation/widgets/calendar_event/calendar_event_detail_widget.dart @@ -14,7 +14,6 @@ class CalendarEventDetailWidget extends StatelessWidget { final CalendarEvent calendarEvent; final String emailContent; - final bool? isDraggableAppActive; final OnMailtoDelegateAction? onMailtoDelegateAction; final PresentationEmail? presentationEmail; final ScrollController? scrollController; @@ -24,7 +23,6 @@ class CalendarEventDetailWidget extends StatelessWidget { super.key, required this.calendarEvent, required this.emailContent, - this.isDraggableAppActive, this.onMailtoDelegateAction, this.presentationEmail, this.scrollController, @@ -64,7 +62,6 @@ class CalendarEventDetailWidget extends StatelessWidget { padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding), child: EventBodyContentWidget( content: eventDesc, - isDraggableAppActive: isDraggableAppActive, onMailtoDelegateAction: onMailtoDelegateAction, scrollController: scrollController, isInsideThreadDetailView: isInsideThreadDetailView, diff --git a/lib/features/email/presentation/widgets/calendar_event/event_body_content_widget.dart b/lib/features/email/presentation/widgets/calendar_event/event_body_content_widget.dart index f70b4b2e2..388f059e4 100644 --- a/lib/features/email/presentation/widgets/calendar_event/event_body_content_widget.dart +++ b/lib/features/email/presentation/widgets/calendar_event/event_body_content_widget.dart @@ -1,5 +1,3 @@ -import 'dart:math'; - import 'package:core/presentation/constants/constants_ui.dart'; import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/resources/image_paths.dart'; @@ -9,15 +7,12 @@ import 'package:core/utils/platform_info.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:get/get.dart'; -import 'package:pointer_interceptor/pointer_interceptor.dart'; -import 'package:tmail_ui_user/features/email/presentation/styles/email_view_styles.dart'; import 'package:tmail_ui_user/features/email/presentation/styles/event_description_detail_widget_styles.dart'; import 'package:tmail_ui_user/main/utils/app_utils.dart'; class EventBodyContentWidget extends StatelessWidget { final String content; - final bool? isDraggableAppActive; final OnMailtoDelegateAction? onMailtoDelegateAction; final ScrollController? scrollController; final bool isInsideThreadDetailView; @@ -25,7 +20,6 @@ class EventBodyContentWidget extends StatelessWidget { const EventBodyContentWidget({ super.key, required this.content, - this.isDraggableAppActive, this.onMailtoDelegateAction, this.scrollController, this.isInsideThreadDetailView = false, @@ -50,35 +44,15 @@ class EventBodyContentWidget extends StatelessWidget { child: Stack( children: [ if (PlatformInfo.isWeb) - Container( - constraints: isInsideThreadDetailView - ? null - : const BoxConstraints( - maxHeight: EventDescriptionDetailWidgetStyles.maxHeight, - ), + Padding( padding: const EdgeInsetsDirectional.only(end: EventDescriptionDetailWidgetStyles.webContentPadding), child: LayoutBuilder(builder: (context, constraints) { - return Stack( - children: [ - HtmlContentViewerOnWeb( - widthContent: constraints.maxWidth, - heightContent: min( - constraints.maxHeight, - EmailViewStyles.initialHtmlViewHeight, - ), - contentHtml: content, - mailtoDelegate: onMailtoDelegateAction, - direction: AppUtils.getCurrentDirection(context), - scrollController: scrollController, - ), - if (isDraggableAppActive == true) - PointerInterceptor( - child: SizedBox( - width: constraints.maxWidth, - height: constraints.maxHeight, - ) - ) - ], + return HtmlContentViewerOnWeb( + widthContent: constraints.maxWidth, + contentHtml: content, + mailtoDelegate: onMailtoDelegateAction, + direction: AppUtils.getCurrentDirection(context), + scrollController: scrollController, ); }) )