Support vertical scrolling email view when cursor is over calendar event description

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-07-09 16:06:22 +07:00
committed by Dat H. Pham
parent a4d7fec6e1
commit 8100e886d7
6 changed files with 105 additions and 110 deletions
@@ -14,7 +14,6 @@ class SanitizeUrl {
String process(String inputText) { String process(String inputText) {
try { try {
log('SanitizeUrl::process:inputText = $inputText');
var originalUrl = Uri.decodeFull(inputText); var originalUrl = Uri.decodeFull(inputText);
if (GetUtils.isURL(originalUrl)) { if (GetUtils.isURL(originalUrl)) {
originalUrl = !originalUrl.startsWith(_protocolIdentifierRegex) originalUrl = !originalUrl.startsWith(_protocolIdentifierRegex)
-1
View File
@@ -113,7 +113,6 @@ class StringConvert {
try { try {
final emailDocument = parse(content); final emailDocument = parse(content);
final contentOriginal = emailDocument.body?.innerHtml ?? content; final contentOriginal = emailDocument.body?.innerHtml ?? content;
log('StringConvert::getContentOriginal:contentOriginal = $contentOriginal');
return contentOriginal; return contentOriginal;
} catch (e) { } catch (e) {
logError('StringConvert::getContentOriginal:Exception = $e'); logError('StringConvert::getContentOriginal:Exception = $e');
+98 -71
View File
@@ -139,76 +139,12 @@ class EmailView extends GetWidget<SingleEmailController> {
OptionalExpanded( OptionalExpanded(
expandedEnabled: !isInsideThreadDetailView, expandedEnabled: !isInsideThreadDetailView,
child: LayoutBuilder(builder: (context, constraints) { child: LayoutBuilder(builder: (context, constraints) {
if (PlatformInfo.isMobile) { return _buildBodyWidget(
return OptionalScroll( context,
scrollEnabled: !isInsideThreadDetailView, currentEmail,
child: Container( constraints,
width: double.infinity, scrollController: scrollController,
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();
}
}),
],
);
}
});
}
}), }),
), ),
Obx(() { Obx(() {
@@ -291,6 +227,7 @@ class EmailView extends GetWidget<SingleEmailController> {
required BoxConstraints bodyConstraints, required BoxConstraints bodyConstraints,
CalendarEvent? calendarEvent, CalendarEvent? calendarEvent,
List<String>? emailAddressSender, List<String>? emailAddressSender,
ScrollController? scrollController,
}) { }) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@@ -398,7 +335,6 @@ class EmailView extends GetWidget<SingleEmailController> {
Obx(() => CalendarEventDetailWidget( Obx(() => CalendarEventDetailWidget(
calendarEvent: calendarEvent, calendarEvent: calendarEvent,
emailContent: controller.currentEmailLoaded.value?.htmlContent ?? '', emailContent: controller.currentEmailLoaded.value?.htmlContent ?? '',
isDraggableAppActive: controller.mailboxDashBoardController.isAttachmentDraggableAppActive,
onMailtoDelegateAction: controller.openMailToLink, onMailtoDelegateAction: controller.openMailToLink,
presentationEmail: controller.currentEmail, presentationEmail: controller.currentEmail,
scrollController: scrollController, scrollController: scrollController,
@@ -554,4 +490,95 @@ class EmailView extends GetWidget<SingleEmailController> {
return usernameEvent.isNotEmpty && titleEvent.isNotEmpty; 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,
);
}
}
} }
@@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
class EventDescriptionDetailWidgetStyles { class EventDescriptionDetailWidgetStyles {
static const double textSize = 16; static const double textSize = 16;
static const double maxHeight = 200;
static const double borderRadius = 16; static const double borderRadius = 16;
static const double contentPadding = 16; static const double contentPadding = 16;
static const double quotedPadding = 8; static const double quotedPadding = 8;
@@ -14,7 +14,6 @@ class CalendarEventDetailWidget extends StatelessWidget {
final CalendarEvent calendarEvent; final CalendarEvent calendarEvent;
final String emailContent; final String emailContent;
final bool? isDraggableAppActive;
final OnMailtoDelegateAction? onMailtoDelegateAction; final OnMailtoDelegateAction? onMailtoDelegateAction;
final PresentationEmail? presentationEmail; final PresentationEmail? presentationEmail;
final ScrollController? scrollController; final ScrollController? scrollController;
@@ -24,7 +23,6 @@ class CalendarEventDetailWidget extends StatelessWidget {
super.key, super.key,
required this.calendarEvent, required this.calendarEvent,
required this.emailContent, required this.emailContent,
this.isDraggableAppActive,
this.onMailtoDelegateAction, this.onMailtoDelegateAction,
this.presentationEmail, this.presentationEmail,
this.scrollController, this.scrollController,
@@ -64,7 +62,6 @@ class CalendarEventDetailWidget extends StatelessWidget {
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding), padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventBodyContentWidget( child: EventBodyContentWidget(
content: eventDesc, content: eventDesc,
isDraggableAppActive: isDraggableAppActive,
onMailtoDelegateAction: onMailtoDelegateAction, onMailtoDelegateAction: onMailtoDelegateAction,
scrollController: scrollController, scrollController: scrollController,
isInsideThreadDetailView: isInsideThreadDetailView, isInsideThreadDetailView: isInsideThreadDetailView,
@@ -1,5 +1,3 @@
import 'dart:math';
import 'package:core/presentation/constants/constants_ui.dart'; import 'package:core/presentation/constants/constants_ui.dart';
import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.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/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: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/features/email/presentation/styles/event_description_detail_widget_styles.dart';
import 'package:tmail_ui_user/main/utils/app_utils.dart'; import 'package:tmail_ui_user/main/utils/app_utils.dart';
class EventBodyContentWidget extends StatelessWidget { class EventBodyContentWidget extends StatelessWidget {
final String content; final String content;
final bool? isDraggableAppActive;
final OnMailtoDelegateAction? onMailtoDelegateAction; final OnMailtoDelegateAction? onMailtoDelegateAction;
final ScrollController? scrollController; final ScrollController? scrollController;
final bool isInsideThreadDetailView; final bool isInsideThreadDetailView;
@@ -25,7 +20,6 @@ class EventBodyContentWidget extends StatelessWidget {
const EventBodyContentWidget({ const EventBodyContentWidget({
super.key, super.key,
required this.content, required this.content,
this.isDraggableAppActive,
this.onMailtoDelegateAction, this.onMailtoDelegateAction,
this.scrollController, this.scrollController,
this.isInsideThreadDetailView = false, this.isInsideThreadDetailView = false,
@@ -50,35 +44,15 @@ class EventBodyContentWidget extends StatelessWidget {
child: Stack( child: Stack(
children: [ children: [
if (PlatformInfo.isWeb) if (PlatformInfo.isWeb)
Container( Padding(
constraints: isInsideThreadDetailView
? null
: const BoxConstraints(
maxHeight: EventDescriptionDetailWidgetStyles.maxHeight,
),
padding: const EdgeInsetsDirectional.only(end: EventDescriptionDetailWidgetStyles.webContentPadding), padding: const EdgeInsetsDirectional.only(end: EventDescriptionDetailWidgetStyles.webContentPadding),
child: LayoutBuilder(builder: (context, constraints) { child: LayoutBuilder(builder: (context, constraints) {
return Stack( return HtmlContentViewerOnWeb(
children: [ widthContent: constraints.maxWidth,
HtmlContentViewerOnWeb( contentHtml: content,
widthContent: constraints.maxWidth, mailtoDelegate: onMailtoDelegateAction,
heightContent: min( direction: AppUtils.getCurrentDirection(context),
constraints.maxHeight, scrollController: scrollController,
EmailViewStyles.initialHtmlViewHeight,
),
contentHtml: content,
mailtoDelegate: onMailtoDelegateAction,
direction: AppUtils.getCurrentDirection(context),
scrollController: scrollController,
),
if (isDraggableAppActive == true)
PointerInterceptor(
child: SizedBox(
width: constraints.maxWidth,
height: constraints.maxHeight,
)
)
],
); );
}) })
) )