diff --git a/lib/features/base/widget/hyper_link_widget.dart b/lib/features/base/widget/hyper_link_widget.dart index a06d0ac5c..55cf8d412 100644 --- a/lib/features/base/widget/hyper_link_widget.dart +++ b/lib/features/base/widget/hyper_link_widget.dart @@ -11,8 +11,8 @@ class HyperLinkWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return RichText( - text: TextSpan( + return Text.rich( + TextSpan( text: urlString, style: const TextStyle( color: HyperLinkWidgetStyles.textColor, diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index 94c9d11df..742d73c61 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -46,215 +46,215 @@ class EmailView extends GetWidget { @override Widget build(BuildContext context) { - return Scaffold( - backgroundColor: controller.responsiveUtils.isWebDesktop(context) - ? AppColor.colorBgDesktop - : Colors.white, - appBar: PlatformInfo.isIOS - ? PreferredSize( - preferredSize: const Size(double.infinity, 100), + return SelectionArea( + child: Scaffold( + backgroundColor: controller.responsiveUtils.isWebDesktop(context) + ? AppColor.colorBgDesktop + : Colors.white, + appBar: PlatformInfo.isIOS + ? PreferredSize( + preferredSize: const Size(double.infinity, 100), + child: Obx(() { + if (controller.currentEmail != null) { + return SafeArea( + top: false, + bottom: false, + child: EmailViewAppBarWidget( + key: const Key('email_view_app_bar_widget'), + presentationEmail: controller.currentEmail!, + mailboxContain: _getMailboxContain(controller.currentEmail!), + isSearchActivated: controller.mailboxDashBoardController.searchController.isSearchEmailRunning, + onBackAction: () => controller.closeEmailView(context: context), + onEmailActionClick: (email, action) => controller.handleEmailAction(context, email, action), + onMoreActionClick: (presentationEmail, position) => _handleMoreEmailAction(context: context, presentationEmail: presentationEmail, position: position) + ), + ); + } else { + return const SizedBox.shrink(); + } + }) + ) + : null, + body: SafeArea( + right: controller.responsiveUtils.isLandscapeMobile(context), + left: controller.responsiveUtils.isLandscapeMobile(context), + bottom: !PlatformInfo.isIOS, + child: Container( + clipBehavior: Clip.antiAlias, + decoration: controller.responsiveUtils.isWebDesktop(context) + ? BoxDecoration( + borderRadius: BorderRadius.circular(20), + border: Border.all(color: AppColor.colorBorderBodyThread, width: 1), + color: Colors.white) + : const BoxDecoration(color: Colors.white), + margin: _getMarginEmailView(context), child: Obx(() { - if (controller.currentEmail != null) { - return SafeArea( - top: false, - bottom: false, - child: EmailViewAppBarWidget( - key: const Key('email_view_app_bar_widget'), - presentationEmail: controller.currentEmail!, - mailboxContain: _getMailboxContain(controller.currentEmail!), - isSearchActivated: controller.mailboxDashBoardController.searchController.isSearchEmailRunning, - onBackAction: () => controller.closeEmailView(context: context), - onEmailActionClick: (email, action) => controller.handleEmailAction(context, email, action), - onMoreActionClick: (presentationEmail, position) => _handleMoreEmailAction(context: context, presentationEmail: presentationEmail, position: position) + final currentEmail = controller.currentEmail; + if (currentEmail != null) { + return Column(children: [ + if (!PlatformInfo.isIOS) + 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) => _handleMoreEmailAction(context: context, presentationEmail: presentationEmail, position: position), + optionsWidget: PlatformInfo.isWeb && controller.emailSupervisorController.supportedPageView.isTrue + ? _buildNavigatorPageViewWidgets(context) + : null, + )), + Obx(() { + final vacation = controller.mailboxDashBoardController.vacationResponse.value; + if (vacation?.vacationResponderIsValid == true && + ( + controller.responsiveUtils.isMobile(context) || + controller.responsiveUtils.isTablet(context) || + controller.responsiveUtils.isLandscapeMobile(context) + ) + ) { + return VacationNotificationMessageWidget( + margin: const EdgeInsets.only(left: 12, right: 12, bottom: 5), + vacationResponse: vacation!, + actionGotoVacationSetting: controller.mailboxDashBoardController.goToVacationSetting, + actionEndNow: controller.mailboxDashBoardController.disableVacationResponder + ); + } else { + return const SizedBox.shrink(); + } + }), + Expanded( + child: LayoutBuilder(builder: (context, constraints) { + log('EmailView::build: EMAIL_BODY_MAX_HEIGHT = ${constraints.maxHeight}'); + return Obx(() { + if (controller.emailSupervisorController.supportedPageView.isTrue) { + final currentListEmail = controller.emailSupervisorController.currentListEmail; + return PageView.builder( + physics: controller.emailSupervisorController.scrollPhysicsPageView.value, + itemCount: currentListEmail.length, + allowImplicitScrolling: true, + controller: controller.emailSupervisorController.pageController, + onPageChanged: controller.emailSupervisorController.onPageChanged, + itemBuilder: (context, index) { + final currentEmail = currentListEmail[index]; + if (PlatformInfo.isMobile) { + return SingleChildScrollView( + physics : const ClampingScrollPhysics(), + child: Container( + width: double.infinity, + alignment: Alignment.center, + color: Colors.white, + child: Obx(() => _buildEmailMessage( + context: context, + presentationEmail: currentEmail, + calendarEvent: controller.calendarEvent.value, + maxBodyHeight: constraints.maxHeight + )) + ) + ); + } else { + return Obx(() { + final calendarEvent = controller.calendarEvent.value; + if (currentEmail.hasCalendarEvent && calendarEvent != null) { + return Padding( + padding: const EdgeInsetsDirectional.symmetric(horizontal: 4), + child: ScrollbarListView( + scrollController: controller.emailContentScrollController, + child: SingleChildScrollView( + physics : const ClampingScrollPhysics(), + child: Container( + width: double.infinity, + alignment: Alignment.center, + color: Colors.white, + child: _buildEmailMessage( + context: context, + presentationEmail: currentEmail, + calendarEvent: calendarEvent, + emailAddressSender: currentEmail.listEmailAddressSender.getListAddress(), + ) + ) + ), + ), + ); + } else { + return _buildEmailMessage( + context: context, + presentationEmail: currentEmail, + maxBodyHeight: constraints.maxHeight + ); + } + }); + } + } + ); + } else { + if (PlatformInfo.isMobile) { + return SingleChildScrollView( + physics : const ClampingScrollPhysics(), + child: Container( + width: double.infinity, + alignment: Alignment.center, + color: Colors.white, + child: Obx(() => _buildEmailMessage( + context: context, + presentationEmail: currentEmail, + calendarEvent: controller.calendarEvent.value, + maxBodyHeight: constraints.maxHeight + )) + ) + ); + } else { + return Obx(() { + final calendarEvent = controller.calendarEvent.value; + if (currentEmail.hasCalendarEvent && calendarEvent != null) { + return Padding( + padding: const EdgeInsetsDirectional.symmetric(horizontal: 4), + child: ScrollbarListView( + scrollController: controller.emailContentScrollController, + child: SingleChildScrollView( + physics : const ClampingScrollPhysics(), + 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 + ); + } + }); + } + } + }); + }), ), - ); + EmailViewBottomBarWidget( + key: const Key('email_view_button_bar'), + presentationEmail: currentEmail, + emailActionCallback: controller.pressEmailAction + ), + ]); } else { - return const SizedBox.shrink(); + return const EmailViewEmptyWidget(); } }) ) - : null, - body: SafeArea( - right: controller.responsiveUtils.isLandscapeMobile(context), - left: controller.responsiveUtils.isLandscapeMobile(context), - bottom: !PlatformInfo.isIOS, - child: Container( - clipBehavior: Clip.antiAlias, - decoration: controller.responsiveUtils.isWebDesktop(context) - ? BoxDecoration( - borderRadius: BorderRadius.circular(20), - border: Border.all(color: AppColor.colorBorderBodyThread, width: 1), - color: Colors.white) - : const BoxDecoration(color: Colors.white), - margin: _getMarginEmailView(context), - child: Obx(() { - final currentEmail = controller.currentEmail; - if (currentEmail != null) { - return Column(children: [ - if (!PlatformInfo.isIOS) - 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) => _handleMoreEmailAction(context: context, presentationEmail: presentationEmail, position: position), - optionsWidget: PlatformInfo.isWeb && controller.emailSupervisorController.supportedPageView.isTrue - ? _buildNavigatorPageViewWidgets(context) - : null, - )), - Obx(() { - final vacation = controller.mailboxDashBoardController.vacationResponse.value; - if (vacation?.vacationResponderIsValid == true && - ( - controller.responsiveUtils.isMobile(context) || - controller.responsiveUtils.isTablet(context) || - controller.responsiveUtils.isLandscapeMobile(context) - ) - ) { - return VacationNotificationMessageWidget( - margin: const EdgeInsets.only(left: 12, right: 12, bottom: 5), - vacationResponse: vacation!, - actionGotoVacationSetting: controller.mailboxDashBoardController.goToVacationSetting, - actionEndNow: controller.mailboxDashBoardController.disableVacationResponder - ); - } else { - return const SizedBox.shrink(); - } - }), - Expanded( - child: LayoutBuilder(builder: (context, constraints) { - log('EmailView::build: EMAIL_BODY_MAX_HEIGHT = ${constraints.maxHeight}'); - return Obx(() { - if (controller.emailSupervisorController.supportedPageView.isTrue) { - final currentListEmail = controller.emailSupervisorController.currentListEmail; - return PageView.builder( - physics: controller.emailSupervisorController.scrollPhysicsPageView.value, - itemCount: currentListEmail.length, - allowImplicitScrolling: true, - controller: controller.emailSupervisorController.pageController, - onPageChanged: controller.emailSupervisorController.onPageChanged, - itemBuilder: (context, index) { - final currentEmail = currentListEmail[index]; - if (PlatformInfo.isMobile) { - return SingleChildScrollView( - physics : const ClampingScrollPhysics(), - 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: ScrollbarListView( - scrollController: controller.emailContentScrollController, - child: SingleChildScrollView( - physics : const ClampingScrollPhysics(), - controller: controller.emailContentScrollController, - child: Container( - width: double.infinity, - alignment: Alignment.center, - color: Colors.white, - child: _buildEmailMessage( - context: context, - presentationEmail: currentEmail, - calendarEvent: calendarEvent, - emailAddressSender: currentEmail.listEmailAddressSender.getListAddress(), - ) - ) - ), - ), - ); - } else { - return _buildEmailMessage( - context: context, - presentationEmail: currentEmail, - maxBodyHeight: constraints.maxHeight - ); - } - }); - } - } - ); - } else { - if (PlatformInfo.isMobile) { - return SingleChildScrollView( - physics : const ClampingScrollPhysics(), - 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: ScrollbarListView( - scrollController: controller.emailContentScrollController, - child: SingleChildScrollView( - physics : const ClampingScrollPhysics(), - controller: controller.emailContentScrollController, - 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 - ); - } - }); - } - } - }); - }), - ), - EmailViewBottomBarWidget( - key: const Key('email_view_button_bar'), - presentationEmail: currentEmail, - emailActionCallback: controller.pressEmailAction - ), - ]); - } else { - return const EmailViewEmptyWidget(); - } - }) ) - ) + ), ); } diff --git a/lib/features/email/presentation/styles/email_subject_styles.dart b/lib/features/email/presentation/styles/email_subject_styles.dart index 177944a34..c8d7a8481 100644 --- a/lib/features/email/presentation/styles/email_subject_styles.dart +++ b/lib/features/email/presentation/styles/email_subject_styles.dart @@ -6,7 +6,6 @@ import 'package:flutter/material.dart'; class EmailSubjectStyles { static const double textSize = 20; static const int? maxLines = PlatformInfo.isWeb ? 2 : null; - static const int? minLines = PlatformInfo.isWeb ? 1 : null; static const Color textColor = AppColor.colorNameEmail; static const Color cursorColor = AppColor.colorTextButton; diff --git a/lib/features/email/presentation/widgets/calendar_event/attendee_widget.dart b/lib/features/email/presentation/widgets/calendar_event/attendee_widget.dart index 607e2a135..8834905b8 100644 --- a/lib/features/email/presentation/widgets/calendar_event/attendee_widget.dart +++ b/lib/features/email/presentation/widgets/calendar_event/attendee_widget.dart @@ -16,8 +16,8 @@ class AttendeeWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return RichText( - text: TextSpan( + return Text.rich( + TextSpan( style: const TextStyle( fontSize: AttendeeWidgetStyles.textSize, fontWeight: FontWeight.w500, diff --git a/lib/features/email/presentation/widgets/calendar_event/calendar_event_action_banner_widget.dart b/lib/features/email/presentation/widgets/calendar_event/calendar_event_action_banner_widget.dart index 36c650746..7fe70559f 100644 --- a/lib/features/email/presentation/widgets/calendar_event/calendar_event_action_banner_widget.dart +++ b/lib/features/email/presentation/widgets/calendar_event/calendar_event_action_banner_widget.dart @@ -48,8 +48,8 @@ class CalendarEventActionBannerWidget extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - RichText( - text: TextSpan( + Text.rich( + TextSpan( style: TextStyle( fontSize: CalendarEventActionBannerStyles.titleTextSize, fontWeight: FontWeight.w400, diff --git a/lib/features/email/presentation/widgets/calendar_event/calendar_event_information_widget.dart b/lib/features/email/presentation/widgets/calendar_event/calendar_event_information_widget.dart index 852d6566d..2c26565c9 100644 --- a/lib/features/email/presentation/widgets/calendar_event/calendar_event_information_widget.dart +++ b/lib/features/email/presentation/widgets/calendar_event/calendar_event_information_widget.dart @@ -76,8 +76,8 @@ class CalendarEventInformationWidget extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - RichText( - text: TextSpan( + Text.rich( + TextSpan( style: const TextStyle( fontSize: CalendarEventInformationWidgetStyles.invitationMessageTextSize, fontWeight: FontWeight.w500, @@ -147,8 +147,8 @@ class CalendarEventInformationWidget extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - RichText( - text: TextSpan( + Text.rich( + TextSpan( style: const TextStyle( fontSize: CalendarEventInformationWidgetStyles.invitationMessageTextSize, fontWeight: FontWeight.w500, diff --git a/lib/features/email/presentation/widgets/calendar_event/event_attendee_information_widget.dart b/lib/features/email/presentation/widgets/calendar_event/event_attendee_information_widget.dart index f38edc797..9ab413796 100644 --- a/lib/features/email/presentation/widgets/calendar_event/event_attendee_information_widget.dart +++ b/lib/features/email/presentation/widgets/calendar_event/event_attendee_information_widget.dart @@ -36,8 +36,8 @@ class EventAttendeeInformationWidget extends StatelessWidget { ), ), ), - Expanded(child: RichText( - text: TextSpan( + Expanded(child: Text.rich( + TextSpan( style: const TextStyle( fontSize: EventAttendeeInformationWidgetStyles.textSize, fontWeight: FontWeight.w500, diff --git a/lib/features/email/presentation/widgets/calendar_event/organizer_widget.dart b/lib/features/email/presentation/widgets/calendar_event/organizer_widget.dart index 4ac0dce03..6ed9f4ae5 100644 --- a/lib/features/email/presentation/widgets/calendar_event/organizer_widget.dart +++ b/lib/features/email/presentation/widgets/calendar_event/organizer_widget.dart @@ -15,8 +15,8 @@ class OrganizerWidget extends StatelessWidget { @override Widget build(BuildContext context) { - return RichText( - text: TextSpan( + return Text.rich( + TextSpan( style: const TextStyle( fontSize: OrganizerWidgetStyles.textSize, fontWeight: FontWeight.w500, diff --git a/lib/features/email/presentation/widgets/email_receiver_widget.dart b/lib/features/email/presentation/widgets/email_receiver_widget.dart index acee9f088..7c1b859f5 100644 --- a/lib/features/email/presentation/widgets/email_receiver_widget.dart +++ b/lib/features/email/presentation/widgets/email_receiver_widget.dart @@ -1,10 +1,9 @@ +import 'package:collection/collection.dart'; import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/resources/image_paths.dart'; import 'package:core/presentation/utils/responsive_utils.dart'; -import 'package:core/presentation/utils/style_utils.dart'; import 'package:core/presentation/views/button/tmail_button_widget.dart'; -import 'package:core/utils/direction_utils.dart'; import 'package:core/utils/platform_info.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -14,10 +13,9 @@ import 'package:model/email/presentation_email.dart'; import 'package:model/extensions/email_address_extension.dart'; import 'package:model/extensions/list_email_address_extension.dart'; import 'package:model/extensions/presentation_email_extension.dart'; -import 'package:tmail_ui_user/features/base/widget/material_text_button.dart'; -import 'package:tmail_ui_user/features/base/widget/scrollbar_list_view.dart'; import 'package:tmail_ui_user/features/composer/presentation/extensions/prefix_email_address_extension.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_sender_builder.dart'; +import 'package:tmail_ui_user/features/email/presentation/widgets/prefix_recipient_widget.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/utils/app_utils.dart'; @@ -47,233 +45,253 @@ class _EmailReceiverWidgetState extends State { final _imagePaths = Get.find(); final _responsiveUtils = Get.find(); - final _scrollController = ScrollController(); bool _isDisplayAll = false; @override Widget build(BuildContext context) { - return Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded(child: Padding( - padding: EdgeInsets.only(top: _isDisplayAll - ? DirectionUtils.isDirectionRTLByLanguage(context) ? 3 : 5.5 - : 0), - child: PlatformInfo.isWeb - ? Container( - constraints: BoxConstraints( - maxHeight: _isDisplayAll && widget.maxHeight != null - ? widget.maxHeight! / 2 - _offsetTop - : double.infinity - ), - child: ScrollbarListView( - scrollController: _scrollController, - child: SingleChildScrollView( - controller: _scrollController, - child: _buildEmailAddressOfReceiver( - context, - widget.emailSelected, - _isDisplayAll, - widget.maxWidth - ), - ), + if (PlatformInfo.isWeb) { + if (_isDisplayAll) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Container( + constraints: BoxConstraints(maxHeight: _maxHeight), + child: ListView( + primary: false, + shrinkWrap: true, + padding: EdgeInsets.zero, + children: [ + if (widget.emailSelected.to.numberEmailAddress() > 0) + _buildRecipientsWidgetToDisplayFull( + context: context, + prefixEmailAddress: PrefixEmailAddress.to, + listEmailAddress: PrefixEmailAddress.to.listEmailAddress(widget.emailSelected) + ), + if (widget.emailSelected.cc.numberEmailAddress() > 0) + _buildRecipientsWidgetToDisplayFull( + context: context, + prefixEmailAddress: PrefixEmailAddress.cc, + listEmailAddress: PrefixEmailAddress.cc.listEmailAddress(widget.emailSelected) + ), + if (widget.emailSelected.bcc.numberEmailAddress() > 0) + _buildRecipientsWidgetToDisplayFull( + context: context, + prefixEmailAddress: PrefixEmailAddress.bcc, + listEmailAddress: PrefixEmailAddress.bcc.listEmailAddress(widget.emailSelected) + ), + ], ), ) - : _buildEmailAddressOfReceiver( - context, - widget.emailSelected, - _isDisplayAll, - widget.maxWidth + ), + TMailButtonWidget.fromText( + text: AppLocalizations.of(context).hide, + textStyle: Theme.of(context).textTheme.labelMedium?.copyWith( + color: AppColor.primaryColor, + fontSize: 15 ), - )), - if (_isDisplayAll) - Padding( - padding: EdgeInsets.symmetric( - vertical: DirectionUtils.isDirectionRTLByLanguage(context) ? 0 : 6), - child: MaterialTextButton( - padding: DirectionUtils.isDirectionRTLByLanguage(context) - ? const EdgeInsets.symmetric(horizontal: 8, vertical: 4) - : null, - onTap: () => setState(() => _isDisplayAll = false), - label: AppLocalizations.of(context).hide, - ) - ) - ] - ); - } - - Widget _buildEmailAddressOfReceiver( - BuildContext context, - PresentationEmail presentationEmail, - bool isDisplayFull, - double maxWidth - ) { - if (!isDisplayFull && presentationEmail.numberOfAllEmailAddress() > 1) { - return Row( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - height: 40, - color: Colors.white, - constraints: BoxConstraints(maxWidth: _getMaxWidthEmailAddressDisplayed(context, maxWidth)), - child: ListView( - scrollDirection: Axis.horizontal, - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - children: [ - if (presentationEmail.to.numberEmailAddress() > 0) - _buildEmailAddressByPrefix( - context, - presentationEmail, - PrefixEmailAddress.to, - isDisplayFull - ), - if (presentationEmail.cc.numberEmailAddress() > 0) - _buildEmailAddressByPrefix( - context, - presentationEmail, - PrefixEmailAddress.cc, - isDisplayFull - ), - if (presentationEmail.bcc.numberEmailAddress() > 0) - _buildEmailAddressByPrefix( - context, - presentationEmail, - PrefixEmailAddress.bcc, - isDisplayFull - ), - ] - ), - ), - Transform( - transform: Matrix4.translationValues(0.0, -5.0, 0.0), - child: TMailButtonWidget.fromIcon( - icon: _imagePaths.icChevronDown, backgroundColor: Colors.transparent, - onTapActionCallback: () => setState(() => _isDisplayAll = true), + onTapActionCallback: () => setState(() => _isDisplayAll = false), + ) + ] + ); + } else { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + ConstrainedBox( + constraints: BoxConstraints( + maxWidth: _getMaxWidth(context), + maxHeight: 34, + ), + child: ListView( + scrollDirection: Axis.horizontal, + physics: const NeverScrollableScrollPhysics(), + padding: EdgeInsets.zero, + shrinkWrap: true, + children: [ + if (widget.emailSelected.to.numberEmailAddress() > 0) + ..._buildRecipientsWidget( + context: context, + prefixEmailAddress: PrefixEmailAddress.to, + listEmailAddress: PrefixEmailAddress.to.listEmailAddress(widget.emailSelected) + ), + if (widget.emailSelected.cc.numberEmailAddress() > 0) + ..._buildRecipientsWidget( + context: context, + prefixEmailAddress: PrefixEmailAddress.cc, + listEmailAddress: PrefixEmailAddress.cc.listEmailAddress(widget.emailSelected) + ), + if (widget.emailSelected.bcc.numberEmailAddress() > 0) + ..._buildRecipientsWidget( + context: context, + prefixEmailAddress: PrefixEmailAddress.bcc, + listEmailAddress: PrefixEmailAddress.bcc.listEmailAddress(widget.emailSelected) + ), + ] + ), ), - ) - ] - ); + if (widget.emailSelected.numberOfAllEmailAddress() > 1) + TMailButtonWidget.fromIcon( + icon: _imagePaths.icChevronDown, + backgroundColor: Colors.transparent, + onTapActionCallback: () => setState(() => _isDisplayAll = true), + ) + ] + ); + } } else { - return Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (presentationEmail.to.numberEmailAddress() > 0) - _buildEmailAddressByPrefix( - context, - presentationEmail, - PrefixEmailAddress.to, - isDisplayFull + if (_isDisplayAll) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Container( + constraints: BoxConstraints(maxHeight: _maxHeight), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (widget.emailSelected.to.numberEmailAddress() > 0) + _buildRecipientsWidgetToDisplayFull( + context: context, + prefixEmailAddress: PrefixEmailAddress.to, + listEmailAddress: PrefixEmailAddress.to.listEmailAddress(widget.emailSelected) + ), + if (widget.emailSelected.cc.numberEmailAddress() > 0) + _buildRecipientsWidgetToDisplayFull( + context: context, + prefixEmailAddress: PrefixEmailAddress.cc, + listEmailAddress: PrefixEmailAddress.cc.listEmailAddress(widget.emailSelected) + ), + if (widget.emailSelected.bcc.numberEmailAddress() > 0) + _buildRecipientsWidgetToDisplayFull( + context: context, + prefixEmailAddress: PrefixEmailAddress.bcc, + listEmailAddress: PrefixEmailAddress.bcc.listEmailAddress(widget.emailSelected) + ), + ], + ), + ) + ), + TMailButtonWidget.fromText( + text: AppLocalizations.of(context).hide, + textStyle: Theme.of(context).textTheme.labelMedium?.copyWith( + color: AppColor.primaryColor, + fontSize: 15 + ), + backgroundColor: Colors.transparent, + onTapActionCallback: () => setState(() => _isDisplayAll = false), + ) + ] + ); + } else { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + height: 40, + constraints: BoxConstraints(maxWidth: _getMaxWidth(context)), + child: ListView( + scrollDirection: Axis.horizontal, + physics: const NeverScrollableScrollPhysics(), + padding: EdgeInsets.zero, + shrinkWrap: true, + children: [ + if (widget.emailSelected.to.numberEmailAddress() > 0) + ..._buildRecipientsWidget( + context: context, + prefixEmailAddress: PrefixEmailAddress.to, + listEmailAddress: PrefixEmailAddress.to.listEmailAddress(widget.emailSelected) + ), + if (widget.emailSelected.cc.numberEmailAddress() > 0) + ..._buildRecipientsWidget( + context: context, + prefixEmailAddress: PrefixEmailAddress.cc, + listEmailAddress: PrefixEmailAddress.cc.listEmailAddress(widget.emailSelected) + ), + if (widget.emailSelected.bcc.numberEmailAddress() > 0) + ..._buildRecipientsWidget( + context: context, + prefixEmailAddress: PrefixEmailAddress.bcc, + listEmailAddress: PrefixEmailAddress.bcc.listEmailAddress(widget.emailSelected) + ), + ] + ), ), - if (presentationEmail.cc.numberEmailAddress() > 0) - _buildEmailAddressByPrefix( - context, - presentationEmail, - PrefixEmailAddress.cc, - isDisplayFull - ), - if (presentationEmail.bcc.numberEmailAddress() > 0) - _buildEmailAddressByPrefix( - context, - presentationEmail, - PrefixEmailAddress.bcc, - isDisplayFull - ), - ], - ); + if (widget.emailSelected.numberOfAllEmailAddress() > 1) + TMailButtonWidget.fromIcon( + icon: _imagePaths.icChevronDown, + backgroundColor: Colors.transparent, + onTapActionCallback: () => setState(() => _isDisplayAll = true), + ) + ] + ); + } } } - Widget _buildEmailAddressByPrefix( - BuildContext context, - PresentationEmail presentationEmail, - PrefixEmailAddress prefixEmailAddress, - bool isDisplayFull - ) { + List _buildRecipientsTag({required List listEmailAddress}) { + return listEmailAddress + .mapIndexed((index, emailAddress) => TMailButtonWidget.fromText( + text: index == listEmailAddress.length - 1 + ? emailAddress.asString() + : '${emailAddress.asString()},', + textStyle: Theme.of(context).textTheme.labelSmall?.copyWith( + color: Colors.black, + fontSize: 16, + ), + padding: const EdgeInsetsDirectional.symmetric(vertical: 5, horizontal: 8), + backgroundColor: Colors.transparent, + onTapActionCallback: () => widget.openEmailAddressDetailAction?.call(context, emailAddress), + onLongPressActionCallback: () => AppUtils.copyEmailAddressToClipboard(context, emailAddress.emailAddress), + )) + .toList(); + } + + + Widget _buildRecipientsWidgetToDisplayFull({ + required BuildContext context, + required PrefixEmailAddress prefixEmailAddress, + required List listEmailAddress, + }) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Padding( - padding: const EdgeInsets.only(top: 5), - child: Text( - '${prefixEmailAddress.asName(context)}:', - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: AppColor.colorEmailAddressFull - ) - ), - ), - if (!isDisplayFull && presentationEmail.numberOfAllEmailAddress() > 1) - _buildListEmailAddressWidget( - context, - prefixEmailAddress.listEmailAddress(presentationEmail), - isDisplayFull + PrefixRecipientWidget(prefixEmailAddress: prefixEmailAddress), + Expanded( + child: Wrap( + children: _buildRecipientsTag(listEmailAddress: listEmailAddress) ) - else - Expanded(child: _buildListEmailAddressWidget( - context, - prefixEmailAddress.listEmailAddress(presentationEmail), - isDisplayFull - )) - ] + ) + ], ); } - Widget _buildListEmailAddressWidget( - BuildContext context, - List listEmailAddress, - bool isDisplayFull - ) { - final lastEmailAddress = listEmailAddress.last; - final emailAddressWidgets = listEmailAddress.map((emailAddress) { - return MaterialTextButton( - label: lastEmailAddress == emailAddress - ? emailAddress.asString() - : '${emailAddress.asString()},', - onTap: () => widget.openEmailAddressDetailAction?.call(context, emailAddress), - onLongPress: () { - AppUtils.copyEmailAddressToClipboard(context, emailAddress.emailAddress); - }, - borderRadius: 8, - labelColor: Colors.black, - labelSize: 16, - softWrap: CommonTextStyle.defaultSoftWrap, - overflow: CommonTextStyle.defaultTextOverFlow, - ); - }).toList(); - - if (isDisplayFull) { - return Wrap(children: emailAddressWidgets); - } else { - return SingleChildScrollView( - scrollDirection: Axis.horizontal, - physics: const NeverScrollableScrollPhysics(), - child: Row( - crossAxisAlignment:CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: emailAddressWidgets - ), - ); - } + List _buildRecipientsWidget({ + required BuildContext context, + required PrefixEmailAddress prefixEmailAddress, + required List listEmailAddress, + }) { + return [ + PrefixRecipientWidget(prefixEmailAddress: prefixEmailAddress), + ..._buildRecipientsTag(listEmailAddress: listEmailAddress) + ]; } - double _getMaxWidthEmailAddressDisplayed(BuildContext context, double maxWidth) { + double _getMaxWidth(BuildContext context) { if (_responsiveUtils.isPortraitMobile(context)) { - return maxWidth - _maxSizeFullDisplayEmailAddressArrowDownButton; + return widget.maxWidth - _maxSizeFullDisplayEmailAddressArrowDownButton; } else if (_responsiveUtils.isWebDesktop(context)) { - return maxWidth / 2; + return widget.maxWidth / 2; } else { - return maxWidth * 3/4; + return widget.maxWidth * 3/4; } } - @override - void dispose() { - _scrollController.dispose(); - super.dispose(); + double get _maxHeight { + return _isDisplayAll && widget.maxHeight != null + ? widget.maxHeight! / 2 - _offsetTop + : double.infinity; } } \ No newline at end of file diff --git a/lib/features/email/presentation/widgets/email_subject_widget.dart b/lib/features/email/presentation/widgets/email_subject_widget.dart index e7611f963..6132c433c 100644 --- a/lib/features/email/presentation/widgets/email_subject_widget.dart +++ b/lib/features/email/presentation/widgets/email_subject_widget.dart @@ -12,11 +12,9 @@ class EmailSubjectWidget extends StatelessWidget { Widget build(BuildContext context) { return Padding( padding: EmailSubjectStyles.padding, - child: SelectableText( + child: Text( presentationEmail.getEmailTitle(), maxLines: EmailSubjectStyles.maxLines, - minLines: EmailSubjectStyles.minLines, - cursorColor: EmailSubjectStyles.cursorColor, style: const TextStyle( fontSize: EmailSubjectStyles.textSize, color: EmailSubjectStyles.textColor, diff --git a/lib/features/email/presentation/widgets/prefix_recipient_widget.dart b/lib/features/email/presentation/widgets/prefix_recipient_widget.dart new file mode 100644 index 000000000..03fe772c2 --- /dev/null +++ b/lib/features/email/presentation/widgets/prefix_recipient_widget.dart @@ -0,0 +1,26 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; +import 'package:model/email/prefix_email_address.dart'; +import 'package:tmail_ui_user/features/composer/presentation/extensions/prefix_email_address_extension.dart'; + +class PrefixRecipientWidget extends StatelessWidget { + final PrefixEmailAddress prefixEmailAddress; + + const PrefixRecipientWidget({super.key, required this.prefixEmailAddress}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(top: 6), + child: Text( + '${prefixEmailAddress.asName(context)}:', + style: Theme.of(context).textTheme.labelMedium?.copyWith( + fontSize: 16, + fontWeight: FontWeight.w500, + color: AppColor.colorEmailAddressFull + ) + ), + ); + } +} \ No newline at end of file