diff --git a/assets/images/ic_format_quote.svg b/assets/images/ic_format_quote.svg new file mode 100644 index 0000000000..6806d928a4 --- /dev/null +++ b/assets/images/ic_format_quote.svg @@ -0,0 +1,5 @@ + + + diff --git a/core/lib/presentation/extensions/color_extension.dart b/core/lib/presentation/extensions/color_extension.dart index 2d26a5607e..34b2157184 100644 --- a/core/lib/presentation/extensions/color_extension.dart +++ b/core/lib/presentation/extensions/color_extension.dart @@ -195,6 +195,8 @@ extension AppColor on Color { static const colorCalendarEventInformationStroke = Color(0x1F000000); static const colorShadowCalendarDateIcon = Color(0x26000000); static const colorOrganizerMailto = Color(0xFFB3B3B3); + static const colorMailto = Color(0xFFB3B3B3); + static const colorEventDescriptionBackground = Color(0x05000000); static const mapGradientColor = [ [Color(0xFF21D4FD), Color(0xFFB721FF)], diff --git a/core/lib/presentation/resources/image_paths.dart b/core/lib/presentation/resources/image_paths.dart index d5a010dd7c..cea00d9f59 100644 --- a/core/lib/presentation/resources/image_paths.dart +++ b/core/lib/presentation/resources/image_paths.dart @@ -198,6 +198,7 @@ class ImagePaths { String get icEventInvited => _getImagePath('ic_event_invited.svg'); String get icEventUpdated => _getImagePath('ic_event_updated.svg'); String get icEventCanceled => _getImagePath('ic_event_canceled.svg'); + String get icFormatQuote => _getImagePath('ic_format_quote.svg'); String _getImagePath(String imageName) { return AssetsPaths.images + imageName; diff --git a/lib/features/base/styles/cupertino_loading_widget_styles.dart b/lib/features/base/styles/cupertino_loading_widget_styles.dart new file mode 100644 index 0000000000..3000ad3694 --- /dev/null +++ b/lib/features/base/styles/cupertino_loading_widget_styles.dart @@ -0,0 +1,7 @@ +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; + +class CupertinoLoadingWidgetStyles { + static const Color progressColor = AppColor.colorLoading; + static const double size = 24; +} \ No newline at end of file diff --git a/lib/features/base/styles/hyper_link_widget_styles.dart b/lib/features/base/styles/hyper_link_widget_styles.dart new file mode 100644 index 0000000000..c8668cb476 --- /dev/null +++ b/lib/features/base/styles/hyper_link_widget_styles.dart @@ -0,0 +1,7 @@ +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; + +class HyperLinkWidgetStyles { + static const Color textColor = AppColor.primaryColor; + static const double textSize = 16; +} \ No newline at end of file diff --git a/lib/features/base/widget/cupertino_loading_widget.dart b/lib/features/base/widget/cupertino_loading_widget.dart new file mode 100644 index 0000000000..0c8d3e72a9 --- /dev/null +++ b/lib/features/base/widget/cupertino_loading_widget.dart @@ -0,0 +1,17 @@ +import 'package:flutter/cupertino.dart'; +import 'package:tmail_ui_user/features/base/styles/cupertino_loading_widget_styles.dart'; + +class CupertinoLoadingWidget extends StatelessWidget { + const CupertinoLoadingWidget({super.key}); + + @override + Widget build(BuildContext context) { + return const Center( + child: SizedBox( + width: CupertinoLoadingWidgetStyles.size, + height: CupertinoLoadingWidgetStyles.size, + child: CupertinoActivityIndicator(color: CupertinoLoadingWidgetStyles.progressColor) + ) + ); + } +} \ No newline at end of file diff --git a/lib/features/base/widget/hyper_link_widget.dart b/lib/features/base/widget/hyper_link_widget.dart new file mode 100644 index 0000000000..f0249179ea --- /dev/null +++ b/lib/features/base/widget/hyper_link_widget.dart @@ -0,0 +1,33 @@ +import 'package:flutter/gestures.dart'; +import 'package:flutter/widgets.dart'; +import 'package:tmail_ui_user/features/base/styles/hyper_link_widget_styles.dart'; +import 'package:url_launcher/url_launcher_string.dart'; + +class HyperLinkWidget extends StatelessWidget { + + final String urlString; + + const HyperLinkWidget({Key? key, required this.urlString}) : super(key: key); + + @override + Widget build(BuildContext context) { + return RichText( + text: TextSpan( + text: urlString, + style: const TextStyle( + color: HyperLinkWidgetStyles.textColor, + fontSize: HyperLinkWidgetStyles.textSize, + decoration: TextDecoration.underline + ), + recognizer: TapGestureRecognizer()..onTap = () async { + if (await canLaunchUrlString(urlString)) { + launchUrlString( + urlString, + mode: LaunchMode.externalApplication + ); + } + } + ) + ); + } +} diff --git a/lib/features/email/presentation/controller/single_email_controller.dart b/lib/features/email/presentation/controller/single_email_controller.dart index 8d75bf248e..8ad0ce6041 100644 --- a/lib/features/email/presentation/controller/single_email_controller.dart +++ b/lib/features/email/presentation/controller/single_email_controller.dart @@ -1279,6 +1279,11 @@ class SingleEmailController extends BaseController with AppLoaderMixin { void _handleParseCalendarEventSuccess(ParseCalendarEventSuccess success) { if (success.calendarEventList.isNotEmpty) { calendarEvent.value = success.calendarEventList.first; + _enableScrollPageView(); } } + + void _enableScrollPageView() { + emailSupervisorController.scrollPhysicsPageView.value = null; + } } \ No newline at end of file diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index f47912de2e..e3594bf0f8 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -22,15 +22,16 @@ import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart'; import 'package:tmail_ui_user/features/base/widget/custom_scroll_behavior.dart'; import 'package:tmail_ui_user/features/base/widget/popup_item_widget.dart'; -import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart'; import 'package:tmail_ui_user/features/email/presentation/controller/single_email_controller.dart'; import 'package:tmail_ui_user/features/email/presentation/styles/email_view_styles.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/app_bar_mail_widget_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/attachment_file_tile_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/bottom_bar_mail_widget_builder.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/calendar_event_action_banner_widget.dart'; +import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/calendar_event_detail_widget.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/calendar_event_information_widget.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/email_action_cupertino_action_sheet_action_builder.dart'; +import 'package:tmail_ui_user/features/email/presentation/widgets/email_view_loading_bar_widget.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/information_sender_and_receiver_builder.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/extensions/vacation_response_extension.dart'; import 'package:tmail_ui_user/features/manage_account/presentation/vacation/widgets/vacation_notification_message_widget.dart'; @@ -228,7 +229,7 @@ class EmailView extends GetWidget with AppLoaderMixin { } Widget _buildEmailBody(BuildContext context, PresentationEmail email) { - if (PlatformInfo.isWeb) { + if (PlatformInfo.isWeb && !email.hasCalendarEvent) { return _buildEmailMessage(context, email); } else { return SingleChildScrollView( @@ -281,59 +282,41 @@ class EmailView extends GetWidget with AppLoaderMixin { imagePaths: imagePaths, responsiveUtils: responsiveUtils, ), - _buildLoadingContentView(), _buildAttachments(context), - Obx(() { - if (controller.calendarEvent.value != null) { - return CalendarEventInformationWidget( - calendarEvent: controller.calendarEvent.value! - ); - } else { - return const SizedBox.shrink(); - } - }), - Obx(() { - if (controller.calendarEvent.value != null) { - return CalendarEventActionBannerWidget( - calendarEvent: controller.calendarEvent.value!, - listFromEmailAddress: controller.currentEmail?.from - ); - } else { - return const SizedBox.shrink(); - } - }), - if (PlatformInfo.isWeb) - Expanded(child: Padding( - padding: const EdgeInsetsDirectional.only(start: 16, bottom: 16), - child: _buildEmailContent(context, constraints, email) - )) + Obx(() => EmailViewLoadingBarWidget( + viewState: controller.viewState.value, + selectedEmail: email + )), + if (email.hasCalendarEvent) + Obx(() { + if (controller.calendarEvent.value != null) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + CalendarEventInformationWidget( + calendarEvent: controller.calendarEvent.value! + ), + CalendarEventActionBannerWidget( + calendarEvent: controller.calendarEvent.value!, + listFromEmailAddress: controller.currentEmail?.from + ), + CalendarEventDetailWidget( + calendarEvent: controller.calendarEvent.value! + ), + ], + ); + } else { + return const SizedBox.shrink(); + } + }) else - Padding( - padding: const EdgeInsetsDirectional.symmetric( - vertical: EmailViewStyles.mobileContentVerticalMargin, - horizontal: EmailViewStyles.mobileContentHorizontalMargin - ), - child: _buildEmailContent(context, constraints, email) - ) + _buildEmailContent(context, constraints, email) ], ); }); } - Widget _buildLoadingContentView() { - return Obx(() { - return controller.viewState.value.fold( - (failure) => const SizedBox.shrink(), - (success) { - if (success is GetEmailContentLoading) { - return loadingWidget; - } else { - return const SizedBox.shrink(); - } - }); - }); - } - Widget _buildAttachments(BuildContext context) { return Obx(() { final attachments = controller.attachments.listAttachmentsDisplayedOutSide; @@ -463,25 +446,36 @@ class EmailView extends GetWidget with AppLoaderMixin { final allEmailContents = controller.emailContents.value; if (PlatformInfo.isWeb) { - return HtmlContentViewerOnWeb( - widthContent: constraints.maxWidth, - heightContent: responsiveUtils.getSizeScreenHeight(context), - contentHtml: allEmailContents ?? "", - controller: HtmlViewerControllerForWeb(), - mailtoDelegate: (uri) => controller.openMailToLink(uri), - direction: AppUtils.getCurrentDirection(context), + return Expanded( + child: Padding( + padding: const EdgeInsetsDirectional.only(start: 16, bottom: 16), + child: HtmlContentViewerOnWeb( + widthContent: constraints.maxWidth, + heightContent: responsiveUtils.getSizeScreenHeight(context), + contentHtml: allEmailContents ?? "", + controller: HtmlViewerControllerForWeb(), + mailtoDelegate: (uri) => controller.openMailToLink(uri), + direction: AppUtils.getCurrentDirection(context), + ), + ), ); } else { - return HtmlContentViewer( - heightContent: responsiveUtils.getSizeScreenHeight(context), - contentHtml: allEmailContents ?? "", - mailtoDelegate: (uri) async => controller.openMailToLink(uri), - onScrollHorizontalEnd: controller.toggleScrollPhysicsPagerView, - onWebViewLoaded: (isScrollPageViewActivated) { - log('EmailView::_buildEmailContent(): isScrollPageViewActivated: $isScrollPageViewActivated'); - controller.emailSupervisorController.updateScrollPhysicPageView(isScrollPageViewActivated: isScrollPageViewActivated); - }, - direction: AppUtils.getCurrentDirection(context), + return Padding( + padding: const EdgeInsetsDirectional.symmetric( + vertical: EmailViewStyles.mobileContentVerticalMargin, + horizontal: EmailViewStyles.mobileContentHorizontalMargin + ), + child: HtmlContentViewer( + heightContent: responsiveUtils.getSizeScreenHeight(context), + contentHtml: allEmailContents ?? "", + mailtoDelegate: (uri) async => controller.openMailToLink(uri), + onScrollHorizontalEnd: controller.toggleScrollPhysicsPagerView, + onWebViewLoaded: (isScrollPageViewActivated) { + log('EmailView::_buildEmailContent(): isScrollPageViewActivated: $isScrollPageViewActivated'); + controller.emailSupervisorController.updateScrollPhysicPageView(isScrollPageViewActivated: isScrollPageViewActivated); + }, + direction: AppUtils.getCurrentDirection(context), + ), ); } } else { diff --git a/lib/features/email/presentation/extensions/calendar_event_extension.dart b/lib/features/email/presentation/extensions/calendar_event_extension.dart index ad55b6ee58..164c4d6a9a 100644 --- a/lib/features/email/presentation/extensions/calendar_event_extension.dart +++ b/lib/features/email/presentation/extensions/calendar_event_extension.dart @@ -269,4 +269,20 @@ extension CalendarEventExtension on CalendarEvent { return ''; } } + + List get videoConferences { + if (extensionFields != null && extensionFields!.mapFields.isNotEmpty) { + final videoConferences = extensionFields!.mapFields['X-OPENPAAS-VIDEOCONFERENCE']; + if (videoConferences != null) { + final videoConferencesNotEmpty = videoConferences + .whereNotNull() + .where((link) => link.isNotEmpty) + .toList(); + log('CalendarEventExtension::getListVideoConference: $videoConferencesNotEmpty'); + return videoConferencesNotEmpty; + } + } + + return []; + } } \ No newline at end of file diff --git a/lib/features/email/presentation/styles/attendee_widget_styles.dart b/lib/features/email/presentation/styles/attendee_widget_styles.dart new file mode 100644 index 0000000000..0a66107c97 --- /dev/null +++ b/lib/features/email/presentation/styles/attendee_widget_styles.dart @@ -0,0 +1,10 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; + +class AttendeeWidgetStyles { + static const double maxWidth = 100; + static const double textSize = 16; + static const Color textColor = Colors.black; + static const Color mailtoColor = AppColor.colorMailto; +} \ No newline at end of file diff --git a/lib/features/email/presentation/styles/calendar_event_detail_widget_styles.dart b/lib/features/email/presentation/styles/calendar_event_detail_widget_styles.dart new file mode 100644 index 0000000000..80d262e2d9 --- /dev/null +++ b/lib/features/email/presentation/styles/calendar_event_detail_widget_styles.dart @@ -0,0 +1,14 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; + +class CalendarEventDetailWidgetStyles { + static const double textSize = 24; + static const double borderRadius = 16; + static const double verticalMargin = 12; + static const double horizontalMargin = 16; + static const double contentPadding = 16; + static const double fieldTopPadding = 16; + static const Color borderStrokeColor = AppColor.colorCalendarEventInformationStroke; + static const double borderStrokeWidth = 0.5; +} \ No newline at end of file diff --git a/lib/features/email/presentation/styles/calendar_event_information_widget_styles.dart b/lib/features/email/presentation/styles/calendar_event_information_widget_styles.dart index 4ef35f7ff1..507a7b643c 100644 --- a/lib/features/email/presentation/styles/calendar_event_information_widget_styles.dart +++ b/lib/features/email/presentation/styles/calendar_event_information_widget_styles.dart @@ -11,7 +11,6 @@ class CalendarEventInformationWidgetStyles { static const Color calendarDateIconBackgroundColor = AppColor.colorCalendarEventInformationBackground; static const double calendarInformationMargin = 16; static const double invitationMessageTextSize = 16; - static const double titleTextSize = 24; static const double fieldTopPadding = 16; static const double space = 8; static const Color titleColor = Colors.black; diff --git a/lib/features/email/presentation/styles/event_attendee_detail_widget_styles.dart b/lib/features/email/presentation/styles/event_attendee_detail_widget_styles.dart new file mode 100644 index 0000000000..f510184b20 --- /dev/null +++ b/lib/features/email/presentation/styles/event_attendee_detail_widget_styles.dart @@ -0,0 +1,11 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; + +class EventAttendeeDetailWidgetStyles { + static const double maxWidth = 100; + static const double textSize = 16; + static const double fieldTopPadding = 8; + static const Color labelColor = AppColor.colorSubTitleEventActionText; + static const Color valueColor = Colors.black; +} \ 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 new file mode 100644 index 0000000000..82b3591bd9 --- /dev/null +++ b/lib/features/email/presentation/styles/event_description_detail_widget_styles.dart @@ -0,0 +1,9 @@ + +import 'package:flutter/material.dart'; + +class EventDescriptionDetailWidgetStyles { + static const double textSize = 16; + static const double borderRadius = 16; + static const double contentPadding = 16; + static const Color valueColor = Colors.black; +} \ No newline at end of file diff --git a/lib/features/email/presentation/styles/event_link_detail_widget_styles.dart b/lib/features/email/presentation/styles/event_link_detail_widget_styles.dart new file mode 100644 index 0000000000..e91c8ba779 --- /dev/null +++ b/lib/features/email/presentation/styles/event_link_detail_widget_styles.dart @@ -0,0 +1,10 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; + +class EventLinkDetailWidgetStyles { + static const double maxWidth = 100; + static const double textSize = 16; + static const Color labelColor = AppColor.colorSubTitleEventActionText; + static const Color valueColor = Colors.black; +} \ No newline at end of file diff --git a/lib/features/email/presentation/styles/event_location_detail_widget_styles.dart b/lib/features/email/presentation/styles/event_location_detail_widget_styles.dart new file mode 100644 index 0000000000..8abe0cdf06 --- /dev/null +++ b/lib/features/email/presentation/styles/event_location_detail_widget_styles.dart @@ -0,0 +1,10 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; + +class EventLocationDetailWidgetStyles { + static const double maxWidth = 100; + static const double textSize = 16; + static const Color labelColor = AppColor.colorSubTitleEventActionText; + static const Color valueColor = Colors.black; +} \ No newline at end of file diff --git a/lib/features/email/presentation/styles/event_time_detail_widget_styles.dart b/lib/features/email/presentation/styles/event_time_detail_widget_styles.dart new file mode 100644 index 0000000000..af54d01924 --- /dev/null +++ b/lib/features/email/presentation/styles/event_time_detail_widget_styles.dart @@ -0,0 +1,10 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; + +class EventTimeDetailWidgetStyles { + static const double maxWidth = 100; + static const double textSize = 16; + static const Color labelColor = AppColor.colorSubTitleEventActionText; + static const Color valueColor = Colors.black; +} \ No newline at end of file diff --git a/lib/features/email/presentation/styles/event_title_widget_styles.dart b/lib/features/email/presentation/styles/event_title_widget_styles.dart new file mode 100644 index 0000000000..f53abaf925 --- /dev/null +++ b/lib/features/email/presentation/styles/event_title_widget_styles.dart @@ -0,0 +1,7 @@ + +import 'package:flutter/material.dart'; + +class EventTitleWidgetStyles { + static const double textSize = 24; + static const Color textColor = Colors.black; +} \ No newline at end of file diff --git a/lib/features/email/presentation/styles/organizer_widget_styles.dart b/lib/features/email/presentation/styles/organizer_widget_styles.dart new file mode 100644 index 0000000000..1ea478c4bc --- /dev/null +++ b/lib/features/email/presentation/styles/organizer_widget_styles.dart @@ -0,0 +1,10 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; + +class OrganizerWidgetStyles { + static const double maxWidth = 100; + static const double textSize = 16; + static const Color textColor = Colors.black; + static const Color mailtoColor = AppColor.colorMailto; +} \ No newline at end of file diff --git a/lib/features/email/presentation/styles/see_all_attendees_button_widget_styles.dart b/lib/features/email/presentation/styles/see_all_attendees_button_widget_styles.dart new file mode 100644 index 0000000000..a64f3ce54e --- /dev/null +++ b/lib/features/email/presentation/styles/see_all_attendees_button_widget_styles.dart @@ -0,0 +1,12 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:flutter/material.dart'; + +class SeeAllAttendeesButtonWidgetStyles { + static const double textSize = 16; + static const double horizontalPadding = 8; + static const double verticalPadding = 4; + static const double borderRadius = 20; + static const double horizontalMargin = -8; + static const Color textColor = AppColor.primaryColor; +} \ No newline at end of file diff --git a/lib/features/email/presentation/widgets/calendar_event/attendee_widget.dart b/lib/features/email/presentation/widgets/calendar_event/attendee_widget.dart new file mode 100644 index 0000000000..03ebcf3d3d --- /dev/null +++ b/lib/features/email/presentation/widgets/calendar_event/attendee_widget.dart @@ -0,0 +1,41 @@ + +import 'package:flutter/material.dart'; +import 'package:jmap_dart_client/jmap/mail/calendar/properties/attendee/calendar_attendee.dart'; +import 'package:tmail_ui_user/features/email/presentation/styles/attendee_widget_styles.dart'; + +class AttendeeWidget extends StatelessWidget { + + final CalendarAttendee attendee; + + const AttendeeWidget({ + super.key, + required this.attendee + }); + + @override + Widget build(BuildContext context) { + return RichText( + text: TextSpan( + style: const TextStyle( + fontSize: AttendeeWidgetStyles.textSize, + fontWeight: FontWeight.w500, + color: AttendeeWidgetStyles.textColor + ), + children: [ + if (attendee.name?.name.isNotEmpty == true) + TextSpan(text: attendee.name!.name), + if (attendee.mailto?.mailAddress.value.isNotEmpty == true) + TextSpan( + text: ' <${attendee.mailto!.mailAddress.value}> ', + style: const TextStyle( + color: AttendeeWidgetStyles.mailtoColor, + fontSize: AttendeeWidgetStyles.textSize, + fontWeight: FontWeight.w500 + ), + ), + const TextSpan(text: ', '), + ] + ) + ); + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..0d6c39bf21 --- /dev/null +++ b/lib/features/email/presentation/widgets/calendar_event/calendar_event_detail_widget.dart @@ -0,0 +1,78 @@ + +import 'package:flutter/material.dart'; +import 'package:jmap_dart_client/jmap/mail/calendar/calendar_event.dart'; +import 'package:tmail_ui_user/features/email/presentation/extensions/calendar_event_extension.dart'; +import 'package:tmail_ui_user/features/email/presentation/styles/calendar_event_detail_widget_styles.dart'; +import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/event_attendee_detail_widget.dart'; +import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/event_description_detail_widget.dart'; +import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/event_link_detail_widget.dart'; +import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/event_location_detail_widget.dart'; +import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/event_time_detail_widget.dart'; +import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/event_title_widget.dart'; + +class CalendarEventDetailWidget extends StatelessWidget { + + final CalendarEvent calendarEvent; + + const CalendarEventDetailWidget({ + super.key, + required this.calendarEvent + }); + + @override + Widget build(BuildContext context) { + return Container( + clipBehavior: Clip.antiAlias, + decoration: const ShapeDecoration( + color: Colors.white, + shape: RoundedRectangleBorder( + side: BorderSide( + width: CalendarEventDetailWidgetStyles.borderStrokeWidth, + color: CalendarEventDetailWidgetStyles.borderStrokeColor, + ), + borderRadius: BorderRadius.all(Radius.circular(CalendarEventDetailWidgetStyles.borderRadius)), + ), + ), + margin: const EdgeInsetsDirectional.symmetric( + vertical: CalendarEventDetailWidgetStyles.verticalMargin, + horizontal: CalendarEventDetailWidgetStyles.horizontalMargin), + padding: const EdgeInsets.all(CalendarEventDetailWidgetStyles.contentPadding), + width: double.infinity, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (calendarEvent.title?.isNotEmpty == true) + EventTitleWidget(title: calendarEvent.title!), + if (calendarEvent.description?.isNotEmpty == true) + Padding( + padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding), + child: EventDescriptionDetailWidget(description: calendarEvent.description!) + ), + if (calendarEvent.dateTimeEventAsString.isNotEmpty) + Padding( + padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding), + child: EventTimeWidgetWidget(timeEvent: calendarEvent.dateTimeEventAsString), + ), + if (calendarEvent.videoConferences.isNotEmpty) + Padding( + padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding), + child: EventLinkDetailWidget(listHyperLink: calendarEvent.videoConferences), + ), + if (calendarEvent.location?.isNotEmpty == true) + Padding( + padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding), + child: EventLocationDetailWidget(locationEvent: calendarEvent.location!), + ), + if (calendarEvent.participants?.isNotEmpty == true && calendarEvent.organizer != null) + Padding( + padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding), + child: EventAttendeeDetailWidget( + attendees: calendarEvent.participants!, + organizer: calendarEvent.organizer!, + ), + ), + ], + ), + ); + } +} 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 ed1cde64b8..62062c4102 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 @@ -10,6 +10,7 @@ import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/calendar_date_icon_widget.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/event_location_information_widget.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/event_time_information_widget.dart'; +import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/event_title_widget.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; class CalendarEventInformationWidget extends StatelessWidget { @@ -82,14 +83,8 @@ class CalendarEventInformationWidget extends StatelessWidget { ) ), const SizedBox(height: CalendarEventInformationWidgetStyles.space), - Text( - calendarEvent.title ?? '', - style: const TextStyle( - fontWeight: FontWeight.w500, - fontSize: CalendarEventInformationWidgetStyles.titleTextSize, - color: CalendarEventInformationWidgetStyles.titleColor - ) - ), + if (calendarEvent.title?.isNotEmpty == true) + EventTitleWidget(title: calendarEvent.title!), if (calendarEvent.dateTimeEventAsString.isNotEmpty) Padding( padding: const EdgeInsets.only(top: CalendarEventInformationWidgetStyles.fieldTopPadding), @@ -153,14 +148,8 @@ class CalendarEventInformationWidget extends StatelessWidget { ) ), const SizedBox(height: CalendarEventInformationWidgetStyles.space), - Text( - calendarEvent.title ?? '', - style: const TextStyle( - fontWeight: FontWeight.w500, - fontSize: CalendarEventInformationWidgetStyles.titleTextSize, - color: CalendarEventInformationWidgetStyles.titleColor - ) - ), + if (calendarEvent.title?.isNotEmpty == true) + EventTitleWidget(title: calendarEvent.title!), if (calendarEvent.dateTimeEventAsString.isNotEmpty) Padding( padding: const EdgeInsets.only(top: CalendarEventInformationWidgetStyles.fieldTopPadding), diff --git a/lib/features/email/presentation/widgets/calendar_event/event_attendee_detail_widget.dart b/lib/features/email/presentation/widgets/calendar_event/event_attendee_detail_widget.dart new file mode 100644 index 0000000000..13f3026e6d --- /dev/null +++ b/lib/features/email/presentation/widgets/calendar_event/event_attendee_detail_widget.dart @@ -0,0 +1,90 @@ + +import 'package:core/utils/app_logger.dart'; +import 'package:flutter/material.dart'; +import 'package:jmap_dart_client/jmap/mail/calendar/properties/attendee/calendar_attendee.dart'; +import 'package:jmap_dart_client/jmap/mail/calendar/properties/calendar_organizer.dart'; +import 'package:tmail_ui_user/features/email/presentation/extensions/list_attendee_extension.dart'; +import 'package:tmail_ui_user/features/email/presentation/styles/event_attendee_detail_widget_styles.dart'; +import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/attendee_widget.dart'; +import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/organizer_widget.dart'; +import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/see_all_attendees_button_widget.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +class EventAttendeeDetailWidget extends StatefulWidget { + + static const int maxAttendeeDisplayed = 6; + + final List attendees; + final CalendarOrganizer organizer; + + const EventAttendeeDetailWidget({ + super.key, + required this.attendees, + required this.organizer + }); + + @override + State createState() => _EventAttendeeDetailWidgetState(); +} + +class _EventAttendeeDetailWidgetState extends State { + + late List _attendeesDisplayed; + late bool _isShowAllAttendee; + + @override + void initState() { + super.initState(); + _attendeesDisplayed = _splitAttendees(widget.attendees); + _isShowAllAttendee = widget.attendees.length <= EventAttendeeDetailWidget.maxAttendeeDisplayed; + log('_EventAttendeeDetailWidgetState::initState:attendees: ${widget.attendees.length} | _isShowAllAttendee: $_isShowAllAttendee'); + } + + @override + Widget build(BuildContext context) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: EventAttendeeDetailWidgetStyles.maxWidth, + child: Text( + AppLocalizations.of(context).attendees, + style: const TextStyle( + fontSize: EventAttendeeDetailWidgetStyles.textSize, + fontWeight: FontWeight.w500, + color: EventAttendeeDetailWidgetStyles.labelColor + ), + ), + ), + Expanded(child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + OrganizerWidget(organizer: widget.organizer), + ..._attendeesDisplayed + .map((attendee) => AttendeeWidget(attendee: attendee)) + .toList(), + if (!_isShowAllAttendee) + Padding( + padding: const EdgeInsets.only(top: EventAttendeeDetailWidgetStyles.fieldTopPadding), + child: SeeAllAttendeesButtonWidget( + onTap: () { + setState(() { + _attendeesDisplayed = widget.attendees.withoutOrganizer(widget.organizer); + _isShowAllAttendee = true; + }); + } + ), + ) + ] + )) + ], + ); + } + + List _splitAttendees(List attendees) { + final attendeesWithoutOrganizer = attendees.withoutOrganizer(widget.organizer); + return attendeesWithoutOrganizer.length > EventAttendeeDetailWidget.maxAttendeeDisplayed + ? attendeesWithoutOrganizer.sublist(0, EventAttendeeDetailWidget.maxAttendeeDisplayed - 1) + : attendeesWithoutOrganizer; + } +} \ No newline at end of file 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 4567c94926..f38edc797a 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 @@ -1,5 +1,7 @@ +import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:flutter/material.dart'; +import 'package:get/get.dart'; import 'package:jmap_dart_client/jmap/mail/calendar/properties/attendee/calendar_attendee.dart'; import 'package:jmap_dart_client/jmap/mail/calendar/properties/calendar_organizer.dart'; import 'package:tmail_ui_user/features/email/presentation/extensions/list_attendee_extension.dart'; @@ -19,6 +21,7 @@ class EventAttendeeInformationWidget extends StatelessWidget { @override Widget build(BuildContext context) { + final responsiveUtils = Get.find(); return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -52,7 +55,11 @@ class EventAttendeeInformationWidget extends StatelessWidget { const TextSpan(text: ', '), TextSpan(text: attendees.withoutOrganizer(organizer).mailtoAsString) ] - ) + ), + overflow: responsiveUtils.isPortraitMobile(context) + ? TextOverflow.clip + : TextOverflow.ellipsis, + maxLines: responsiveUtils.isPortraitMobile(context) ? null : 2, )) ], ); diff --git a/lib/features/email/presentation/widgets/calendar_event/event_description_detail_widget.dart b/lib/features/email/presentation/widgets/calendar_event/event_description_detail_widget.dart new file mode 100644 index 0000000000..298a5465e7 --- /dev/null +++ b/lib/features/email/presentation/widgets/calendar_event/event_description_detail_widget.dart @@ -0,0 +1,48 @@ + +import 'package:core/presentation/extensions/color_extension.dart'; +import 'package:core/presentation/resources/image_paths.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/email/presentation/styles/event_description_detail_widget_styles.dart'; + +class EventDescriptionDetailWidget extends StatelessWidget { + + final String description; + + const EventDescriptionDetailWidget({ + super.key, + required this.description + }); + + @override + Widget build(BuildContext context) { + final imagePath = Get.find(); + return Container( + clipBehavior: Clip.antiAlias, + decoration: const BoxDecoration( + color: AppColor.colorEventDescriptionBackground, + borderRadius: BorderRadius.all(Radius.circular(EventDescriptionDetailWidgetStyles.borderRadius)), + ), + width: double.infinity, + padding: const EdgeInsetsDirectional.all(EventDescriptionDetailWidgetStyles.contentPadding), + child: Stack( + children: [ + Text( + description, + style: const TextStyle( + fontWeight: FontWeight.w500, + fontSize: EventDescriptionDetailWidgetStyles.textSize, + color: EventDescriptionDetailWidgetStyles.valueColor + ) + ), + PositionedDirectional( + top: 0, + end: 0, + child: SvgPicture.asset(imagePath.icFormatQuote) + ) + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/features/email/presentation/widgets/calendar_event/event_link_detail_widget.dart b/lib/features/email/presentation/widgets/calendar_event/event_link_detail_widget.dart new file mode 100644 index 0000000000..32bbccd945 --- /dev/null +++ b/lib/features/email/presentation/widgets/calendar_event/event_link_detail_widget.dart @@ -0,0 +1,39 @@ + +import 'package:flutter/material.dart'; +import 'package:tmail_ui_user/features/base/widget/hyper_link_widget.dart'; +import 'package:tmail_ui_user/features/email/presentation/styles/event_link_detail_widget_styles.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +class EventLinkDetailWidget extends StatelessWidget { + + final List listHyperLink; + + const EventLinkDetailWidget({ + super.key, + required this.listHyperLink + }); + + @override + Widget build(BuildContext context) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: EventLinkDetailWidgetStyles.maxWidth, + child: Text( + AppLocalizations.of(context).link, + style: const TextStyle( + fontSize: EventLinkDetailWidgetStyles.textSize, + fontWeight: FontWeight.w500, + color: EventLinkDetailWidgetStyles.labelColor + ), + ), + ), + Expanded(child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: listHyperLink.map((link) => HyperLinkWidget(urlString: link)).toList(), + )) + ], + ); + } +} \ No newline at end of file diff --git a/lib/features/email/presentation/widgets/calendar_event/event_location_detail_widget.dart b/lib/features/email/presentation/widgets/calendar_event/event_location_detail_widget.dart new file mode 100644 index 0000000000..36b046848d --- /dev/null +++ b/lib/features/email/presentation/widgets/calendar_event/event_location_detail_widget.dart @@ -0,0 +1,42 @@ + +import 'package:flutter/material.dart'; +import 'package:tmail_ui_user/features/email/presentation/styles/event_location_detail_widget_styles.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +class EventLocationDetailWidget extends StatelessWidget { + + final String locationEvent; + + const EventLocationDetailWidget({ + super.key, + required this.locationEvent + }); + + @override + Widget build(BuildContext context) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: EventLocationDetailWidgetStyles.maxWidth, + child: Text( + AppLocalizations.of(context).location, + style: const TextStyle( + fontSize: EventLocationDetailWidgetStyles.textSize, + fontWeight: FontWeight.w500, + color: EventLocationDetailWidgetStyles.labelColor + ), + ), + ), + Expanded(child: Text( + locationEvent, + style: const TextStyle( + fontSize: EventLocationDetailWidgetStyles.textSize, + fontWeight: FontWeight.w500, + color: EventLocationDetailWidgetStyles.valueColor + ), + )) + ], + ); + } +} \ No newline at end of file diff --git a/lib/features/email/presentation/widgets/calendar_event/event_location_information_widget.dart b/lib/features/email/presentation/widgets/calendar_event/event_location_information_widget.dart index f19c917d71..3aa35ff053 100644 --- a/lib/features/email/presentation/widgets/calendar_event/event_location_information_widget.dart +++ b/lib/features/email/presentation/widgets/calendar_event/event_location_information_widget.dart @@ -1,6 +1,8 @@ +import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/presentation/utils/style_utils.dart'; import 'package:flutter/material.dart'; +import 'package:get/get.dart'; import 'package:tmail_ui_user/features/email/presentation/styles/event_location_information_widget_styles.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; @@ -15,6 +17,7 @@ class EventLocationInformationWidget extends StatelessWidget { @override Widget build(BuildContext context) { + final responsiveUtils = Get.find(); return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -31,8 +34,9 @@ class EventLocationInformationWidget extends StatelessWidget { ), Expanded(child: Text( locationEvent, - overflow: CommonTextStyle.defaultTextOverFlow, - softWrap: CommonTextStyle.defaultSoftWrap, + overflow: responsiveUtils.isPortraitMobile(context) ? null : CommonTextStyle.defaultTextOverFlow, + softWrap: responsiveUtils.isPortraitMobile(context) ? null : CommonTextStyle.defaultSoftWrap, + maxLines: responsiveUtils.isPortraitMobile(context) ? null : 1, style: const TextStyle( fontSize: EventLocationInformationWidgetStyles.textSize, fontWeight: FontWeight.w500, diff --git a/lib/features/email/presentation/widgets/calendar_event/event_time_detail_widget.dart b/lib/features/email/presentation/widgets/calendar_event/event_time_detail_widget.dart new file mode 100644 index 0000000000..1af9a6ca94 --- /dev/null +++ b/lib/features/email/presentation/widgets/calendar_event/event_time_detail_widget.dart @@ -0,0 +1,42 @@ + +import 'package:flutter/material.dart'; +import 'package:tmail_ui_user/features/email/presentation/styles/event_time_detail_widget_styles.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +class EventTimeWidgetWidget extends StatelessWidget { + + final String timeEvent; + + const EventTimeWidgetWidget({ + super.key, + required this.timeEvent + }); + + @override + Widget build(BuildContext context) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: EventTimeDetailWidgetStyles.maxWidth, + child: Text( + AppLocalizations.of(context).time, + style: const TextStyle( + fontSize: EventTimeDetailWidgetStyles.textSize, + fontWeight: FontWeight.w500, + color: EventTimeDetailWidgetStyles.labelColor + ), + ), + ), + Expanded(child: Text( + timeEvent, + style: const TextStyle( + fontSize: EventTimeDetailWidgetStyles.textSize, + fontWeight: FontWeight.w500, + color: EventTimeDetailWidgetStyles.valueColor + ), + )) + ], + ); + } +} \ No newline at end of file diff --git a/lib/features/email/presentation/widgets/calendar_event/event_time_information_widget.dart b/lib/features/email/presentation/widgets/calendar_event/event_time_information_widget.dart index 4d8af58d42..1130e5a23e 100644 --- a/lib/features/email/presentation/widgets/calendar_event/event_time_information_widget.dart +++ b/lib/features/email/presentation/widgets/calendar_event/event_time_information_widget.dart @@ -1,6 +1,8 @@ +import 'package:core/presentation/utils/responsive_utils.dart'; import 'package:core/presentation/utils/style_utils.dart'; import 'package:flutter/material.dart'; +import 'package:get/get.dart'; import 'package:tmail_ui_user/features/email/presentation/styles/event_time_information_widget_styles.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; @@ -15,6 +17,7 @@ class EventTimeInformationWidget extends StatelessWidget { @override Widget build(BuildContext context) { + final responsiveUtils = Get.find(); return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -31,8 +34,9 @@ class EventTimeInformationWidget extends StatelessWidget { ), Expanded(child: Text( timeEvent, - overflow: CommonTextStyle.defaultTextOverFlow, - softWrap: CommonTextStyle.defaultSoftWrap, + overflow: responsiveUtils.isPortraitMobile(context) ? null : CommonTextStyle.defaultTextOverFlow, + softWrap: responsiveUtils.isPortraitMobile(context) ? null : CommonTextStyle.defaultSoftWrap, + maxLines: responsiveUtils.isPortraitMobile(context) ? null : 1, style: const TextStyle( fontSize: EventTimeInformationWidgetStyles.textSize, fontWeight: FontWeight.w500, diff --git a/lib/features/email/presentation/widgets/calendar_event/event_title_widget.dart b/lib/features/email/presentation/widgets/calendar_event/event_title_widget.dart new file mode 100644 index 0000000000..99284c95c1 --- /dev/null +++ b/lib/features/email/presentation/widgets/calendar_event/event_title_widget.dart @@ -0,0 +1,22 @@ + +import 'package:flutter/material.dart'; +import 'package:tmail_ui_user/features/email/presentation/styles/event_title_widget_styles.dart'; + +class EventTitleWidget extends StatelessWidget { + + final String title; + + const EventTitleWidget({super.key, required this.title}); + + @override + Widget build(BuildContext context) { + return Text( + title, + style: const TextStyle( + fontWeight: FontWeight.w500, + fontSize: EventTitleWidgetStyles.textSize, + color: EventTitleWidgetStyles.textColor + ) + ); + } +} \ No newline at end of file diff --git a/lib/features/email/presentation/widgets/calendar_event/organizer_widget.dart b/lib/features/email/presentation/widgets/calendar_event/organizer_widget.dart new file mode 100644 index 0000000000..4ac0dce035 --- /dev/null +++ b/lib/features/email/presentation/widgets/calendar_event/organizer_widget.dart @@ -0,0 +1,43 @@ + +import 'package:flutter/material.dart'; +import 'package:jmap_dart_client/jmap/mail/calendar/properties/calendar_organizer.dart'; +import 'package:tmail_ui_user/features/email/presentation/styles/organizer_widget_styles.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +class OrganizerWidget extends StatelessWidget { + + final CalendarOrganizer organizer; + + const OrganizerWidget({ + super.key, + required this.organizer + }); + + @override + Widget build(BuildContext context) { + return RichText( + text: TextSpan( + style: const TextStyle( + fontSize: OrganizerWidgetStyles.textSize, + fontWeight: FontWeight.w500, + color: OrganizerWidgetStyles.textColor + ), + children: [ + if (organizer.name?.isNotEmpty == true) + TextSpan(text: organizer.name!), + if (organizer.mailto?.value.isNotEmpty == true) + TextSpan( + text: ' <${organizer.mailto!.value}> ', + style: const TextStyle( + color: OrganizerWidgetStyles.mailtoColor, + fontSize: OrganizerWidgetStyles.textSize, + fontWeight: FontWeight.w500 + ), + ), + TextSpan(text: '(${AppLocalizations.of(context).organizer})'), + const TextSpan(text: ', '), + ] + ) + ); + } +} \ No newline at end of file diff --git a/lib/features/email/presentation/widgets/calendar_event/see_all_attendees_button_widget.dart b/lib/features/email/presentation/widgets/calendar_event/see_all_attendees_button_widget.dart new file mode 100644 index 0000000000..78ce4d4dcf --- /dev/null +++ b/lib/features/email/presentation/widgets/calendar_event/see_all_attendees_button_widget.dart @@ -0,0 +1,35 @@ + +import 'package:flutter/cupertino.dart'; +import 'package:tmail_ui_user/features/base/widget/material_text_button.dart'; +import 'package:tmail_ui_user/features/email/presentation/styles/see_all_attendees_button_widget_styles.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +class SeeAllAttendeesButtonWidget extends StatelessWidget { + + final VoidCallback onTap; + + const SeeAllAttendeesButtonWidget({ + super.key, + required this.onTap + }); + + @override + Widget build(BuildContext context) { + return Transform( + transform: Matrix4.translationValues(SeeAllAttendeesButtonWidgetStyles.horizontalMargin, 0.0, 0.0), + child: MaterialTextButton( + label: AppLocalizations.of(context).seeAllAttendees, + onTap: onTap, + borderRadius: SeeAllAttendeesButtonWidgetStyles.borderRadius, + padding: const EdgeInsetsDirectional.symmetric( + horizontal: SeeAllAttendeesButtonWidgetStyles.horizontalPadding, + vertical: SeeAllAttendeesButtonWidgetStyles.verticalPadding + ), + customStyle: const TextStyle( + fontSize: SeeAllAttendeesButtonWidgetStyles.textSize, + color: SeeAllAttendeesButtonWidgetStyles.textColor + ), + ), + ); + } +} diff --git a/lib/features/email/presentation/widgets/email_view_loading_bar_widget.dart b/lib/features/email/presentation/widgets/email_view_loading_bar_widget.dart new file mode 100644 index 0000000000..4d92cf4785 --- /dev/null +++ b/lib/features/email/presentation/widgets/email_view_loading_bar_widget.dart @@ -0,0 +1,34 @@ +import 'package:core/presentation/state/failure.dart'; +import 'package:core/presentation/state/success.dart'; +import 'package:dartz/dartz.dart'; +import 'package:flutter/material.dart'; +import 'package:model/email/presentation_email.dart'; +import 'package:tmail_ui_user/features/base/widget/cupertino_loading_widget.dart'; +import 'package:tmail_ui_user/features/email/domain/state/get_email_content_state.dart'; +import 'package:tmail_ui_user/features/email/domain/state/parse_calendar_event_state.dart'; + +class EmailViewLoadingBarWidget extends StatelessWidget { + + final PresentationEmail selectedEmail; + final Either viewState; + + const EmailViewLoadingBarWidget({ + super.key, + required this.viewState, + required this.selectedEmail + }); + + @override + Widget build(BuildContext context) { + return viewState.fold( + (failure) => const SizedBox.shrink(), + (success) { + if (success is GetEmailContentLoading || (success is ParseCalendarEventLoading && selectedEmail.hasCalendarEvent)) { + return const CupertinoLoadingWidget(); + } else { + return const SizedBox.shrink(); + } + } + ); + } +} diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb index b5aa0216c2..7dfb0a04b5 100644 --- a/lib/l10n/intl_messages.arb +++ b/lib/l10n/intl_messages.arb @@ -1,5 +1,5 @@ { - "@@last_modified": "2023-07-26T18:42:34.026265", + "@@last_modified": "2023-07-28T02:46:38.430701", "initializing_data": "Initializing data...", "@initializing_data": { "type": "text", @@ -3077,5 +3077,35 @@ "type": "text", "placeholders_order": [], "placeholders": {} + }, + "time": "Time", + "@time": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "location": "Location", + "@location": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "attendees": "Attendees", + "@attendees": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "seeAllAttendees": "See all attendees", + "@seeAllAttendees": { + "type": "text", + "placeholders_order": [], + "placeholders": {} + }, + "link": "Link", + "@link": { + "type": "text", + "placeholders_order": [], + "placeholders": {} } } \ No newline at end of file diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart index f4102265b6..29e81d2090 100644 --- a/lib/main/localizations/app_localizations.dart +++ b/lib/main/localizations/app_localizations.dart @@ -3173,4 +3173,35 @@ class AppLocalizations { 'Organizer', name: 'organizer'); } + + String get time { + return Intl.message( + 'Time', + name: 'time', + ); + } + + String get location { + return Intl.message( + 'Location', + name: 'location'); + } + + String get attendees { + return Intl.message( + 'Attendees', + name: 'attendees'); + } + + String get seeAllAttendees { + return Intl.message( + 'See all attendees', + name: 'seeAllAttendees'); + } + + String get link { + return Intl.message( + 'Link', + name: 'link'); + } } \ No newline at end of file