Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TF-2907 Disable YES/NO/MAYBE action for events when missing METHOD/ORGANIZER/ATTENDEES in ics #2915

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions contact/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -611,8 +611,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: migrate_cnb_to_master_5Jun
resolved-ref: "49305a382ca77211a0668fd9fe196a3c057cdc8e"
ref: sprint25_from_migrate_5jun
resolved-ref: "4783ba7b56eb4dda591538d9c486375162a9da79"
url: "https://github.com/linagora/jmap-dart-client.git"
source: git
version: "0.0.1"
Expand Down
2 changes: 1 addition & 1 deletion contact/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ dependencies:
jmap_dart_client:
git:
url: https://github.com/linagora/jmap-dart-client.git
ref: migrate_cnb_to_master_5Jun
ref: sprint25_from_migrate_5jun

### Dependencies from pub.dev ###
equatable: 2.0.5
Expand Down
4 changes: 2 additions & 2 deletions email_recovery/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: migrate_cnb_to_master_5Jun
resolved-ref: "49305a382ca77211a0668fd9fe196a3c057cdc8e"
ref: sprint25_from_migrate_5jun
resolved-ref: "4783ba7b56eb4dda591538d9c486375162a9da79"
url: "https://github.com/linagora/jmap-dart-client.git"
source: git
version: "0.0.1"
Expand Down
2 changes: 1 addition & 1 deletion email_recovery/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dependencies:
jmap_dart_client:
git:
url: https://github.com/linagora/jmap-dart-client.git
ref: migrate_cnb_to_master_5Jun
ref: sprint25_from_migrate_5jun

### Dependencies from pub.dev ###
equatable: 2.0.5
Expand Down
4 changes: 2 additions & 2 deletions fcm/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: migrate_cnb_to_master_5Jun
resolved-ref: "49305a382ca77211a0668fd9fe196a3c057cdc8e"
ref: sprint25_from_migrate_5jun
resolved-ref: "4783ba7b56eb4dda591538d9c486375162a9da79"
url: "https://github.com/linagora/jmap-dart-client.git"
source: git
version: "0.0.1"
Expand Down
2 changes: 1 addition & 1 deletion fcm/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dependencies:
jmap_dart_client:
git:
url: https://github.com/linagora/jmap-dart-client.git
ref: migrate_cnb_to_master_5Jun
ref: sprint25_from_migrate_5jun

### Dependencies from pub.dev ###
equatable: 2.0.5
Expand Down
4 changes: 2 additions & 2 deletions forward/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: migrate_cnb_to_master_5Jun
resolved-ref: "49305a382ca77211a0668fd9fe196a3c057cdc8e"
ref: sprint25_from_migrate_5jun
resolved-ref: "4783ba7b56eb4dda591538d9c486375162a9da79"
url: "https://github.com/linagora/jmap-dart-client.git"
source: git
version: "0.0.1"
Expand Down
2 changes: 1 addition & 1 deletion forward/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dependencies:
jmap_dart_client:
git:
url: https://github.com/linagora/jmap-dart-client.git
ref: migrate_cnb_to_master_5Jun
ref: sprint25_from_migrate_5jun

### Dependencies from pub.dev ###
equatable: 2.0.5
Expand Down
18 changes: 15 additions & 3 deletions lib/features/email/data/network/calendar_event_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ class CalendarEventAPI {
throw NotAcceptableCalendarEventException();
}

return calendarEventAcceptResponse;
if (calendarEventAcceptResponse.accepted?.isNotEmpty == true) {
return calendarEventAcceptResponse;
} else {
throw CannotReplyCalendarEventException(mapErrors: calendarEventAcceptResponse.notAccepted);
}
}

Future<CalendarEventMaybeResponse> maybeEventInvitation(
Expand Down Expand Up @@ -102,7 +106,11 @@ class CalendarEventAPI {
throw NotMaybeableCalendarEventException();
}

return calendarEventMaybeResponse;
if (calendarEventMaybeResponse.maybe?.isNotEmpty == true) {
return calendarEventMaybeResponse;
} else {
throw CannotReplyCalendarEventException(mapErrors: calendarEventMaybeResponse.notMaybe);
}
}

Future<CalendarEventRejectResponse> rejectEventInvitation(
Expand Down Expand Up @@ -130,6 +138,10 @@ class CalendarEventAPI {
throw NotRejectableCalendarEventException();
}

return calendarEventRejectResponse;
if (calendarEventRejectResponse.rejected?.isNotEmpty == true) {
return calendarEventRejectResponse;
} else {
throw CannotReplyCalendarEventException(mapErrors: calendarEventRejectResponse.notRejected);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

import 'package:jmap_dart_client/jmap/core/error/set_error.dart';
import 'package:jmap_dart_client/jmap/core/id.dart';

class NotFoundCalendarEventException implements Exception {}

class NotParsableCalendarEventException implements Exception {}
Expand All @@ -8,3 +11,9 @@ class NotAcceptableCalendarEventException implements Exception {}
class NotMaybeableCalendarEventException implements Exception {}

class NotRejectableCalendarEventException implements Exception {}

class CannotReplyCalendarEventException implements Exception {
final Map<Id, SetError>? mapErrors;

CannotReplyCalendarEventException({this.mapErrors});
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import 'package:tmail_ui_user/features/base/mixin/app_loader_mixin.dart';
import 'package:tmail_ui_user/features/base/state/button_state.dart';
import 'package:tmail_ui_user/features/composer/presentation/extensions/email_action_type_extension.dart';
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart';
import 'package:tmail_ui_user/features/email/domain/exceptions/calendar_event_exceptions.dart';
import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.dart';
import 'package:tmail_ui_user/features/email/domain/extensions/list_attachments_extension.dart';
import 'package:tmail_ui_user/features/email/domain/model/detailed_email.dart';
Expand Down Expand Up @@ -255,7 +256,7 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
_showMessageWhenEmailPrintingFailed(failure);
} else if (failure is CalendarEventReplyFailure
|| failure is StoreEventAttendanceStatusFailure) {
_calendarEventFailure();
_calendarEventFailure(failure);
}
}

Expand Down Expand Up @@ -1752,12 +1753,26 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
success.eventActionType.getToastMessageSuccess(currentContext!));
}

void _calendarEventFailure() {
if (currentOverlayContext != null && currentContext != null) {
appToast.showToastErrorMessage(
currentOverlayContext!,
AppLocalizations.of(currentContext!).eventReplyWasSentUnsuccessfully);
void _calendarEventFailure(Failure failure) {
if (currentOverlayContext == null || currentContext == null) {
return;
}

if (failure is CalendarEventReplyFailure && failure.exception is CannotReplyCalendarEventException) {
final replyEventException = failure.exception as CannotReplyCalendarEventException;

if (replyEventException.mapErrors?.isNotEmpty == true) {
appToast.showToastErrorMessage(
currentOverlayContext!,
replyEventException.mapErrors!.values.first.description
?? AppLocalizations.of(currentContext!).eventReplyWasSentUnsuccessfully);
return;
}
}

appToast.showToastErrorMessage(
currentOverlayContext!,
AppLocalizations.of(currentContext!).eventReplyWasSentUnsuccessfully);
}

void _downloadMessageAsEML(PresentationEmail presentationEmail) {
Expand Down
19 changes: 18 additions & 1 deletion lib/features/email/presentation/email_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,10 @@ class EmailView extends GetWidget<SingleEmailController> {
presentationEmail: controller.currentEmail,
onMailtoAttendeesAction: controller.handleMailToAttendees,
)),
if (calendarEvent.getTitleEventAction(context, emailAddressSender ?? []).isNotEmpty)
if (_validateDisplayEventActionBanner(
context: context,
event: calendarEvent,
emailAddressSender: emailAddressSender ?? []))
CalendarEventActionBannerWidget(
calendarEvent: calendarEvent,
listEmailAddressSender: emailAddressSender ?? []
Expand Down Expand Up @@ -472,6 +475,20 @@ class EmailView extends GetWidget<SingleEmailController> {
);
}

bool _validateDisplayEventActionBanner({
required BuildContext context,
required CalendarEvent event,
required List<String> emailAddressSender
}) {
final usernameEvent = event.getUserNameEventAction(
context: context,
imagePaths: controller.imagePaths,
listEmailAddressSender: emailAddressSender);
final titleEvent = event.getTitleEventAction(context, emailAddressSender);

return usernameEvent.isNotEmpty && titleEvent.isNotEmpty;
}

void _handleMoreEmailAction({
required BuildContext context,
required PresentationEmail presentationEmail,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ extension CalendarEventExtension on CalendarEvent {
case EventMethod.refresh:
case EventMethod.cancel:
case EventMethod.declineCounter:
return getOrganizerNameEvent(context);
return organizerName;
case EventMethod.reply:
case EventMethod.counter:
return getAttendeeNameEvent(context, listEmailAddressSender);
Expand All @@ -119,8 +119,6 @@ extension CalendarEventExtension on CalendarEvent {
}
}

String getOrganizerNameEvent(BuildContext context) => organizer?.name ?? AppLocalizations.of(context).you;

String get organizerName => organizer?.name ?? organizer?.mailto?.value ?? '';

String getAttendeeNameEvent(BuildContext context, List<String> listEmailAddressSender) {
Expand Down Expand Up @@ -356,4 +354,8 @@ extension CalendarEventExtension on CalendarEvent {
}
return [];
}

bool get isDisplayedEventReplyAction => method != null
&& organizer != null
&& participants?.isNotEmpty == true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ extension ListAttendeeExtension on List<CalendarAttendee> {
.join(', ');
}

List<CalendarAttendee> withoutOrganizer(CalendarOrganizer organizer) {
return where((attendee) => attendee.mailto?.mailAddress != organizer.mailto)
.whereNotNull()
.toList();
List<CalendarAttendee> withoutOrganizer(CalendarOrganizer? organizer) {
if (organizer == null) {
return this;
}
return where((attendee) => attendee.mailto?.mailAddress != organizer.mailto)
.whereNotNull()
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,13 @@ class CalendarEventDetailWidget extends StatelessWidget {
children: [
if (calendarEvent.title?.isNotEmpty == true)
EventTitleWidget(title: calendarEvent.title!),
Padding(
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventBodyContentWidget(
content: eventDesc,
isDraggableAppActive: isDraggableAppActive,
onMailtoDelegateAction: onMailtoDelegateAction)),
if (eventDesc.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventBodyContentWidget(
content: eventDesc,
isDraggableAppActive: isDraggableAppActive,
onMailtoDelegateAction: onMailtoDelegateAction)),
_buildEventTimeWidget(),
if (calendarEvent.videoConferences.isNotEmpty)
Padding(
Expand All @@ -93,23 +94,24 @@ class CalendarEventDetailWidget extends StatelessWidget {
onOpenNewTabAction: onOpenNewTabAction,
),
),
if (calendarEvent.participants?.isNotEmpty == true && calendarEvent.organizer != null)
if (calendarEvent.participants?.isNotEmpty == true || calendarEvent.organizer != null)
Padding(
padding: const EdgeInsets.only(top: CalendarEventDetailWidgetStyles.fieldTopPadding),
child: EventAttendeeDetailWidget(
attendees: calendarEvent.participants!,
organizer: calendarEvent.organizer!,
attendees: calendarEvent.participants ?? [],
organizer: calendarEvent.organizer,
),
),
CalendarEventActionButtonWidget(
onCalendarEventReplyActionClick: onCalendarEventReplyActionClick,
calendarEventReplying: calendarEventReplying,
presentationEmail: presentationEmail,
onMailToAttendeesAction: () => onMailtoAttendeesAction?.call(
calendarEvent.organizer,
calendarEvent.participants,
if (calendarEvent.isDisplayedEventReplyAction)
CalendarEventActionButtonWidget(
onCalendarEventReplyActionClick: onCalendarEventReplyActionClick,
calendarEventReplying: calendarEventReplying,
presentationEmail: presentationEmail,
onMailToAttendeesAction: () => onMailtoAttendeesAction?.call(
calendarEvent.organizer,
calendarEvent.participants,
),
),
),
],
),
);
Expand Down
Loading
Loading