Fix avoid creating a white overlay on email content when scrolling the thread

Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
dab246
2025-07-24 11:20:09 +07:00
committed by Dat H. Pham
parent f4b353a38d
commit 9b5fa6ce3f
2 changed files with 306 additions and 273 deletions
+64 -37
View File
@@ -63,32 +63,26 @@ class EmailView extends GetWidget<SingleEmailController> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ColoredBox( final bodyWidget = Container(
color: controller.responsiveUtils.isWebDesktop(context)
? AppColor.colorBgDesktop
: Colors.white,
child: SafeArea(
right: controller.responsiveUtils.isLandscapeMobile(context),
left: controller.responsiveUtils.isLandscapeMobile(context),
bottom: !PlatformInfo.isIOS,
child: Container(
clipBehavior: Clip.antiAlias,
decoration: _getDecorationEmailView(context), decoration: _getDecorationEmailView(context),
margin: _getMarginEmailView(context), margin: _getMarginEmailView(context),
child: Obx(() { child: Obx(() {
final currentEmailListener = Rxn(controller.currentEmail); final currentEmailListener = Rxn(controller.currentEmail);
final currentEmail = currentEmailListener.value; final currentEmail = currentEmailListener.value;
if (currentEmail != null) { if (currentEmail != null) {
return Column(children: [ return Column(
children: [
if (!isInsideThreadDetailView) if (!isInsideThreadDetailView)
Obx(() => EmailViewAppBarWidget( Obx(
() => EmailViewAppBarWidget(
key: const Key('email_view_app_bar_widget'), key: const Key('email_view_app_bar_widget'),
presentationEmail: currentEmail, presentationEmail: currentEmail,
mailboxContain: _getMailboxContain(currentEmail), mailboxContain: _getMailboxContain(currentEmail),
isSearchActivated: controller.mailboxDashBoardController.searchController.isSearchEmailRunning, isSearchActivated: controller.mailboxDashBoardController.searchController.isSearchEmailRunning,
onBackAction: () => controller.closeEmailView(context: context), onBackAction: () => controller.closeEmailView(context: context),
onEmailActionClick: (email, action) => controller.handleEmailAction(context, email, action), onEmailActionClick: (email, action) => controller.handleEmailAction(context, email, action),
onMoreActionClick: (presentationEmail, position) => controller.emailActionReactor.handleMoreEmailAction( onMoreActionClick: (presentationEmail, position) {
return controller.emailActionReactor.handleMoreEmailAction(
mailboxContain: controller.getMailboxContain(presentationEmail), mailboxContain: controller.getMailboxContain(presentationEmail),
presentationEmail: presentationEmail, presentationEmail: presentationEmail,
position: position, position: position,
@@ -100,30 +94,44 @@ class EmailView extends GetWidget<SingleEmailController> {
emailIsRead: presentationEmail.hasRead, emailIsRead: presentationEmail.hasRead,
openBottomSheetContextMenu: controller.mailboxDashBoardController.openBottomSheetContextMenu, openBottomSheetContextMenu: controller.mailboxDashBoardController.openBottomSheetContextMenu,
openPopupMenu: controller.mailboxDashBoardController.openPopupMenu, openPopupMenu: controller.mailboxDashBoardController.openPopupMenu,
), );
},
supportBackAction: !isInsideThreadDetailView, supportBackAction: !isInsideThreadDetailView,
appBarDecoration: isInsideThreadDetailView appBarDecoration: isInsideThreadDetailView
? const BoxDecoration(border: Border(bottom: BorderSide( ? const BoxDecoration(
border: Border(
bottom: BorderSide(
color: AppColor.colorDividerEmailView, color: AppColor.colorDividerEmailView,
))) ),
),
)
: null, : null,
emailLoaded: controller.currentEmailLoaded.value, emailLoaded: controller.currentEmailLoaded.value,
isInsideThreadDetailView: isInsideThreadDetailView, isInsideThreadDetailView: isInsideThreadDetailView,
)), ),
),
Obx(() { Obx(() {
final vacation = controller.mailboxDashBoardController.vacationResponse.value; final vacation = controller.mailboxDashBoardController.vacationResponse.value;
if (vacation?.vacationResponderIsValid == true &&
( bool isPlatformSupportVacationVisible =
controller.responsiveUtils.isMobile(context) || controller.responsiveUtils.isMobile(context) ||
controller.responsiveUtils.isTablet(context) || controller.responsiveUtils.isTablet(context) ||
controller.responsiveUtils.isLandscapeMobile(context) controller.responsiveUtils.isLandscapeMobile(context);
)
) { bool isVacationBannerVisible =
vacation?.vacationResponderIsValid == true &&
isPlatformSupportVacationVisible;
if (isVacationBannerVisible) {
return VacationNotificationMessageWidget( return VacationNotificationMessageWidget(
margin: const EdgeInsetsDirectional.only(start: 12, end: 12, top: 8), margin: const EdgeInsetsDirectional.only(
start: 12,
end: 12,
top: 8,
),
vacationResponse: vacation!, vacationResponse: vacation!,
actionGotoVacationSetting: controller.mailboxDashBoardController.goToVacationSetting, actionGotoVacationSetting: controller.mailboxDashBoardController.goToVacationSetting,
actionEndNow: controller.mailboxDashBoardController.disableVacationResponder actionEndNow: controller.mailboxDashBoardController.disableVacationResponder,
); );
} else { } else {
return const SizedBox.shrink(); return const SizedBox.shrink();
@@ -139,20 +147,24 @@ class EmailView extends GetWidget<SingleEmailController> {
width: double.infinity, width: double.infinity,
alignment: Alignment.center, alignment: Alignment.center,
color: Colors.white, color: Colors.white,
child: Obx(() => _buildEmailMessage( child: Obx(
() => _buildEmailMessage(
context: context, context: context,
presentationEmail: currentEmail, presentationEmail: currentEmail,
calendarEvent: controller.calendarEvent, calendarEvent: controller.calendarEvent,
maxBodyHeight: constraints.maxHeight maxBodyHeight: constraints.maxHeight,
)) ),
) ),
),
); );
} else { } else {
return Obx(() { return Obx(() {
final calendarEvent = controller.calendarEvent; final calendarEvent = controller.calendarEvent;
if (currentEmail.hasCalendarEvent && calendarEvent != null) { if (currentEmail.hasCalendarEvent && calendarEvent != null) {
return Padding( return Padding(
padding: const EdgeInsetsDirectional.symmetric(horizontal: 4), padding: const EdgeInsetsDirectional.symmetric(
horizontal: 4,
),
child: OptionalScroll( child: OptionalScroll(
scrollEnabled: !isInsideThreadDetailView, scrollEnabled: !isInsideThreadDetailView,
child: Container( child: Container(
@@ -164,16 +176,16 @@ class EmailView extends GetWidget<SingleEmailController> {
presentationEmail: currentEmail, presentationEmail: currentEmail,
calendarEvent: calendarEvent, calendarEvent: calendarEvent,
emailAddressSender: currentEmail.listEmailAddressSender.getListAddress(), emailAddressSender: currentEmail.listEmailAddressSender.getListAddress(),
maxBodyHeight: constraints.maxHeight maxBodyHeight: constraints.maxHeight,
) ),
) ),
), ),
); );
} else { } else {
return _buildEmailMessage( return _buildEmailMessage(
context: context, context: context,
presentationEmail: currentEmail, presentationEmail: currentEmail,
maxBodyHeight: constraints.maxHeight maxBodyHeight: constraints.maxHeight,
); );
} }
}); });
@@ -197,14 +209,29 @@ class EmailView extends GetWidget<SingleEmailController> {
emailActionCallback: controller.pressEmailAction, emailActionCallback: controller.pressEmailAction,
); );
}), }),
]); ],
);
} else { } else {
return const EmailViewEmptyWidget(); return const EmailViewEmptyWidget();
} }
}) }),
)
)
); );
if (PlatformInfo.isMobile) {
return ColoredBox(
color: controller.responsiveUtils.isWebDesktop(context)
? AppColor.colorBgDesktop
: Colors.white,
child: SafeArea(
right: controller.responsiveUtils.isLandscapeMobile(context),
left: controller.responsiveUtils.isLandscapeMobile(context),
bottom: !PlatformInfo.isIOS,
child: bodyWidget,
),
);
} else {
return bodyWidget;
}
} }
BoxDecoration _getDecorationEmailView(BuildContext context) { BoxDecoration _getDecorationEmailView(BuildContext context) {
@@ -29,8 +29,7 @@ class ThreadDetailView extends GetWidget<ThreadDetailController> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final child = SelectionArea(child: SafeArea( Widget bodyWidget = Column(
child: Column(
children: [ children: [
Obx(() { Obx(() {
final isLoading = showLoadingView(controller.viewState.value); final isLoading = showLoadingView(controller.viewState.value);
@@ -195,12 +194,19 @@ class ThreadDetailView extends GetWidget<ThreadDetailController> {
if (controller.responsiveUtils.isDesktop(context)) if (controller.responsiveUtils.isDesktop(context))
const SizedBox(height: 16), const SizedBox(height: 16),
], ],
), );
));
if (PlatformInfo.isMobile) {
bodyWidget = SafeArea(child: bodyWidget);
}
if (PlatformInfo.isWeb) {
bodyWidget = SelectionArea(child: bodyWidget);
}
return ClipRRect( return ClipRRect(
borderRadius: const BorderRadius.vertical(bottom: Radius.circular(20)), borderRadius: const BorderRadius.vertical(bottom: Radius.circular(20)),
child: child, child: bodyWidget,
); );
} }