From 474a8806e2d7140a0fe94171b9341c4e0d1c974e Mon Sep 17 00:00:00 2001 From: dab246 Date: Wed, 15 Oct 2025 15:17:12 +0700 Subject: [PATCH] TF-4102 Don't display free-busy on IMIP responses (accepted, tentative, rejected) --- lib/features/email/presentation/email_view.dart | 3 ++- .../extensions/calendar_event_extension.dart | 11 +++++++++++ ...validate_display_free_busy_message_extension.dart | 9 +++++++++ .../calendar_event_information_widget.dart | 6 +++--- .../event_time_information_widget.dart | 6 +++--- .../calendar_event_information_widget_test.dart | 6 +++--- .../event_time_information_widget_test.dart | 12 ++++++------ 7 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 lib/features/email/presentation/extensions/validate_display_free_busy_message_extension.dart diff --git a/lib/features/email/presentation/email_view.dart b/lib/features/email/presentation/email_view.dart index ab122fe7e..f509c7799 100644 --- a/lib/features/email/presentation/email_view.dart +++ b/lib/features/email/presentation/email_view.dart @@ -19,6 +19,7 @@ import 'package:tmail_ui_user/features/base/widget/optional_expanded.dart'; import 'package:tmail_ui_user/features/base/widget/optional_scroll.dart'; import 'package:tmail_ui_user/features/email/presentation/controller/single_email_controller.dart'; import 'package:tmail_ui_user/features/email/presentation/extensions/calendar_event_extension.dart'; +import 'package:tmail_ui_user/features/email/presentation/extensions/validate_display_free_busy_message_extension.dart'; import 'package:tmail_ui_user/features/email/presentation/styles/email_view_styles.dart'; import 'package:tmail_ui_user/features/email/presentation/utils/email_action_reactor/email_action_reactor.dart'; import 'package:tmail_ui_user/features/email/presentation/widgets/calendar_event/calendar_event_action_banner_widget.dart'; @@ -315,7 +316,7 @@ class EmailView extends GetWidget { ownEmailAddress: controller.ownEmailAddress, onMailtoAttendeesAction: controller.handleMailToAttendees, openEmailAddressDetailAction: (_, emailAddress) => controller.openEmailAddressDialog(emailAddress), - isFree: controller.isCalendarEventFree, + isFreeBusyEnabled: controller.isFreeBusyEnabled(emailAddressSender ?? []), listEmailAddressSender: emailAddressSender ?? [], isPortraitMobile: controller .responsiveUtils diff --git a/lib/features/email/presentation/extensions/calendar_event_extension.dart b/lib/features/email/presentation/extensions/calendar_event_extension.dart index dcd7bef9c..d712c2410 100644 --- a/lib/features/email/presentation/extensions/calendar_event_extension.dart +++ b/lib/features/email/presentation/extensions/calendar_event_extension.dart @@ -437,6 +437,17 @@ extension CalendarEventExtension on CalendarEvent { } } + bool isIMIPResponsesAvailable(List listEmailAddressSender) { + final participationStatus = findAttendeeHasUpdatedStatus( + listEmailAddressSender, + )?.participationStatus?.value; + + return method == EventMethod.reply && + (participationStatus == acceptedParticipationStatus || + participationStatus == tentativeParticipationStatus || + participationStatus == declinedParticipationStatus); + } + CalendarEvent copyWith({ EventId? eventId, String? title, diff --git a/lib/features/email/presentation/extensions/validate_display_free_busy_message_extension.dart b/lib/features/email/presentation/extensions/validate_display_free_busy_message_extension.dart new file mode 100644 index 000000000..975dfc909 --- /dev/null +++ b/lib/features/email/presentation/extensions/validate_display_free_busy_message_extension.dart @@ -0,0 +1,9 @@ +import 'package:tmail_ui_user/features/email/presentation/controller/single_email_controller.dart'; +import 'package:tmail_ui_user/features/email/presentation/extensions/calendar_event_extension.dart'; + +extension ValidateDisplayFreeBusyMessageExtension on SingleEmailController { + bool isFreeBusyEnabled(List listEmailAddressSender) { + return !isCalendarEventFree && + calendarEvent?.isIMIPResponsesAvailable(listEmailAddressSender) != true; + } +} 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 a30fb1cf1..0fa8cd6ec 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 @@ -31,7 +31,7 @@ class CalendarEventInformationWidget extends StatelessWidget { final AttendanceStatus? attendanceStatus; final OnMailtoAttendeesAction? onMailtoAttendeesAction; final OnOpenEmailAddressDetailAction? openEmailAddressDetailAction; - final bool isFree; + final bool isFreeBusyEnabled; final List listEmailAddressSender; final String ownEmailAddress; final bool isPortraitMobile; @@ -41,7 +41,7 @@ class CalendarEventInformationWidget extends StatelessWidget { required this.calendarEvent, required this.onCalendarEventReplyActionClick, required this.calendarEventReplying, - required this.isFree, + required this.isFreeBusyEnabled, required this.ownEmailAddress, this.onOpenNewTabAction, this.onOpenComposerAction, @@ -233,7 +233,7 @@ class CalendarEventInformationWidget extends StatelessWidget { padding: const EdgeInsets.only(top: CalendarEventInformationWidgetStyles.fieldTopPadding), child: EventTimeInformationWidget( timeEvent: dateTimeEvent, - isFree: isFree, + isFreeBusyEnabled: isFreeBusyEnabled, ), ); } else { 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 96247da14..89eb99aee 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 @@ -13,12 +13,12 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; class EventTimeInformationWidget extends StatelessWidget { final String timeEvent; - final bool isFree; + final bool isFreeBusyEnabled; const EventTimeInformationWidget({ super.key, required this.timeEvent, - required this.isFree, + required this.isFreeBusyEnabled, }); @override @@ -51,7 +51,7 @@ class EventTimeInformationWidget extends StatelessWidget { color: EventTimeInformationWidgetStyles.valueColor ), )), - if (!isFree) + if (isFreeBusyEnabled) ...[ const SizedBox(width: EventTimeInformationWidgetStyles.horizontalSpacing), Tooltip( diff --git a/test/features/email/presentation/widgets/calendar_event/calendar_event_information_widget_test.dart b/test/features/email/presentation/widgets/calendar_event/calendar_event_information_widget_test.dart index e98f02470..2f555d316 100644 --- a/test/features/email/presentation/widgets/calendar_event/calendar_event_information_widget_test.dart +++ b/test/features/email/presentation/widgets/calendar_event/calendar_event_information_widget_test.dart @@ -38,7 +38,7 @@ void main() { calendarEvent: calendarEvent, onCalendarEventReplyActionClick: (_) {}, calendarEventReplying: false, - isFree: false, + isFreeBusyEnabled: false, ownEmailAddress: ownEmail, ), ), @@ -81,7 +81,7 @@ void main() { calendarEvent: calendarEvent, onCalendarEventReplyActionClick: (_) {}, calendarEventReplying: false, - isFree: false, + isFreeBusyEnabled: false, ownEmailAddress: ownEmail, ), ), @@ -121,7 +121,7 @@ void main() { calendarEvent: calendarEvent, onCalendarEventReplyActionClick: (_) {}, calendarEventReplying: false, - isFree: false, + isFreeBusyEnabled: false, ownEmailAddress: ownEmail, ), ), diff --git a/test/features/email/presentation/widgets/calendar_event/event_time_information_widget_test.dart b/test/features/email/presentation/widgets/calendar_event/event_time_information_widget_test.dart index 88af3deda..c8b407038 100644 --- a/test/features/email/presentation/widgets/calendar_event/event_time_information_widget_test.dart +++ b/test/features/email/presentation/widgets/calendar_event/event_time_information_widget_test.dart @@ -21,21 +21,21 @@ void main() { group('EventTimeInformationWidget tests', () { Widget makeTestableWidget({ required String timeEvent, - required bool isFree, + required bool isFreeBusyEnabled, }) { return WidgetFixtures.makeTestableWidget( child: EventTimeInformationWidget( timeEvent: timeEvent, - isFree: isFree, + isFreeBusyEnabled: isFreeBusyEnabled, ), ); } - testWidgets('should show error icon with tooltip when isFree is false', (tester) async { + testWidgets('should show error icon with tooltip when isFreeBusyEnabled is true', (tester) async { // arrange final widget = makeTestableWidget( timeEvent: '10:00 AM - 11:00 AM', - isFree: false, + isFreeBusyEnabled: true, ); // act @@ -51,11 +51,11 @@ void main() { expect(find.byType(Tooltip), findsOneWidget); }); - testWidgets('should not show error icon when isFree is true', (tester) async { + testWidgets('should not show error icon when isFreeBusyEnabled is false', (tester) async { // arrange final widget = makeTestableWidget( timeEvent: '10:00 AM - 11:00 AM', - isFree: true, + isFreeBusyEnabled: false, ); // act