TF-2859 Add language when reply calendar invitation

This commit is contained in:
DatDang
2024-05-17 14:44:36 +07:00
committed by Dat H. Pham
parent c2979429cf
commit 2e68e7df7d
10 changed files with 161 additions and 36 deletions
@@ -9,9 +9,18 @@ import 'package:tmail_ui_user/features/email/presentation/model/blob_calendar_ev
abstract class CalendarEventDataSource { abstract class CalendarEventDataSource {
Future<List<BlobCalendarEvent>> parse(AccountId accountId, Set<Id> blobIds); Future<List<BlobCalendarEvent>> parse(AccountId accountId, Set<Id> blobIds);
Future<CalendarEventAcceptResponse> acceptEventInvitation(AccountId accountId, Set<Id> blobIds); Future<CalendarEventAcceptResponse> acceptEventInvitation(
AccountId accountId,
Set<Id> blobIds,
String? language);
Future<CalendarEventMaybeResponse> maybeEventInvitation(AccountId accountId, Set<Id> blobIds); Future<CalendarEventMaybeResponse> maybeEventInvitation(
AccountId accountId,
Set<Id> blobIds,
String? language);
Future<CalendarEventRejectResponse> rejectEventInvitation(AccountId accountId, Set<Id> blobIds); Future<CalendarEventRejectResponse> rejectEventInvitation(
AccountId accountId,
Set<Id> blobIds,
String? language);
} }
@@ -24,23 +24,32 @@ class CalendarEventDataSourceImpl extends CalendarEventDataSource {
} }
@override @override
Future<CalendarEventAcceptResponse> acceptEventInvitation(AccountId accountId, Set<Id> blobIds) { Future<CalendarEventAcceptResponse> acceptEventInvitation(
AccountId accountId,
Set<Id> blobIds,
String? language) {
return Future.sync(() async { return Future.sync(() async {
return await _calendarEventAPI.acceptEventInvitation(accountId, blobIds); return await _calendarEventAPI.acceptEventInvitation(accountId, blobIds, language);
}).catchError(_exceptionThrower.throwException); }).catchError(_exceptionThrower.throwException);
} }
@override @override
Future<CalendarEventMaybeResponse> maybeEventInvitation(AccountId accountId, Set<Id> blobIds) { Future<CalendarEventMaybeResponse> maybeEventInvitation(
AccountId accountId,
Set<Id> blobIds,
String? language) {
return Future.sync(() async { return Future.sync(() async {
return await _calendarEventAPI.maybe(accountId, blobIds); return await _calendarEventAPI.maybeEventInvitation(accountId, blobIds, language);
}).catchError(_exceptionThrower.throwException); }).catchError(_exceptionThrower.throwException);
} }
@override @override
Future<CalendarEventRejectResponse> rejectEventInvitation(AccountId accountId, Set<Id> blobIds) { Future<CalendarEventRejectResponse> rejectEventInvitation(
AccountId accountId,
Set<Id> blobIds,
String? language) {
return Future.sync(() async { return Future.sync(() async {
return await _calendarEventAPI.reject(accountId, blobIds); return await _calendarEventAPI.rejectEventInvitation(accountId, blobIds, language);
}).catchError(_exceptionThrower.throwException); }).catchError(_exceptionThrower.throwException);
} }
} }
@@ -49,11 +49,18 @@ class CalendarEventAPI {
} }
} }
Future<CalendarEventAcceptResponse> acceptEventInvitation(AccountId accountId, Set<Id> blobIds) async { Future<CalendarEventAcceptResponse> acceptEventInvitation(
AccountId accountId,
Set<Id> blobIds,
String? language
) async {
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation()); final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
final calendarEventAcceptMethod = CalendarEventAcceptMethod( final calendarEventAcceptMethod = CalendarEventAcceptMethod(
accountId, accountId,
blobIds: blobIds.toList()); blobIds: blobIds.toList());
if (language != null) {
calendarEventAcceptMethod.addLanguage(language);
}
final calendarEventAcceptInvocation = requestBuilder.invocation(calendarEventAcceptMethod); final calendarEventAcceptInvocation = requestBuilder.invocation(calendarEventAcceptMethod);
final response = await (requestBuilder..usings(calendarEventAcceptMethod.requiredCapabilities)) final response = await (requestBuilder..usings(calendarEventAcceptMethod.requiredCapabilities))
.build() .build()
@@ -70,11 +77,18 @@ class CalendarEventAPI {
return calendarEventAcceptResponse; return calendarEventAcceptResponse;
} }
Future<CalendarEventMaybeResponse> maybe(AccountId accountId, Set<Id> blobIds) async { Future<CalendarEventMaybeResponse> maybeEventInvitation(
AccountId accountId,
Set<Id> blobIds,
String? language
) async {
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation()); final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
final calendarEventMaybeMethod = CalendarEventMaybeMethod( final calendarEventMaybeMethod = CalendarEventMaybeMethod(
accountId, accountId,
blobIds: blobIds.toList()); blobIds: blobIds.toList());
if (language != null) {
calendarEventMaybeMethod.addLanguage(language);
}
final calendarEventMaybeInvocation = requestBuilder.invocation(calendarEventMaybeMethod); final calendarEventMaybeInvocation = requestBuilder.invocation(calendarEventMaybeMethod);
final response = await (requestBuilder..usings(calendarEventMaybeMethod.requiredCapabilities)) final response = await (requestBuilder..usings(calendarEventMaybeMethod.requiredCapabilities))
.build() .build()
@@ -91,11 +105,18 @@ class CalendarEventAPI {
return calendarEventMaybeResponse; return calendarEventMaybeResponse;
} }
Future<CalendarEventRejectResponse> reject(AccountId accountId, Set<Id> blobIds) async { Future<CalendarEventRejectResponse> rejectEventInvitation(
AccountId accountId,
Set<Id> blobIds,
String? language
) async {
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation()); final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
final calendarEventRejectMethod = CalendarEventRejectMethod( final calendarEventRejectMethod = CalendarEventRejectMethod(
accountId, accountId,
blobIds: blobIds.toList()); blobIds: blobIds.toList());
if (language != null) {
calendarEventRejectMethod.addLanguage(language);
}
final calendarEventRejectInvocation = requestBuilder.invocation(calendarEventRejectMethod); final calendarEventRejectInvocation = requestBuilder.invocation(calendarEventRejectMethod);
final response = await (requestBuilder..usings(calendarEventRejectMethod.requiredCapabilities)) final response = await (requestBuilder..usings(calendarEventRejectMethod.requiredCapabilities))
.build() .build()
@@ -21,17 +21,32 @@ class CalendarEventRepositoryImpl extends CalendarEventRepository {
} }
@override @override
Future<CalendarEventAcceptResponse> acceptEventInvitation(AccountId accountId, Set<Id> blobIds) { Future<CalendarEventAcceptResponse> acceptEventInvitation(
return _calendarEventDataSource[DataSourceType.network]!.acceptEventInvitation(accountId, blobIds); AccountId accountId,
Set<Id> blobIds,
String? language
) {
return _calendarEventDataSource[DataSourceType.network]!
.acceptEventInvitation(accountId, blobIds, language);
} }
@override @override
Future<CalendarEventMaybeResponse> maybeEventInvitation(AccountId accountId, Set<Id> blobIds) { Future<CalendarEventMaybeResponse> maybeEventInvitation(
return _calendarEventDataSource[DataSourceType.network]!.maybeEventInvitation(accountId, blobIds); AccountId accountId,
Set<Id> blobIds,
String? language
) {
return _calendarEventDataSource[DataSourceType.network]!
.maybeEventInvitation(accountId, blobIds, language);
} }
@override @override
Future<CalendarEventRejectResponse> rejectEventInvitation(AccountId accountId, Set<Id> blobIds) { Future<CalendarEventRejectResponse> rejectEventInvitation(
return _calendarEventDataSource[DataSourceType.network]!.rejectEventInvitation(accountId, blobIds); AccountId accountId,
Set<Id> blobIds,
String? language
) {
return _calendarEventDataSource[DataSourceType.network]!
.rejectEventInvitation(accountId, blobIds, language);
} }
} }
@@ -9,9 +9,18 @@ import 'package:jmap_dart_client/jmap/mail/calendar/reply/calendar_event_reject_
abstract class CalendarEventRepository { abstract class CalendarEventRepository {
Future<List<BlobCalendarEvent>> parse(AccountId accountId, Set<Id> blobIds); Future<List<BlobCalendarEvent>> parse(AccountId accountId, Set<Id> blobIds);
Future<CalendarEventAcceptResponse> acceptEventInvitation(AccountId accountId, Set<Id> blobIds); Future<CalendarEventAcceptResponse> acceptEventInvitation(
AccountId accountId,
Set<Id> blobIds,
String? language);
Future<CalendarEventMaybeResponse> maybeEventInvitation(AccountId accountId, Set<Id> blobIds); Future<CalendarEventMaybeResponse> maybeEventInvitation(
AccountId accountId,
Set<Id> blobIds,
String? language);
Future<CalendarEventRejectResponse> rejectEventInvitation(AccountId accountId, Set<Id> blobIds); Future<CalendarEventRejectResponse> rejectEventInvitation(
AccountId accountId,
Set<Id> blobIds,
String? language);
} }
@@ -16,10 +16,12 @@ class AcceptCalendarEventInteractor {
AccountId accountId, AccountId accountId,
Set<Id> blobIds, Set<Id> blobIds,
EmailId emailId, EmailId emailId,
String? language
) async* { ) async* {
try { try {
yield Right(CalendarEventAccepting()); yield Right(CalendarEventAccepting());
final result = await _calendarEventRepository.acceptEventInvitation(accountId, blobIds); final result = await _calendarEventRepository
.acceptEventInvitation(accountId, blobIds, language);
yield Right(CalendarEventAccepted(result, emailId)); yield Right(CalendarEventAccepted(result, emailId));
} catch (e) { } catch (e) {
yield Left(CalendarEventAcceptFailure(exception: e)); yield Left(CalendarEventAcceptFailure(exception: e));
@@ -16,10 +16,12 @@ class RejectCalendarEventInteractor {
AccountId accountId, AccountId accountId,
Set<Id> blobIds, Set<Id> blobIds,
EmailId emailId, EmailId emailId,
String? language
) async* { ) async* {
try { try {
yield Right(CalendarEventRejecting()); yield Right(CalendarEventRejecting());
final result = await _calendarEventRepository.rejectEventInvitation(accountId, blobIds); final result = await _calendarEventRepository
.rejectEventInvitation(accountId, blobIds, language);
yield Right(CalendarEventRejected(result, emailId)); yield Right(CalendarEventRejected(result, emailId));
} catch (e) { } catch (e) {
yield Left(CalendarEventRejectFailure(exception: e)); yield Left(CalendarEventRejectFailure(exception: e));
@@ -16,10 +16,12 @@ class MaybeCalendarEventInteractor {
AccountId accountId, AccountId accountId,
Set<Id> blobIds, Set<Id> blobIds,
EmailId emailId, EmailId emailId,
String? language
) async* { ) async* {
try { try {
yield Right(CalendarEventMaybeReplying()); yield Right(CalendarEventMaybeReplying());
final result = await _calendarEventRepository.maybeEventInvitation(accountId, blobIds); final result = await _calendarEventRepository
.maybeEventInvitation(accountId, blobIds, language);
yield Right(CalendarEventMaybeSuccess(result, emailId)); yield Right(CalendarEventMaybeSuccess(result, emailId));
} catch (e) { } catch (e) {
yield Left(CalendarEventMaybeFailure(exception: e)); yield Left(CalendarEventMaybeFailure(exception: e));
@@ -100,6 +100,7 @@ import 'package:tmail_ui_user/features/thread/domain/constants/thread_constants.
import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.dart'; import 'package:tmail_ui_user/features/thread/presentation/model/delete_action_type.dart';
import 'package:tmail_ui_user/main/error/capability_validator.dart'; import 'package:tmail_ui_user/main/error/capability_validator.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/localizations/localization_service.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart'; import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/dialog_router.dart'; import 'package:tmail_ui_user/main/routes/dialog_router.dart';
import 'package:tmail_ui_user/main/routes/navigation_router.dart'; import 'package:tmail_ui_user/main/routes/navigation_router.dart';
@@ -1729,42 +1730,63 @@ class SingleEmailController extends BaseController with AppLoaderMixin {
void _acceptCalendarEventAction(EmailId emailId) { void _acceptCalendarEventAction(EmailId emailId) {
if (_acceptCalendarEventInteractor == null if (_acceptCalendarEventInteractor == null
|| _displayingEventBlobId == null || _displayingEventBlobId == null
|| mailboxDashBoardController.accountId.value == null) { || mailboxDashBoardController.accountId.value == null
consumeState(Stream.value(Left(CalendarEventAcceptFailure()))); || mailboxDashBoardController.sessionCurrent == null
|| mailboxDashBoardController.sessionCurrent
!.validateCalendarEventCapability(mailboxDashBoardController.accountId.value!)
.isAvailable == false
) {
consumeState(Stream.value(Left(CalendarEventAcceptFailure())));
} else { } else {
consumeState(_acceptCalendarEventInteractor!.execute( consumeState(_acceptCalendarEventInteractor!.execute(
mailboxDashBoardController.accountId.value!, mailboxDashBoardController.accountId.value!,
{_displayingEventBlobId!}, {_displayingEventBlobId!},
emailId emailId,
)); mailboxDashBoardController.sessionCurrent!.getLanguageForCalendarEvent(
LocalizationService.getLocaleFromLanguage(),
mailboxDashBoardController.accountId.value!)));
} }
} }
void _rejectCalendarEventAction(EmailId emailId) { void _rejectCalendarEventAction(EmailId emailId) {
if (_rejectCalendarEventInteractor == null if (_rejectCalendarEventInteractor == null
|| _displayingEventBlobId == null || _displayingEventBlobId == null
|| mailboxDashBoardController.accountId.value == null) { || mailboxDashBoardController.accountId.value == null
consumeState(Stream.value(Left(CalendarEventRejectFailure()))); || mailboxDashBoardController.sessionCurrent == null
|| mailboxDashBoardController.sessionCurrent
!.validateCalendarEventCapability(mailboxDashBoardController.accountId.value!)
.isAvailable == false
) {
consumeState(Stream.value(Left(CalendarEventRejectFailure())));
} else { } else {
consumeState(_rejectCalendarEventInteractor!.execute( consumeState(_rejectCalendarEventInteractor!.execute(
mailboxDashBoardController.accountId.value!, mailboxDashBoardController.accountId.value!,
{_displayingEventBlobId!}, {_displayingEventBlobId!},
emailId emailId,
)); mailboxDashBoardController.sessionCurrent!.getLanguageForCalendarEvent(
LocalizationService.getLocaleFromLanguage(),
mailboxDashBoardController.accountId.value!)));
} }
} }
void _maybeCalendarEventAction(EmailId emailId) { void _maybeCalendarEventAction(EmailId emailId) {
if (_maybeCalendarEventInteractor == null if (_maybeCalendarEventInteractor == null
|| _displayingEventBlobId == null || _displayingEventBlobId == null
|| mailboxDashBoardController.accountId.value == null) { || mailboxDashBoardController.accountId.value == null
consumeState(Stream.value(Left(CalendarEventMaybeFailure()))); || mailboxDashBoardController.sessionCurrent == null
|| mailboxDashBoardController.sessionCurrent
!.validateCalendarEventCapability(mailboxDashBoardController.accountId.value!)
.isAvailable == false
) {
consumeState(Stream.value(Left(CalendarEventMaybeFailure())));
} else { } else {
consumeState(_maybeCalendarEventInteractor!.execute( consumeState(_maybeCalendarEventInteractor!.execute(
mailboxDashBoardController.accountId.value!, mailboxDashBoardController.accountId.value!,
{_displayingEventBlobId!}, {_displayingEventBlobId!},
emailId emailId,
)); mailboxDashBoardController.sessionCurrent!.getLanguageForCalendarEvent(
LocalizationService.getLocaleFromLanguage(),
mailboxDashBoardController.accountId.value!)));
} }
} }
@@ -1,6 +1,9 @@
import 'dart:ui';
import 'package:core/presentation/extensions/uri_extension.dart'; import 'package:core/presentation/extensions/uri_extension.dart';
import 'package:jmap_dart_client/jmap/account_id.dart'; import 'package:jmap_dart_client/jmap/account_id.dart';
import 'package:jmap_dart_client/jmap/core/capability/calendar_event_capability.dart';
import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart'; import 'package:jmap_dart_client/jmap/core/capability/capability_identifier.dart';
import 'package:jmap_dart_client/jmap/core/capability/capability_properties.dart'; import 'package:jmap_dart_client/jmap/core/capability/capability_properties.dart';
import 'package:jmap_dart_client/jmap/core/capability/empty_capability.dart'; import 'package:jmap_dart_client/jmap/core/capability/empty_capability.dart';
@@ -63,4 +66,35 @@ extension SessionExtension on Session {
} }
throw NotFoundPersonalAccountException(); throw NotFoundPersonalAccountException();
} }
({
bool isAvailable,
CalendarEventCapability? calendarEventCapability
}) validateCalendarEventCapability(AccountId accountId) {
final capability = getCapabilityProperties<CalendarEventCapability>(
accountId,
CapabilityIdentifier.jamesCalendarEvent);
return (isAvailable: capability != null, calendarEventCapability: capability);
}
String? getLanguageForCalendarEvent(
Locale locale,
AccountId accountId,
) {
final validation = validateCalendarEventCapability(accountId);
if (!validation.isAvailable) return null;
final supportedLanguages = validation.calendarEventCapability!.replySupportedLanguage;
if (supportedLanguages == null) return null;
final currentLanguage = locale.languageCode;
if (supportedLanguages.contains(currentLanguage)) {
return currentLanguage;
} else if (supportedLanguages.contains('en')) {
return 'en';
} else {
return supportedLanguages.firstOrNull;
}
}
} }