diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index 69eb6053f..11b61aabd 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -63,148 +63,175 @@ class EmailView extends GetWidget { @override Widget build(BuildContext context) { - 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: Container( - clipBehavior: Clip.antiAlias, - decoration: _getDecorationEmailView(context), - margin: _getMarginEmailView(context), - child: Obx(() { - final currentEmailListener = Rxn(controller.currentEmail); - final currentEmail = currentEmailListener.value; - if (currentEmail != null) { - return Column(children: [ - if (!isInsideThreadDetailView) - Obx(() => EmailViewAppBarWidget( + final bodyWidget = Container( + decoration: _getDecorationEmailView(context), + margin: _getMarginEmailView(context), + child: Obx(() { + final currentEmailListener = Rxn(controller.currentEmail); + final currentEmail = currentEmailListener.value; + if (currentEmail != null) { + return Column( + children: [ + if (!isInsideThreadDetailView) + Obx( + () => EmailViewAppBarWidget( key: const Key('email_view_app_bar_widget'), presentationEmail: currentEmail, mailboxContain: _getMailboxContain(currentEmail), isSearchActivated: controller.mailboxDashBoardController.searchController.isSearchEmailRunning, onBackAction: () => controller.closeEmailView(context: context), onEmailActionClick: (email, action) => controller.handleEmailAction(context, email, action), - onMoreActionClick: (presentationEmail, position) => controller.emailActionReactor.handleMoreEmailAction( - mailboxContain: controller.getMailboxContain(presentationEmail), - presentationEmail: presentationEmail, - position: position, - responsiveUtils: controller.responsiveUtils, - imagePaths: controller.imagePaths, - username: controller.session?.username, - handleEmailAction: (email, action) => controller.handleEmailAction(context, email, action), - additionalActions: [], - emailIsRead: presentationEmail.hasRead, - openBottomSheetContextMenu: controller.mailboxDashBoardController.openBottomSheetContextMenu, - openPopupMenu: controller.mailboxDashBoardController.openPopupMenu, - ), + onMoreActionClick: (presentationEmail, position) { + return controller.emailActionReactor.handleMoreEmailAction( + mailboxContain: controller.getMailboxContain(presentationEmail), + presentationEmail: presentationEmail, + position: position, + responsiveUtils: controller.responsiveUtils, + imagePaths: controller.imagePaths, + username: controller.session?.username, + handleEmailAction: (email, action) => controller.handleEmailAction(context, email, action), + additionalActions: [], + emailIsRead: presentationEmail.hasRead, + openBottomSheetContextMenu: controller.mailboxDashBoardController.openBottomSheetContextMenu, + openPopupMenu: controller.mailboxDashBoardController.openPopupMenu, + ); + }, supportBackAction: !isInsideThreadDetailView, appBarDecoration: isInsideThreadDetailView - ? const BoxDecoration(border: Border(bottom: BorderSide( - color: AppColor.colorDividerEmailView, - ))) - : null, + ? const BoxDecoration( + border: Border( + bottom: BorderSide( + color: AppColor.colorDividerEmailView, + ), + ), + ) + : null, emailLoaded: controller.currentEmailLoaded.value, isInsideThreadDetailView: isInsideThreadDetailView, - )), - Obx(() { - final vacation = controller.mailboxDashBoardController.vacationResponse.value; - if (vacation?.vacationResponderIsValid == true && - ( - controller.responsiveUtils.isMobile(context) || + ), + ), + Obx(() { + final vacation = controller.mailboxDashBoardController.vacationResponse.value; + + bool isPlatformSupportVacationVisible = + controller.responsiveUtils.isMobile(context) || controller.responsiveUtils.isTablet(context) || - controller.responsiveUtils.isLandscapeMobile(context) - ) - ) { - return VacationNotificationMessageWidget( - margin: const EdgeInsetsDirectional.only(start: 12, end: 12, top: 8), - vacationResponse: vacation!, - actionGotoVacationSetting: controller.mailboxDashBoardController.goToVacationSetting, - actionEndNow: controller.mailboxDashBoardController.disableVacationResponder - ); - } else { - return const SizedBox.shrink(); - } - }), - 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( + controller.responsiveUtils.isLandscapeMobile(context); + + bool isVacationBannerVisible = + vacation?.vacationResponderIsValid == true && + isPlatformSupportVacationVisible; + + if (isVacationBannerVisible) { + return VacationNotificationMessageWidget( + margin: const EdgeInsetsDirectional.only( + start: 12, + end: 12, + top: 8, + ), + vacationResponse: vacation!, + actionGotoVacationSetting: controller.mailboxDashBoardController.goToVacationSetting, + actionEndNow: controller.mailboxDashBoardController.disableVacationResponder, + ); + } else { + return const SizedBox.shrink(); + } + }), + 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, - maxBodyHeight: constraints.maxHeight - )) - ) - ); - } 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(), - maxBodyHeight: constraints.maxHeight - ) - ) + maxBodyHeight: constraints.maxHeight, + ), + ), + ), + ); + } 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(), + maxBodyHeight: constraints.maxHeight, + ), ), - ); - } else { - return _buildEmailMessage( - context: context, - presentationEmail: currentEmail, - maxBodyHeight: constraints.maxHeight - ); - } - }); - } - }), - ), - Obx(() { - final emailLoaded = controller.currentEmailLoaded.value; - - if (emailLoaded == null || isInsideThreadDetailView) { - return const SizedBox.shrink(); + ), + ); + } else { + return _buildEmailMessage( + context: context, + presentationEmail: currentEmail, + maxBodyHeight: constraints.maxHeight, + ); + } + }); } - - return EmailViewBottomBarWidget( - key: const Key('email_view_button_bar'), - imagePaths: controller.imagePaths, - responsiveUtils: controller.responsiveUtils, - emailLoaded: emailLoaded, - presentationEmail: currentEmail, - userName: controller.getOwnEmailAddress(), - emailActionCallback: controller.pressEmailAction, - ); }), - ]); - } else { - return const EmailViewEmptyWidget(); - } - }) - ) - ) + ), + Obx(() { + final emailLoaded = controller.currentEmailLoaded.value; + + if (emailLoaded == null || isInsideThreadDetailView) { + return const SizedBox.shrink(); + } + + return EmailViewBottomBarWidget( + key: const Key('email_view_button_bar'), + imagePaths: controller.imagePaths, + responsiveUtils: controller.responsiveUtils, + emailLoaded: emailLoaded, + presentationEmail: currentEmail, + userName: controller.getOwnEmailAddress(), + emailActionCallback: controller.pressEmailAction, + ); + }), + ], + ); + } else { + 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) { diff --git a/lib/features/thread_detail/presentation/thread_detail_view.dart b/lib/features/thread_detail/presentation/thread_detail_view.dart index f39c17303..060907c02 100644 --- a/lib/features/thread_detail/presentation/thread_detail_view.dart +++ b/lib/features/thread_detail/presentation/thread_detail_view.dart @@ -29,178 +29,184 @@ class ThreadDetailView extends GetWidget { @override Widget build(BuildContext context) { - final child = SelectionArea(child: SafeArea( - child: Column( - children: [ - Obx(() { - final isLoading = showLoadingView(controller.viewState.value); + Widget bodyWidget = Column( + children: [ + Obx(() { + final isLoading = showLoadingView(controller.viewState.value); - return ThreadDetailAppBar( - responsiveUtils: controller.responsiveUtils, - imagePaths: controller.imagePaths, - isSearchRunning: controller.isSearchRunning, - closeThreadDetailAction: controller.closeThreadDetailAction, - lastEmailOfThread: controller.emailIdsPresentation.values.lastOrNull, - ownUserName: controller.session?.getOwnEmailAddress() ?? '', - mailboxContain: _getMailboxContain(), - onEmailActionClick: isLoading + return ThreadDetailAppBar( + responsiveUtils: controller.responsiveUtils, + imagePaths: controller.imagePaths, + isSearchRunning: controller.isSearchRunning, + closeThreadDetailAction: controller.closeThreadDetailAction, + lastEmailOfThread: controller.emailIdsPresentation.values.lastOrNull, + ownUserName: controller.session?.getOwnEmailAddress() ?? '', + mailboxContain: _getMailboxContain(), + onEmailActionClick: isLoading ? null : controller.threadDetailOnEmailActionClick, - onMoreActionClick: (presentationEmail, position) => isLoading + onMoreActionClick: (presentationEmail, position) => isLoading ? null : controller.emailActionReactor.handleMoreEmailAction( - mailboxContain: controller.getThreadDetailEmailMailboxContains( - presentationEmail, - ), - presentationEmail: presentationEmail, - position: position, - responsiveUtils: controller.responsiveUtils, - imagePaths: controller.imagePaths, - username: controller.session?.username, - handleEmailAction: controller.threadDetailOnEmailActionClick, - additionalActions: [ - if (controller.responsiveUtils.isMobile(context)) ...[ - EmailActionType.forward, - EmailActionType.replyAll, - EmailActionType.replyToList, - ], - EmailActionType.markAsStarred, - EmailActionType.unMarkAsStarred, - EmailActionType.moveToTrash, - EmailActionType.deletePermanently, - EmailActionType.printAll, - EmailActionType.moveToMailbox, - ], - emailIsRead: presentationEmail.hasRead, - openBottomSheetContextMenu: controller.mailboxDashBoardController.openBottomSheetContextMenu, - openPopupMenu: controller.mailboxDashBoardController.openPopupMenu, - ), - optionWidgets: [ - if (controller.previousAvailable) - TMailButtonWidget.fromIcon( - icon: controller.imagePaths.icNewer, - iconSize: EmailViewAppBarWidgetStyles.buttonIconSize, - iconColor: EmailViewAppBarWidgetStyles.iconColor, - tooltipMessage: AppLocalizations.of(context).newer, - backgroundColor: Colors.transparent, - onTapActionCallback: controller.onPrevious, - ), - if (controller.nextAvailable) - TMailButtonWidget.fromIcon( - icon: controller.imagePaths.icOlder, - iconSize: EmailViewAppBarWidgetStyles.buttonIconSize, - iconColor: EmailViewAppBarWidgetStyles.iconColor, - tooltipMessage: AppLocalizations.of(context).older, - backgroundColor: Colors.transparent, - onTapActionCallback: controller.onNext, - ), + mailboxContain: controller.getThreadDetailEmailMailboxContains( + presentationEmail, + ), + presentationEmail: presentationEmail, + position: position, + responsiveUtils: controller.responsiveUtils, + imagePaths: controller.imagePaths, + username: controller.session?.username, + handleEmailAction: controller.threadDetailOnEmailActionClick, + additionalActions: [ + if (controller.responsiveUtils.isMobile(context)) ...[ + EmailActionType.forward, + EmailActionType.replyAll, + EmailActionType.replyToList, + ], + EmailActionType.markAsStarred, + EmailActionType.unMarkAsStarred, + EmailActionType.moveToTrash, + EmailActionType.deletePermanently, + EmailActionType.printAll, + EmailActionType.moveToMailbox, ], - ); - }), - Obx(() { - final nonPageViewThread = Expanded( - child: Container( - color: Colors.white, - padding: _padding(context), - child: SingleChildScrollView( - controller: controller.scrollController, - child: Column( + emailIsRead: presentationEmail.hasRead, + openBottomSheetContextMenu: controller.mailboxDashBoardController.openBottomSheetContextMenu, + openPopupMenu: controller.mailboxDashBoardController.openPopupMenu, + ), + optionWidgets: [ + if (controller.previousAvailable) + TMailButtonWidget.fromIcon( + icon: controller.imagePaths.icNewer, + iconSize: EmailViewAppBarWidgetStyles.buttonIconSize, + iconColor: EmailViewAppBarWidgetStyles.iconColor, + tooltipMessage: AppLocalizations.of(context).newer, + backgroundColor: Colors.transparent, + onTapActionCallback: controller.onPrevious, + ), + if (controller.nextAvailable) + TMailButtonWidget.fromIcon( + icon: controller.imagePaths.icOlder, + iconSize: EmailViewAppBarWidgetStyles.buttonIconSize, + iconColor: EmailViewAppBarWidgetStyles.iconColor, + tooltipMessage: AppLocalizations.of(context).older, + backgroundColor: Colors.transparent, + onTapActionCallback: controller.onNext, + ), + ], + ); + }), + Obx(() { + final nonPageViewThread = Expanded( + child: Container( + color: Colors.white, + padding: _padding(context), + child: SingleChildScrollView( + controller: controller.scrollController, + child: Column( mainAxisSize: MainAxisSize.min, children: controller.getThreadDetailEmailViews() - ), ), ), - ); + ), + ); - if (PlatformInfo.isMobile) { - final manager = controller.threadDetailManager; - final currentIndex = manager.currentMobilePageViewIndex.value; + if (PlatformInfo.isMobile) { + final manager = controller.threadDetailManager; + final currentIndex = manager.currentMobilePageViewIndex.value; - if (currentIndex == -1) return nonPageViewThread; + if (currentIndex == -1) return nonPageViewThread; - return Expanded( - child: PageView.builder( - controller: manager.pageController, - itemCount: manager.isThreadDetailEnabled + return Expanded( + child: PageView.builder( + controller: manager.pageController, + itemCount: manager.isThreadDetailEnabled ? manager.availableThreadIds.length : manager.currentDisplayedEmails.length, - itemBuilder: (context, index) { - if (index != currentIndex) { - return const SizedBox.shrink(); - } - - return SingleChildScrollView( - child: Column( + itemBuilder: (context, index) { + if (index != currentIndex) { + return const SizedBox.shrink(); + } + + return SingleChildScrollView( + child: Column( mainAxisSize: MainAxisSize.min, children: controller.getThreadDetailEmailViews() - ), - ); - }, - onPageChanged: controller.onThreadPageChanged, - ), - ); - } - - return nonPageViewThread; - }), - Obx(() { - final expandedEmailId = controller.currentExpandedEmailId.value; - if (expandedEmailId == null) { - return const SizedBox.shrink(); - } - final expandedPresentationEmail = controller.emailIdsPresentation[expandedEmailId]; - if (expandedPresentationEmail == null) { - return const SizedBox.shrink(); - } - - final currentEmailLoaded = controller.currentEmailLoaded.value; - if (currentEmailLoaded == null) { - return const SizedBox.shrink(); - } - - return Padding( - padding: controller.responsiveUtils.isDesktop(context) - ? const EdgeInsetsDirectional.only(end: 16) - : EdgeInsets.zero, - child: ClipRRect( - borderRadius: const BorderRadius.vertical( - bottom: Radius.circular(20), - ), - child: EmailViewBottomBarWidget( - key: const Key('email_view_button_bar'), - imagePaths: controller.imagePaths, - responsiveUtils: controller.responsiveUtils, - emailLoaded: currentEmailLoaded, - presentationEmail: expandedPresentationEmail, - userName: controller.session?.getOwnEmailAddress() ?? '', - emailActionCallback: (action, email) { - controller.mailboxDashBoardController - ..dispatchEmailUIAction(PerformEmailActionInThreadDetailAction( - emailActionType: action, - presentationEmail: email, - )) - ..dispatchEmailUIAction(EmailUIAction()); - }, - bottomBarDecoration: const BoxDecoration( - color: Colors.white, - border: Border( - top: BorderSide(color: AppColor.colorDividerEmailView), ), - ), - padding: EdgeInsets.zero, - ), + ); + }, + onPageChanged: controller.onThreadPageChanged, ), ); - }), - if (controller.responsiveUtils.isDesktop(context)) - const SizedBox(height: 16), - ], - ), - )); + } + + return nonPageViewThread; + }), + Obx(() { + final expandedEmailId = controller.currentExpandedEmailId.value; + if (expandedEmailId == null) { + return const SizedBox.shrink(); + } + final expandedPresentationEmail = controller.emailIdsPresentation[expandedEmailId]; + if (expandedPresentationEmail == null) { + return const SizedBox.shrink(); + } + + final currentEmailLoaded = controller.currentEmailLoaded.value; + if (currentEmailLoaded == null) { + return const SizedBox.shrink(); + } + + return Padding( + padding: controller.responsiveUtils.isDesktop(context) + ? const EdgeInsetsDirectional.only(end: 16) + : EdgeInsets.zero, + child: ClipRRect( + borderRadius: const BorderRadius.vertical( + bottom: Radius.circular(20), + ), + child: EmailViewBottomBarWidget( + key: const Key('email_view_button_bar'), + imagePaths: controller.imagePaths, + responsiveUtils: controller.responsiveUtils, + emailLoaded: currentEmailLoaded, + presentationEmail: expandedPresentationEmail, + userName: controller.session?.getOwnEmailAddress() ?? '', + emailActionCallback: (action, email) { + controller.mailboxDashBoardController + ..dispatchEmailUIAction(PerformEmailActionInThreadDetailAction( + emailActionType: action, + presentationEmail: email, + )) + ..dispatchEmailUIAction(EmailUIAction()); + }, + bottomBarDecoration: const BoxDecoration( + color: Colors.white, + border: Border( + top: BorderSide(color: AppColor.colorDividerEmailView), + ), + ), + padding: EdgeInsets.zero, + ), + ), + ); + }), + if (controller.responsiveUtils.isDesktop(context)) + const SizedBox(height: 16), + ], + ); + + if (PlatformInfo.isMobile) { + bodyWidget = SafeArea(child: bodyWidget); + } + + if (PlatformInfo.isWeb) { + bodyWidget = SelectionArea(child: bodyWidget); + } return ClipRRect( borderRadius: const BorderRadius.vertical(bottom: Radius.circular(20)), - child: child, + child: bodyWidget, ); }