TF-2949 Fix remove duplicated information in email of calendar event

This commit is contained in:
dab246
2024-07-19 16:34:42 +07:00
committed by Dat H. Pham
parent 957fe7a78c
commit 47a140be62
9 changed files with 22 additions and 333 deletions
@@ -374,14 +374,8 @@ class EmailView extends GetWidget<SingleEmailController> {
calendarEvent: calendarEvent,
emailContent: controller.currentEmailLoaded.value?.htmlContent ?? '',
isDraggableAppActive: controller.mailboxDashBoardController.isAttachmentDraggableAppActive,
onOpenComposerAction: controller.openNewComposerAction,
onOpenNewTabAction: controller.openNewTabAction,
onMailtoDelegateAction: controller.openMailToLink,
onCalendarEventReplyActionClick: (eventActionType) =>
controller.onCalendarEventReplyAction(eventActionType, presentationEmail.id!),
calendarEventReplying: controller.calendarEventProcessing,
presentationEmail: controller.currentEmail,
onMailtoAttendeesAction: controller.handleMailToAttendees,
)),
],
)
@@ -4,16 +4,9 @@ import 'package:jmap_dart_client/jmap/mail/calendar/calendar_event.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:model/email/presentation_email.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/calendar_event_action_button_widget.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_body_content_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';
import 'package:tmail_ui_user/main/utils/app_utils.dart';
typedef OnMailtoAttendeesAction = Function(CalendarOrganizer? organizer, List<CalendarAttendee>? participants);
@@ -21,27 +14,17 @@ class CalendarEventDetailWidget extends StatelessWidget {
final CalendarEvent calendarEvent;
final String emailContent;
final OnOpenNewTabAction? onOpenNewTabAction;
final OnOpenComposerAction? onOpenComposerAction;
final bool? isDraggableAppActive;
final OnMailtoDelegateAction? onMailtoDelegateAction;
final OnCalendarEventReplyActionClick onCalendarEventReplyActionClick;
final bool calendarEventReplying;
final PresentationEmail? presentationEmail;
final OnMailtoAttendeesAction? onMailtoAttendeesAction;
const CalendarEventDetailWidget({
super.key,
required this.calendarEvent,
required this.emailContent,
required this.onCalendarEventReplyActionClick,
required this.calendarEventReplying,
this.isDraggableAppActive,
this.onOpenNewTabAction,
this.onOpenComposerAction,
this.onMailtoDelegateAction,
this.presentationEmail,
this.onMailtoAttendeesAction,
});
@override
@@ -79,56 +62,8 @@ class CalendarEventDetailWidget extends StatelessWidget {
content: eventDesc,
isDraggableAppActive: isDraggableAppActive,
onMailtoDelegateAction: onMailtoDelegateAction)),
_buildEventTimeWidget(),
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!,
onOpenComposerAction: onOpenComposerAction,
onOpenNewTabAction: onOpenNewTabAction,
),
),
if (calendarEvent.participants?.isNotEmpty == true || calendarEvent.organizer != null)
Padding(
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventAttendeeDetailWidget(
attendees: calendarEvent.participants ?? [],
organizer: calendarEvent.organizer,
),
),
if (calendarEvent.isDisplayedEventReplyAction)
CalendarEventActionButtonWidget(
onCalendarEventReplyActionClick: onCalendarEventReplyActionClick,
calendarEventReplying: calendarEventReplying,
presentationEmail: presentationEmail,
onMailToAttendeesAction: () => onMailtoAttendeesAction?.call(
calendarEvent.organizer,
calendarEvent.participants,
),
),
],
),
);
}
Widget _buildEventTimeWidget() {
final dateTimeEvent = calendarEvent.getDateTimeEvent(
dateLocale: AppUtils.getCurrentDateLocale(),
timeZone: AppUtils.getTimeZone()
);
if (dateTimeEvent.isNotEmpty) {
return Padding(
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventTimeWidgetWidget(timeEvent: dateTimeEvent),
);
} else {
return const SizedBox.shrink();
}
}
}
@@ -5,18 +5,22 @@ import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/calendar/calendar_event.dart';
import 'package:model/email/presentation_email.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/styles/calendar_event_information_widget_styles.dart';
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/calendar_event_action_button_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/event_attendee_information_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_attendee_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_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';
import 'package:tmail_ui_user/main/utils/app_utils.dart';
typedef OnOpenNewTabAction = void Function(String link);
typedef OnOpenComposerAction = void Function(String emailAddress);
class CalendarEventInformationWidget extends StatelessWidget {
final CalendarEvent calendarEvent;
@@ -115,10 +119,15 @@ class CalendarEventInformationWidget extends StatelessWidget {
onOpenNewTabAction: onOpenNewTabAction,
),
),
if (calendarEvent.videoConferences.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventLinkDetailWidget(listHyperLink: calendarEvent.videoConferences),
),
if (calendarEvent.participants?.isNotEmpty == true || calendarEvent.organizer != null)
Padding(
padding: const EdgeInsets.only(top: CalendarEventInformationWidgetStyles.fieldTopPadding),
child: EventAttendeeInformationWidget(
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventAttendeeDetailWidget(
attendees: calendarEvent.participants ?? [],
organizer: calendarEvent.organizer,
),
@@ -195,10 +204,15 @@ class CalendarEventInformationWidget extends StatelessWidget {
onOpenNewTabAction: onOpenNewTabAction,
),
),
if (calendarEvent.videoConferences.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventLinkDetailWidget(listHyperLink: calendarEvent.videoConferences),
),
if (calendarEvent.participants?.isNotEmpty == true || calendarEvent.organizer != null)
Padding(
padding: const EdgeInsets.only(top: CalendarEventInformationWidgetStyles.fieldTopPadding),
child: EventAttendeeInformationWidget(
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventAttendeeDetailWidget(
attendees: calendarEvent.participants ?? [],
organizer: calendarEvent.organizer,
),
@@ -48,7 +48,7 @@ class _EventAttendeeDetailWidgetState extends State<EventAttendeeDetailWidget> {
SizedBox(
width: EventAttendeeDetailWidgetStyles.maxWidth,
child: Text(
AppLocalizations.of(context).attendees,
AppLocalizations.of(context).who,
style: const TextStyle(
fontSize: EventAttendeeDetailWidgetStyles.textSize,
fontWeight: FontWeight.w500,
@@ -1,72 +0,0 @@
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';
import 'package:tmail_ui_user/features/email/presentation/styles/event_attendee_information_widget_styles.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class EventAttendeeInformationWidget extends StatelessWidget {
final List<CalendarAttendee> attendees;
final CalendarOrganizer? organizer;
final _responsiveUtils = Get.find<ResponsiveUtils>();
EventAttendeeInformationWidget({
super.key,
required this.attendees,
required this.organizer
});
@override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: EventAttendeeInformationWidgetStyles.maxWidth,
child: Text(
AppLocalizations.of(context).who,
style: const TextStyle(
fontSize: EventAttendeeInformationWidgetStyles.textSize,
fontWeight: FontWeight.w500,
color: EventAttendeeInformationWidgetStyles.labelColor
),
),
),
Expanded(child: Text.rich(
TextSpan(
style: const TextStyle(
fontSize: EventAttendeeInformationWidgetStyles.textSize,
fontWeight: FontWeight.w500,
color: EventAttendeeInformationWidgetStyles.valueColor
),
children: [
if (organizer != null)
...[
TextSpan(
text: '${organizer!.mailto?.value} (${AppLocalizations.of(context).organizer})',
style: const TextStyle(
color: EventAttendeeInformationWidgetStyles.valueOrganizerColor,
fontSize: EventAttendeeInformationWidgetStyles.textSize,
fontWeight: FontWeight.w500
),
),
const TextSpan(text: ', '),
],
if (attendees.isNotEmpty)
TextSpan(text: attendees.withoutOrganizer(organizer).mailtoAsString)
]
),
overflow: _responsiveUtils.isPortraitMobile(context)
? TextOverflow.clip
: TextOverflow.ellipsis,
maxLines: _responsiveUtils.isPortraitMobile(context) ? null : 2,
))
],
);
}
}
@@ -1,72 +0,0 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/utils/app_logger.dart';
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.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';
import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/event_location_detail_widget.dart';
class EventDescriptionDetailWidget extends StatelessWidget {
final String description;
final OnOpenNewTabAction? onOpenNewTabAction;
final OnOpenComposerAction? onOpenComposerAction;
const EventDescriptionDetailWidget({
super.key,
required this.description,
this.onOpenNewTabAction,
this.onOpenComposerAction,
});
@override
Widget build(BuildContext context) {
final imagePath = Get.find<ImagePaths>();
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: [
Linkify(
onOpen: (element) {
log('EventDescriptionDetailWidget::build:element: $element');
if (element is UrlElement) {
onOpenNewTabAction?.call(element.url);
} else if (element is EmailElement) {
onOpenComposerAction?.call(element.emailAddress);
}
},
text: description,
linkifiers: const [
EmailLinkifier(),
UrlLinkifier()
],
style: const TextStyle(
fontWeight: FontWeight.w500,
fontSize: EventDescriptionDetailWidgetStyles.textSize,
color: EventDescriptionDetailWidgetStyles.valueColor
),
options: const LinkifyOptions(
removeWww: true,
looseUrl: true,
defaultToHttps: true
),
),
PositionedDirectional(
top: 0,
end: 0,
child: SvgPicture.asset(imagePath.icFormatQuote)
)
],
),
);
}
}
@@ -1,68 +0,0 @@
import 'package:core/utils/app_logger.dart';
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.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';
typedef OnOpenNewTabAction = void Function(String link);
typedef OnOpenComposerAction = void Function(String emailAddress);
class EventLocationDetailWidget extends StatelessWidget {
final String locationEvent;
final OnOpenNewTabAction? onOpenNewTabAction;
final OnOpenComposerAction? onOpenComposerAction;
const EventLocationDetailWidget({
super.key,
required this.locationEvent,
this.onOpenNewTabAction,
this.onOpenComposerAction,
});
@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: Linkify(
onOpen: (element) {
log('EventLocationDetailWidget::build:element: $element');
if (element is UrlElement) {
onOpenNewTabAction?.call(element.url);
} else if (element is EmailElement) {
onOpenComposerAction?.call(element.emailAddress);
}
},
text: locationEvent,
linkifiers: const [
EmailLinkifier(),
UrlLinkifier()
],
style: const TextStyle(
fontSize: EventLocationDetailWidgetStyles.textSize,
fontWeight: FontWeight.w500,
color: EventLocationDetailWidgetStyles.valueColor
),
options: const LinkifyOptions(
removeWww: true,
looseUrl: true,
defaultToHttps: true
),
))
],
);
}
}
@@ -3,7 +3,7 @@ import 'package:core/utils/app_logger.dart';
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:tmail_ui_user/features/email/presentation/styles/event_location_information_widget_styles.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/calendar_event_information_widget.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class EventLocationInformationWidget extends StatelessWidget {
@@ -1,42 +0,0 @@
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
),
))
],
);
}
}