TF-1897 Implement resend sending email when failed
(cherry picked from commit f508b65688503e9ae8ece5a1924e84481b98a39e)
This commit is contained in:
@@ -21,7 +21,6 @@ class SendingEmailCacheManager {
|
||||
SendingEmailHiveCache sendingEmailHiveCache
|
||||
) async {
|
||||
final keyCache = TupleKey(sendingEmailHiveCache.sendingId, accountId.asString, userName.value).encodeKey;
|
||||
log('SendingEmailCacheManager::storeSendingEmail():keyCache: $keyCache | sendingEmailHiveCache: $sendingEmailHiveCache');
|
||||
await _hiveCacheClient.insertItem(keyCache, sendingEmailHiveCache);
|
||||
final newSendingEmailHiveCache = await _hiveCacheClient.getItem(keyCache);
|
||||
if (newSendingEmailHiveCache != null) {
|
||||
@@ -32,29 +31,15 @@ class SendingEmailCacheManager {
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<SendingEmailHiveCache>> getAllSendingEmailsByTupleKey(
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
{bool needToReopen = false}
|
||||
) async {
|
||||
final sendingEmailsCache = await _hiveCacheClient.getListByTupleKey(
|
||||
accountId.asString,
|
||||
userName.value,
|
||||
needToReopen: needToReopen);
|
||||
log('SendingEmailCacheManager::getAllSendingEmailsByTupleKey():COUNT: ${sendingEmailsCache.length}');
|
||||
Future<List<SendingEmailHiveCache>> getAllSendingEmailsByTupleKey(AccountId accountId, UserName userName) async {
|
||||
final sendingEmailsCache = await _hiveCacheClient.getListByTupleKey(accountId.asString, userName.value);
|
||||
sendingEmailsCache.sortByLatestTime();
|
||||
return sendingEmailsCache;
|
||||
}
|
||||
|
||||
Future<void> deleteSendingEmail(
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
String sendingId,
|
||||
{bool needToReopen = false}
|
||||
) async {
|
||||
Future<void> deleteSendingEmail(AccountId accountId, UserName userName, String sendingId) async {
|
||||
final keyCache = TupleKey(sendingId, accountId.asString, userName.value).encodeKey;
|
||||
log('SendingEmailCacheManager::deleteSendingEmail():keyCache: $keyCache');
|
||||
await _hiveCacheClient.deleteItem(keyCache, needToReopen: needToReopen);
|
||||
await _hiveCacheClient.deleteItem(keyCache);
|
||||
final storedSendingEmail = await _hiveCacheClient.getItem(keyCache);
|
||||
if (storedSendingEmail != null) {
|
||||
log('SendingEmailCacheManager::deleteSendingEmail():sendingId: ${storedSendingEmail.sendingId}');
|
||||
@@ -62,9 +47,8 @@ class SendingEmailCacheManager {
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<SendingEmailHiveCache>> getAllSendingEmails({bool needToReopen = false}) async {
|
||||
final sendingEmailsCache = await _hiveCacheClient.getAll(needToReopen: needToReopen);
|
||||
log('SendingEmailCacheManager::getAllSendingEmails():COUNT: ${sendingEmailsCache.length}');
|
||||
Future<List<SendingEmailHiveCache>> getAllSendingEmails() async {
|
||||
final sendingEmailsCache = await _hiveCacheClient.getAll();
|
||||
sendingEmailsCache.sortByLatestTime();
|
||||
return sendingEmailsCache;
|
||||
}
|
||||
@@ -74,12 +58,10 @@ class SendingEmailCacheManager {
|
||||
Future<SendingEmailHiveCache> updateSendingEmail(
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
SendingEmailHiveCache sendingEmailHiveCache,
|
||||
{bool needToReopen = false}
|
||||
SendingEmailHiveCache sendingEmailHiveCache
|
||||
) async {
|
||||
final keyCache = TupleKey(sendingEmailHiveCache.sendingId, accountId.asString, userName.value).encodeKey;
|
||||
log('SendingEmailCacheManager::updateSendingEmail():keyCache: $keyCache | sendingEmailHiveCache: $sendingEmailHiveCache');
|
||||
await _hiveCacheClient.updateItem(keyCache, sendingEmailHiveCache, needToReopen: needToReopen);
|
||||
await _hiveCacheClient.updateItem(keyCache, sendingEmailHiveCache);
|
||||
final newSendingEmailHiveCache = await _hiveCacheClient.getItem(keyCache);
|
||||
if (newSendingEmailHiveCache != null) {
|
||||
log('SendingEmailCacheManager::updateSendingEmail():sendingId: ${newSendingEmailHiveCache.sendingId} | sendingState: ${newSendingEmailHiveCache.sendingState}');
|
||||
@@ -88,4 +70,31 @@ class SendingEmailCacheManager {
|
||||
throw NotFoundSendingEmailHiveObject();
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<SendingEmailHiveCache>> updateMultipleSendingEmail(
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
List<SendingEmailHiveCache> listSendingEmailHiveCache
|
||||
) async {
|
||||
final mapSendingEmailCache = {
|
||||
for (var sendingEmailCache in listSendingEmailHiveCache)
|
||||
TupleKey(sendingEmailCache.sendingId, accountId.asString, userName.value).encodeKey: sendingEmailCache
|
||||
};
|
||||
await _hiveCacheClient.updateMultipleItem(mapSendingEmailCache);
|
||||
final newListSendingEmailCache = await _hiveCacheClient.getValuesByListKey(mapSendingEmailCache.keys.toList());
|
||||
log('SendingEmailCacheManager::updateMultipleSendingEmail():newListSendingEmailCache: ${newListSendingEmailCache.map((sendingEmail) => '${sendingEmail.sendingId} | ${sendingEmail.sendingState}').toList()}');
|
||||
return newListSendingEmailCache;
|
||||
}
|
||||
|
||||
Future<void> deleteMultipleSendingEmail(AccountId accountId, UserName userName, List<String> sendingIds) async {
|
||||
final listTupleKey = sendingIds.map((sendingId) => TupleKey(sendingId, accountId.asString, userName.value).encodeKey).toList();
|
||||
await _hiveCacheClient.deleteMultipleItem(listTupleKey);
|
||||
final newListSendingEmailCache = await _hiveCacheClient.getValuesByListKey(listTupleKey);
|
||||
log('SendingEmailCacheManager::deleteMultipleSendingEmail():newListSendingEmailCache: ${newListSendingEmailCache.map((sendingEmail) => '${sendingEmail.sendingId} | ${sendingEmail.sendingState}').toList()}');
|
||||
if (newListSendingEmailCache.isNotEmpty) {
|
||||
throw ExistSendingEmailHiveObject();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> closeSendingEmailHiveCacheBox() => _hiveCacheClient.closeBox();
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import 'package:tmail_ui_user/features/mailbox/domain/model/create_new_mailbox_r
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/mailbox_dashboard_bindings.dart';
|
||||
import 'package:tmail_ui_user/features/offline_mode/bindings/sending_email_interactor_bindings.dart';
|
||||
import 'package:tmail_ui_user/features/offline_mode/exceptions/workmanager_exception.dart';
|
||||
import 'package:tmail_ui_user/features/offline_mode/manager/sending_email_cache_manager.dart';
|
||||
import 'package:tmail_ui_user/features/offline_mode/model/sending_state.dart';
|
||||
import 'package:tmail_ui_user/features/offline_mode/observer/work_observer.dart';
|
||||
import 'package:tmail_ui_user/features/push_notification/presentation/notification/local_notification_config.dart';
|
||||
@@ -53,6 +54,7 @@ class SendingEmailObserver extends WorkObserver {
|
||||
DeleteSendingEmailInteractor? _deleteSendingEmailInteractor;
|
||||
SendingQueueIsolateManager? _sendingQueueIsolateManager;
|
||||
UpdateSendingEmailInteractor? _updateSendingEmailInteractor;
|
||||
SendingEmailCacheManager? _sendingEmailCacheManager;
|
||||
|
||||
Completer<bool>? _completer;
|
||||
|
||||
@@ -64,7 +66,6 @@ class SendingEmailObserver extends WorkObserver {
|
||||
|
||||
@override
|
||||
Future<void> observe(String taskId, Map<String, dynamic> inputData, Completer<bool> completer) async {
|
||||
log('SendingEmailObserver::observe():taskId: $taskId | inputData: $inputData');
|
||||
_completer = completer;
|
||||
_sendingEmail = SendingEmail.fromJson(inputData);
|
||||
log('SendingEmailObserver::observe():_sendingEmail: $_sendingEmail');
|
||||
@@ -85,14 +86,20 @@ class SendingEmailObserver extends WorkObserver {
|
||||
SendEmailInteractorBindings().dependencies();
|
||||
});
|
||||
|
||||
return await _getInteractorBindings();
|
||||
await _getInteractorBindings();
|
||||
|
||||
await _sendingEmailCacheManager?.closeSendingEmailHiveCacheBox();
|
||||
|
||||
return Future.value();
|
||||
}
|
||||
|
||||
@override
|
||||
void handleFailureViewState(Failure failure) {
|
||||
log('SendingEmailObserver::_handleFailureViewState(): $failure');
|
||||
if (failure is SendEmailFailure || failure is DeleteSendingEmailFailure) {
|
||||
_updateStoredSendingEmail(SendingState.error);
|
||||
if (failure is SendEmailFailure) {
|
||||
_handleSendEmailFailure(failure);
|
||||
} else if (failure is DeleteSendingEmailFailure) {
|
||||
_handleDeleteSendingEmailFailure(failure);
|
||||
} else if (failure is GetAuthenticatedAccountFailure ||
|
||||
failure is NoAuthenticatedAccountFailure ||
|
||||
failure is GetSessionFailure ||
|
||||
@@ -115,7 +122,7 @@ class SendingEmailObserver extends WorkObserver {
|
||||
} else if (success is SendEmailSuccess) {
|
||||
_handleSendEmailSuccess(success);
|
||||
} else if (success is DeleteSendingEmailSuccess) {
|
||||
_handleDeleteSendingEmailSuccess();
|
||||
_handleDeleteSendingEmailSuccess(success);
|
||||
} else if (success is UpdateSendingEmailSuccess) {
|
||||
_handleUpdateStoredSendingEmailSuccess(success);
|
||||
}
|
||||
@@ -137,6 +144,7 @@ class SendingEmailObserver extends WorkObserver {
|
||||
_deleteSendingEmailInteractor = getBinding<DeleteSendingEmailInteractor>();
|
||||
_sendingQueueIsolateManager = getBinding<SendingQueueIsolateManager>();
|
||||
_updateSendingEmailInteractor = getBinding<UpdateSendingEmailInteractor>();
|
||||
_sendingEmailCacheManager = getBinding<SendingEmailCacheManager>();
|
||||
} catch (e) {
|
||||
logError('SendingEmailObserver::_getInteractorBindings(): ${e.toString()}');
|
||||
_handleTaskFailureInWorkManager();
|
||||
@@ -153,19 +161,11 @@ class SendingEmailObserver extends WorkObserver {
|
||||
}
|
||||
|
||||
void _getAuthenticatedAccount() {
|
||||
if (_getAuthenticatedAccountInteractor != null) {
|
||||
consumeState(_getAuthenticatedAccountInteractor!.execute());
|
||||
} else {
|
||||
_handleTaskFailureInWorkManager();
|
||||
}
|
||||
consumeState(_getAuthenticatedAccountInteractor!.execute());
|
||||
}
|
||||
|
||||
void _getSessionAction() {
|
||||
if (_getSessionInteractor != null) {
|
||||
consumeState(_getSessionInteractor!.execute());
|
||||
} else {
|
||||
_handleTaskFailureInWorkManager();
|
||||
}
|
||||
consumeState(_getSessionInteractor!.execute());
|
||||
}
|
||||
|
||||
void _handleGetSessionSuccess(GetSessionSuccess success) async {
|
||||
@@ -174,13 +174,7 @@ class SendingEmailObserver extends WorkObserver {
|
||||
final apiUrl = success.session.getQualifiedApiUrl(baseUrl: _dynamicUrlInterceptors?.jmapUrl);
|
||||
if (apiUrl.isNotEmpty) {
|
||||
_dynamicUrlInterceptors?.changeBaseUrl(apiUrl);
|
||||
|
||||
_updateStoredSendingEmail(SendingState.running);
|
||||
|
||||
await Future.delayed(
|
||||
const Duration(milliseconds: 2000),
|
||||
_sendEmailAction
|
||||
);
|
||||
_sendEmailAction();
|
||||
} else {
|
||||
_handleTaskFailureInWorkManager();
|
||||
}
|
||||
@@ -197,26 +191,32 @@ class SendingEmailObserver extends WorkObserver {
|
||||
}
|
||||
|
||||
void _sendEmailAction() {
|
||||
if (_sendEmailInteractor != null && _isDataParameterNotNull) {
|
||||
final mailboxRequest = _sendingEmail!.mailboxNameRequest != null && _sendingEmail!.creationIdRequest != null
|
||||
? CreateNewMailboxRequest(_sendingEmail!.creationIdRequest!, _sendingEmail!.mailboxNameRequest!)
|
||||
: null;
|
||||
consumeState(_sendEmailInteractor!.execute(
|
||||
consumeState(
|
||||
_sendEmailInteractor!.execute(
|
||||
_currentSession!,
|
||||
_currentAccountId!,
|
||||
_sendingEmail!.toEmailRequest(),
|
||||
mailboxRequest: mailboxRequest
|
||||
));
|
||||
mailboxRequest: _getMailboxRequest()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
CreateNewMailboxRequest? _getMailboxRequest() {
|
||||
if (_sendingEmail!.mailboxNameRequest != null &&
|
||||
_sendingEmail!.creationIdRequest != null) {
|
||||
return CreateNewMailboxRequest(
|
||||
_sendingEmail!.creationIdRequest!,
|
||||
_sendingEmail!.mailboxNameRequest!);
|
||||
} else {
|
||||
_updateStoredSendingEmail(SendingState.error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
void _handleGetAccountByOidcSuccess(GetStoredTokenOidcSuccess storedTokenOidcSuccess) {
|
||||
_dynamicUrlInterceptors?.setJmapUrl(storedTokenOidcSuccess.baseUrl.toString());
|
||||
_authorizationInterceptors?.setTokenAndAuthorityOidc(
|
||||
newToken: storedTokenOidcSuccess.tokenOidc.toToken(),
|
||||
newConfig: storedTokenOidcSuccess.oidcConfiguration
|
||||
newToken: storedTokenOidcSuccess.tokenOidc.toToken(),
|
||||
newConfig: storedTokenOidcSuccess.oidcConfiguration
|
||||
);
|
||||
_dynamicUrlInterceptors?.changeBaseUrl(storedTokenOidcSuccess.baseUrl.toString());
|
||||
_getSessionAction();
|
||||
@@ -224,28 +224,31 @@ class SendingEmailObserver extends WorkObserver {
|
||||
|
||||
void _handleSendEmailSuccess(SendEmailSuccess success) {
|
||||
_showLocalNotification();
|
||||
_deleteSendingEmailAction();
|
||||
_updateStoredSendingEmail(SendingState.success);
|
||||
}
|
||||
|
||||
void _handleSendEmailFailure(SendEmailFailure failure) {
|
||||
_updateStoredSendingEmail(SendingState.error);
|
||||
}
|
||||
|
||||
void _deleteSendingEmailAction() {
|
||||
log('SendingEmailObserver::_deleteSendingEmailAction():');
|
||||
if (_deleteSendingEmailInteractor != null && _isDataParameterNotNull) {
|
||||
consumeState(_deleteSendingEmailInteractor!.execute(
|
||||
consumeState(
|
||||
_deleteSendingEmailInteractor!.execute(
|
||||
_currentAccountId!,
|
||||
_currentSession!.username,
|
||||
_sendingEmail!.sendingId,
|
||||
needToReopen: true
|
||||
));
|
||||
} else {
|
||||
log('SendingEmailObserver::_deleteSendingEmailAction(): NOT CALLED');
|
||||
_updateStoredSendingEmail(SendingState.error);
|
||||
}
|
||||
_sendingEmail!.sendingId
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void _handleDeleteSendingEmailSuccess() {
|
||||
void _handleDeleteSendingEmailSuccess(DeleteSendingEmailSuccess success) {
|
||||
_handleTaskSuccessInWorkManager();
|
||||
}
|
||||
|
||||
void _handleDeleteSendingEmailFailure(DeleteSendingEmailFailure failure) {
|
||||
_handleTaskFailureInWorkManager();
|
||||
}
|
||||
|
||||
void _showLocalNotification() {
|
||||
LocalNotificationManager.instance.showPushNotification(
|
||||
id: _sendingEmail?.sendingId ?? '',
|
||||
@@ -255,26 +258,26 @@ class SendingEmailObserver extends WorkObserver {
|
||||
);
|
||||
}
|
||||
|
||||
bool get _isDataParameterNotNull => _currentSession != null && _currentAccountId != null && _sendingEmail != null;
|
||||
|
||||
void _updateStoredSendingEmail(SendingState newState) {
|
||||
log('SendingEmailObserver::_updateStoredSendingEmail():newState: $newState');
|
||||
if (_updateSendingEmailInteractor != null && _isDataParameterNotNull) {
|
||||
consumeState(_updateSendingEmailInteractor!.execute(
|
||||
consumeState(
|
||||
_updateSendingEmailInteractor!.execute(
|
||||
_currentAccountId!,
|
||||
_currentSession!.username,
|
||||
_sendingEmail!.updatingSendingState(newState),
|
||||
needToReopen: true
|
||||
));
|
||||
} else {
|
||||
_handleTaskFailureInWorkManager();
|
||||
}
|
||||
_sendingEmail!.updatingSendingState(newState)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void _handleUpdateStoredSendingEmailSuccess(UpdateSendingEmailSuccess success) {
|
||||
_updatingSendingStateToMainUI(
|
||||
sendingState: success.newSendingEmail.sendingState,
|
||||
sendingId: success.newSendingEmail.sendingId);
|
||||
log('SendingEmailObserver::_handleUpdateStoredSendingEmailSuccess(): $success');
|
||||
if (success.newSendingEmail.isSuccess) {
|
||||
_deleteSendingEmailAction();
|
||||
} else {
|
||||
_updatingSendingStateToMainUI(
|
||||
sendingState: success.newSendingEmail.sendingState,
|
||||
sendingId: success.newSendingEmail.sendingId);
|
||||
}
|
||||
}
|
||||
|
||||
void _handleTaskFailureInWorkManager() async {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import 'package:tmail_ui_user/features/offline_mode/model/sending_email_hive_cache.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/extensions/sending_email_extension.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
|
||||
|
||||
extension ListSendingEmailExtension on List<SendingEmail> {
|
||||
List<SendingEmailHiveCache> toHiveCache() => map((sendingEmail) => sendingEmail.toHiveCache()).toList();
|
||||
|
||||
List<String> get sendingIds => map((sendingEmail) => sendingEmail.sendingId).toSet().toList();
|
||||
}
|
||||
@@ -101,6 +101,10 @@ class SendingEmail with EquatableMixin {
|
||||
|
||||
bool get isWaiting => sendingState == SendingState.waiting;
|
||||
|
||||
bool get isError => sendingState == SendingState.error;
|
||||
|
||||
bool get isSuccess => sendingState == SendingState.success;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
sendingId,
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
|
||||
|
||||
class UpdateMultipleSendingEmailLoading extends UIState {}
|
||||
|
||||
class UpdateMultipleSendingEmailAllSuccess extends UIState {
|
||||
final List<SendingEmail> newSendingEmails;
|
||||
|
||||
UpdateMultipleSendingEmailAllSuccess(this.newSendingEmails);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [newSendingEmails];
|
||||
}
|
||||
|
||||
class UpdateMultipleSendingEmailHasSomeSuccess extends UIState {
|
||||
final List<SendingEmail> newSendingEmails;
|
||||
|
||||
UpdateMultipleSendingEmailHasSomeSuccess(this.newSendingEmails);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [newSendingEmails];
|
||||
}
|
||||
|
||||
class UpdateMultipleSendingEmailAllFailure extends FeatureFailure {
|
||||
|
||||
UpdateMultipleSendingEmailAllFailure(dynamic exception) : super(exception: exception);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [exception];
|
||||
}
|
||||
|
||||
class UpdateMultipleSendingEmailFailure extends FeatureFailure {
|
||||
|
||||
UpdateMultipleSendingEmailFailure(dynamic exception) : super(exception: exception);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [exception];
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/user_name.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/data/exceptions/sending_queue_exceptions.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/repository/sending_queue_repository.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/state/update_multiple_sending_email_state.dart';
|
||||
|
||||
class UpdateMultipleSendingEmailInteractor {
|
||||
final SendingQueueRepository _sendingQueueRepository;
|
||||
|
||||
UpdateMultipleSendingEmailInteractor(this._sendingQueueRepository);
|
||||
|
||||
Stream<Either<Failure, Success>> execute(
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
List<SendingEmail> newSendingEmails
|
||||
) async* {
|
||||
try {
|
||||
yield Right<Failure, Success>(UpdateMultipleSendingEmailLoading());
|
||||
final storedSendingEmails = await _sendingQueueRepository.updateMultipleSendingEmail(
|
||||
accountId,
|
||||
userName,
|
||||
newSendingEmails);
|
||||
if (storedSendingEmails.length == newSendingEmails.length) {
|
||||
yield Right<Failure, Success>(UpdateMultipleSendingEmailAllSuccess(storedSendingEmails));
|
||||
} else if (storedSendingEmails.isEmpty) {
|
||||
yield Left<Failure, Success>(UpdateMultipleSendingEmailAllFailure(NotFoundSendingEmailHiveObject()));
|
||||
} else {
|
||||
yield Right<Failure, Success>(UpdateMultipleSendingEmailHasSomeSuccess(storedSendingEmails));
|
||||
}
|
||||
} catch (e) {
|
||||
yield Left<Failure, Success>(UpdateMultipleSendingEmailFailure(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,11 @@ class UpdateSendingEmailInteractor {
|
||||
Stream<Either<Failure, Success>> execute(
|
||||
AccountId accountId,
|
||||
UserName userName,
|
||||
SendingEmail newSendingEmail,
|
||||
{bool needToReopen = false}
|
||||
SendingEmail newSendingEmail
|
||||
) async* {
|
||||
try {
|
||||
yield Right<Failure, Success>(UpdateSendingEmailLoading());
|
||||
final storedSendingEmail = await _sendingQueueRepository.updateSendingEmail(accountId, userName, newSendingEmail, needToReopen: needToReopen);
|
||||
final storedSendingEmail = await _sendingQueueRepository.updateSendingEmail(accountId, userName, newSendingEmail);
|
||||
yield Right<Failure, Success>(UpdateSendingEmailSuccess(storedSendingEmail));
|
||||
} catch (e) {
|
||||
yield Left<Failure, Success>(UpdateSendingEmailFailure(e));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/delete_multiple_sending_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/update_multiple_sending_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/update_sending_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/presentation/sending_queue_controller.dart';
|
||||
|
||||
@@ -15,6 +16,7 @@ class SendingQueueBindings extends Bindings {
|
||||
Get.put(SendingQueueController(
|
||||
Get.find<DeleteMultipleSendingEmailInteractor>(),
|
||||
Get.find<UpdateSendingEmailInteractor>(),
|
||||
Get.find<UpdateMultipleSendingEmailInteractor>(),
|
||||
));
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -7,7 +7,6 @@ import 'package:tmail_ui_user/features/sending_queue/data/repository/sending_que
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/repository/sending_queue_repository.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/delete_multiple_sending_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/delete_sending_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/delete_single_sending_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/get_all_sending_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_manager.dart';
|
||||
import 'package:tmail_ui_user/features/offline_mode/manager/detailed_email_cache_worker_queue.dart';
|
||||
@@ -15,6 +14,7 @@ import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_m
|
||||
import 'package:tmail_ui_user/features/offline_mode/manager/opened_email_cache_worker_queue.dart';
|
||||
import 'package:tmail_ui_user/features/offline_mode/manager/sending_email_cache_manager.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/store_sending_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/update_multiple_sending_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/update_sending_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/thread/data/local/email_cache_manager.dart';
|
||||
import 'package:tmail_ui_user/main/exceptions/cache_exception_thrower.dart';
|
||||
@@ -41,10 +41,10 @@ class SendingQueueInteractorBindings extends InteractorsBindings {
|
||||
void bindingsInteractor() {
|
||||
Get.lazyPut(() => StoreSendingEmailInteractor(Get.find<SendingQueueRepository>()));
|
||||
Get.lazyPut(() => GetAllSendingEmailInteractor(Get.find<SendingQueueRepository>()));
|
||||
Get.lazyPut(() => DeleteSingleSendingEmailInteractor(Get.find<SendingQueueRepository>()));
|
||||
Get.lazyPut(() => DeleteMultipleSendingEmailInteractor(Get.find<DeleteSingleSendingEmailInteractor>()));
|
||||
Get.lazyPut(() => DeleteMultipleSendingEmailInteractor(Get.find<SendingQueueRepository>()));
|
||||
Get.lazyPut(() => DeleteSendingEmailInteractor(Get.find<SendingQueueRepository>()));
|
||||
Get.lazyPut(() => UpdateSendingEmailInteractor(Get.find<SendingQueueRepository>()));
|
||||
Get.lazyPut(() => UpdateMultipleSendingEmailInteractor(Get.find<SendingQueueRepository>()));
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
|
||||
import 'package:tmail_ui_user/features/offline_mode/model/sending_state.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/extensions/sending_email_extension.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
|
||||
|
||||
@@ -16,4 +17,8 @@ extension ListSendingEmailExtension on List<SendingEmail> {
|
||||
bool isAllUnSelected() => every((sendingEmail) => !sendingEmail.isSelected);
|
||||
|
||||
List<SendingEmail> listSelected() => where((sendingEmail) => sendingEmail.isSelected).toList();
|
||||
|
||||
bool isAllSendingStateError() => every((sendingEmail) => sendingEmail.isError);
|
||||
|
||||
List<SendingEmail> toSendingStateWaiting() => map((sendingEmail) => sendingEmail.updatingSendingState(SendingState.waiting)).toList();
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
enum SendingEmailActionType {
|
||||
create,
|
||||
edit,
|
||||
resend,
|
||||
delete;
|
||||
|
||||
String getButtonTitle(BuildContext context) {
|
||||
@@ -17,6 +18,8 @@ enum SendingEmailActionType {
|
||||
return AppLocalizations.of(context).edit;
|
||||
case SendingEmailActionType.create:
|
||||
return '';
|
||||
case SendingEmailActionType.resend:
|
||||
return AppLocalizations.of(context).resend;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +31,8 @@ enum SendingEmailActionType {
|
||||
return 'button_edit_sending_email';
|
||||
case SendingEmailActionType.create:
|
||||
return '';
|
||||
case SendingEmailActionType.resend:
|
||||
return 'button_resend_sending_email';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +41,7 @@ enum SendingEmailActionType {
|
||||
case SendingEmailActionType.delete:
|
||||
return AppColor.colorDeletePermanentlyButton.withOpacity(buttonState.opacity);
|
||||
case SendingEmailActionType.edit:
|
||||
case SendingEmailActionType.resend:
|
||||
return AppColor.primaryColor.withOpacity(buttonState.opacity);
|
||||
case SendingEmailActionType.create:
|
||||
return Colors.transparent.withOpacity(buttonState.opacity);
|
||||
@@ -47,6 +53,7 @@ enum SendingEmailActionType {
|
||||
case SendingEmailActionType.delete:
|
||||
return AppColor.colorDeletePermanentlyButton.withOpacity(buttonState.opacity);
|
||||
case SendingEmailActionType.edit:
|
||||
case SendingEmailActionType.resend:
|
||||
return AppColor.primaryColor.withOpacity(buttonState.opacity);
|
||||
case SendingEmailActionType.create:
|
||||
return Colors.transparent.withOpacity(buttonState.opacity);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/resources/image_paths.dart';
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:core/presentation/utils/app_toast.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -17,9 +17,14 @@ import 'package:tmail_ui_user/features/caching/utils/cache_utils.dart';
|
||||
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/controller/mailbox_dashboard_controller.dart';
|
||||
import 'package:tmail_ui_user/features/network_status_handle/presentation/network_connnection_controller.dart';
|
||||
import 'package:tmail_ui_user/features/offline_mode/manager/sending_email_cache_manager.dart';
|
||||
import 'package:tmail_ui_user/features/offline_mode/model/sending_state.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/extensions/list_sending_email_extension.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/extensions/sending_email_extension.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/state/update_multiple_sending_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/state/update_sending_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/update_multiple_sending_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/usecases/update_sending_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/presentation/utils/sending_queue_isolate_manager.dart';
|
||||
import 'package:tmail_ui_user/features/offline_mode/controller/work_scheduler_controller.dart';
|
||||
@@ -34,10 +39,12 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
|
||||
|
||||
final DeleteMultipleSendingEmailInteractor _deleteMultipleSendingEmailInteractor;
|
||||
final UpdateSendingEmailInteractor _updateSendingEmailInteractor;
|
||||
final UpdateMultipleSendingEmailInteractor _updateMultipleSendingEmailInteractor;
|
||||
|
||||
final dashboardController = getBinding<MailboxDashBoardController>();
|
||||
final _networkConnectionController = getBinding<NetworkConnectionController>();
|
||||
final _sendingQueueIsolateManager = getBinding<SendingQueueIsolateManager>();
|
||||
final _sendingEmailCacheManager = getBinding<SendingEmailCacheManager>();
|
||||
final _imagePaths = getBinding<ImagePaths>();
|
||||
final _appToast = getBinding<AppToast>();
|
||||
|
||||
@@ -48,6 +55,7 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
|
||||
SendingQueueController(
|
||||
this._deleteMultipleSendingEmailInteractor,
|
||||
this._updateSendingEmailInteractor,
|
||||
this._updateMultipleSendingEmailInteractor,
|
||||
);
|
||||
|
||||
@override
|
||||
@@ -61,7 +69,7 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
|
||||
);
|
||||
}
|
||||
|
||||
void _handleSendingQueueEvent(Object? event) {
|
||||
void _handleSendingQueueEvent(Object? event) async {
|
||||
log('SendingQueueController::_handleSendingQueueEvent():event: $event');
|
||||
try {
|
||||
if (event is String) {
|
||||
@@ -69,16 +77,20 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
|
||||
final sendingId = tupleKey.parts[0];
|
||||
final sendingState = SendingState.values.firstWhereOrNull((state) => state.name == tupleKey.parts[1]);
|
||||
log('SendingQueueController::_handleSendingQueueEvent():sendingId: $sendingId | sendingState: $sendingState');
|
||||
|
||||
if (sendingState != null) {
|
||||
await _sendingEmailCacheManager?.closeSendingEmailHiveCacheBox();
|
||||
|
||||
switch(sendingState) {
|
||||
case SendingState.waiting:
|
||||
_handleSendingStateRunningEvent(sendingId);
|
||||
_updatingSendingStateToRunningAction(sendingId);
|
||||
break;
|
||||
case SendingState.running:
|
||||
case SendingState.success:
|
||||
refreshSendingQueue();
|
||||
break;
|
||||
case SendingState.error:
|
||||
refreshSendingQueue(needToReopen: true);
|
||||
await WorkSchedulerController().cancelByUniqueId(sendingId);
|
||||
_updatingSendingStateToErrorAction(sendingId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -88,11 +100,21 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
|
||||
}
|
||||
}
|
||||
|
||||
void _handleSendingStateRunningEvent(String sendingId) {
|
||||
log('SendingQueueController::_handleSendingStateRunningEvent():sendingId: $sendingId');
|
||||
void _updatingSendingStateToRunningAction(String sendingId) {
|
||||
log('SendingQueueController::_updatingSendingStateToRunningAction():sendingId: $sendingId');
|
||||
final matchedSendingEmail = dashboardController!.listSendingEmails.firstWhereOrNull((sendingEmail) => sendingEmail.sendingId == sendingId);
|
||||
if (matchedSendingEmail != null) {
|
||||
_updateSendingEmailAction(matchedSendingEmail);
|
||||
final newSendingEmail = matchedSendingEmail.updatingSendingState(SendingState.running);
|
||||
_updateSendingEmailAction(newSendingEmail);
|
||||
}
|
||||
}
|
||||
|
||||
void _updatingSendingStateToErrorAction(String sendingId) {
|
||||
log('SendingQueueController::_updatingSendingStateToErrorAction():sendingId: $sendingId');
|
||||
final matchedSendingEmail = dashboardController!.listSendingEmails.firstWhereOrNull((sendingEmail) => sendingEmail.sendingId == sendingId);
|
||||
if (matchedSendingEmail != null) {
|
||||
final newSendingEmail = matchedSendingEmail.updatingSendingState(SendingState.error);
|
||||
_updateSendingEmailAction(newSendingEmail);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,8 +140,8 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
|
||||
|
||||
bool get isConnectedNetwork => _networkConnectionController?.isNetworkConnectionAvailable() == true;
|
||||
|
||||
void refreshSendingQueue({bool needToReopen = false}) {
|
||||
dashboardController!.getAllSendingEmails(needToReopen: needToReopen);
|
||||
void refreshSendingQueue() {
|
||||
dashboardController!.getAllSendingEmails();
|
||||
}
|
||||
|
||||
void openMailboxMenu() {
|
||||
@@ -148,6 +170,9 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
|
||||
break;
|
||||
case SendingEmailActionType.create:
|
||||
break;
|
||||
case SendingEmailActionType.resend:
|
||||
_resendSendingEmailAction(listSendingEmails);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,32 +210,31 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
|
||||
}
|
||||
|
||||
void _handleDeleteSendingEmail(List<SendingEmail> listSendingEmails) async {
|
||||
disableSelectionMode();
|
||||
|
||||
final accountId = dashboardController!.accountId.value;
|
||||
final session = dashboardController!.sessionCurrent;
|
||||
|
||||
if (accountId != null && session != null) {
|
||||
final sendingIds = listSendingEmails.map((sendingEmail) => sendingEmail.sendingId).toSet().toList();
|
||||
|
||||
await Future.wait(
|
||||
sendingIds.map((sendingId) => WorkSchedulerController().cancelByUniqueId(sendingId)),
|
||||
eagerError: true
|
||||
consumeState(
|
||||
_deleteMultipleSendingEmailInteractor.execute(
|
||||
accountId,
|
||||
session.username,
|
||||
listSendingEmails.sendingIds
|
||||
)
|
||||
);
|
||||
|
||||
consumeState(_deleteMultipleSendingEmailInteractor.execute(accountId, session.username, sendingIds));
|
||||
}
|
||||
}
|
||||
|
||||
void _handleDeleteSendingEmailSuccess() {
|
||||
if (currentContext != null && currentOverlayContext != null) {
|
||||
selectionState.value = SelectMode.INACTIVE;
|
||||
void _handleDeleteSendingEmailSuccess(DeleteMultipleSendingEmailSuccess success) async {
|
||||
await Future.wait(success.sendingIds.map(WorkSchedulerController().cancelByUniqueId));
|
||||
|
||||
if (currentContext != null && currentOverlayContext != null) {
|
||||
_appToast!.showToastSuccessMessage(
|
||||
currentOverlayContext!,
|
||||
AppLocalizations.of(currentContext!).messageHaveBeenDeletedSuccessfully
|
||||
);
|
||||
|
||||
refreshSendingQueue();
|
||||
AppLocalizations.of(currentContext!).messageHaveBeenDeletedSuccessfully);
|
||||
}
|
||||
|
||||
refreshSendingQueue();
|
||||
}
|
||||
|
||||
void _editSendingEmailAction(SendingEmail sendingEmail) {
|
||||
@@ -227,10 +251,6 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
|
||||
dashboardController?.goToComposer(arguments);
|
||||
}
|
||||
|
||||
void _handleDeleteSendingEmailFailure() {
|
||||
selectionState.value = SelectMode.INACTIVE;
|
||||
}
|
||||
|
||||
void _updateSendingEmailAction(SendingEmail newSendingEmail) {
|
||||
final accountId = dashboardController!.accountId.value;
|
||||
final session = dashboardController!.sessionCurrent;
|
||||
@@ -238,29 +258,62 @@ class SendingQueueController extends BaseController with MessageDialogActionMixi
|
||||
consumeState(_updateSendingEmailInteractor.execute(
|
||||
accountId,
|
||||
session.username,
|
||||
newSendingEmail,
|
||||
needToReopen: true
|
||||
newSendingEmail
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
void _resendSendingEmailAction(List<SendingEmail> listSendingEmails) async {
|
||||
disableSelectionMode();
|
||||
|
||||
final accountId = dashboardController!.accountId.value;
|
||||
final session = dashboardController!.sessionCurrent;
|
||||
|
||||
if (accountId != null && session != null) {
|
||||
consumeState(
|
||||
_updateMultipleSendingEmailInteractor.execute(
|
||||
accountId,
|
||||
session.username,
|
||||
listSendingEmails.toSendingStateWaiting()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _handleResendSendingEmailSuccess(List<SendingEmail> newListSendingEmails) async {
|
||||
await Future.forEach<SendingEmail>(newListSendingEmails, (sendingEmail) async {
|
||||
await WorkSchedulerController().cancelByUniqueId(sendingEmail.sendingId);
|
||||
dashboardController!.addSendingEmailToSendingQueue(sendingEmail);
|
||||
});
|
||||
|
||||
if (currentContext != null && currentOverlayContext != null) {
|
||||
_appToast!.showToastSuccessMessage(
|
||||
currentOverlayContext!,
|
||||
AppLocalizations.of(currentContext!).messagesHaveBeenResent);
|
||||
}
|
||||
refreshSendingQueue();
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
void handleSuccessViewState(Success success) {
|
||||
super.handleSuccessViewState(success);
|
||||
if (success is DeleteMultipleSendingEmailAllSuccess ||
|
||||
success is DeleteMultipleSendingEmailHasSomeSuccess) {
|
||||
_handleDeleteSendingEmailSuccess();
|
||||
if (success is DeleteMultipleSendingEmailSuccess) {
|
||||
_handleDeleteSendingEmailSuccess(success);
|
||||
} else if (success is UpdateSendingEmailSuccess) {
|
||||
refreshSendingQueue(needToReopen: true);
|
||||
refreshSendingQueue();
|
||||
} else if (success is UpdateMultipleSendingEmailAllSuccess) {
|
||||
_handleResendSendingEmailSuccess(success.newSendingEmails);
|
||||
} else if (success is UpdateMultipleSendingEmailHasSomeSuccess) {
|
||||
_handleResendSendingEmailSuccess(success.newSendingEmails);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void handleFailureViewState(Failure failure) {
|
||||
super.handleFailureViewState(failure);
|
||||
if (failure is DeleteMultipleSendingEmailAllFailure ||
|
||||
failure is DeleteMultipleSendingEmailFailure) {
|
||||
_handleDeleteSendingEmailFailure();
|
||||
if (failure is UpdateSendingEmailFailure) {
|
||||
refreshSendingQueue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ class SendingQueueView extends GetWidget<SendingQueueController> with AppLoaderM
|
||||
if (controller.selectionState.value == SelectMode.INACTIVE) {
|
||||
return RefreshIndicator(
|
||||
color: AppColor.primaryColor,
|
||||
onRefresh: () async => controller.refreshSendingQueue(needToReopen: true),
|
||||
onRefresh: () async => controller.refreshSendingQueue(),
|
||||
child: _buildListViewItemSendingEmails());
|
||||
} else {
|
||||
return _buildListViewItemSendingEmails();
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/base/state/button_state.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/domain/model/sending_email.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/presentation/extensions/list_sending_email_extension.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/presentation/model/sending_email_action_type.dart';
|
||||
|
||||
typedef OnHandleSendingEmailActionType = void Function(SendingEmailActionType, List<SendingEmail>);
|
||||
@@ -53,6 +54,19 @@ class BottomBarSendingQueueWidget extends StatelessWidget {
|
||||
})
|
||||
..text(SendingEmailActionType.edit.getButtonTitle(context), isVertical: responsiveUtils.isPortraitMobile(context))
|
||||
).build()),
|
||||
Expanded(child: (ButtonBuilder(imagePaths.icRefresh)
|
||||
..key(Key(SendingEmailActionType.resend.getButtonKey()))
|
||||
..iconColor(SendingEmailActionType.resend.getButtonIconColor(_isCanResend ? ButtonState.enabled : ButtonState.disabled))
|
||||
..padding(const EdgeInsets.all(8))
|
||||
..radiusSplash(8)
|
||||
..textStyle(TextStyle(fontSize: 12, color: SendingEmailActionType.resend.getButtonTitleColor(_isCanResend ? ButtonState.enabled : ButtonState.disabled)))
|
||||
..onPressActionClick(() {
|
||||
if (_isCanResend) {
|
||||
onHandleSendingEmailActionType?.call(SendingEmailActionType.resend, listSendingEmailSelected);
|
||||
}
|
||||
})
|
||||
..text(SendingEmailActionType.resend.getButtonTitle(context), isVertical: responsiveUtils.isPortraitMobile(context))
|
||||
).build()),
|
||||
Expanded(child: (ButtonBuilder(imagePaths.icDeleteComposer)
|
||||
..key(Key(SendingEmailActionType.delete.getButtonKey()))
|
||||
..iconColor(SendingEmailActionType.delete.getButtonIconColor(ButtonState.enabled))
|
||||
@@ -70,4 +84,6 @@ class BottomBarSendingQueueWidget extends StatelessWidget {
|
||||
bool get _isEditable => !isConnectedNetwork &&
|
||||
listSendingEmailSelected.length == 1 &&
|
||||
listSendingEmailSelected.first.isWaiting;
|
||||
|
||||
bool get _isCanResend => listSendingEmailSelected.isAllSendingStateError();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"@@last_modified": "2023-06-09T10:30:29.843203",
|
||||
"@@last_modified": "2023-06-09T22:51:52.101985",
|
||||
"initializing_data": "Initializing data...",
|
||||
"@initializing_data": {
|
||||
"type": "text",
|
||||
@@ -2905,5 +2905,17 @@
|
||||
"type": "text",
|
||||
"placeholders_order": [],
|
||||
"placeholders": {}
|
||||
},
|
||||
"resend": "Resend",
|
||||
"@resend": {
|
||||
"type": "text",
|
||||
"placeholders_order": [],
|
||||
"placeholders": {}
|
||||
},
|
||||
"messagesHaveBeenResent": "Messages have been resent",
|
||||
"@messagesHaveBeenResent": {
|
||||
"type": "text",
|
||||
"placeholders_order": [],
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
@@ -2995,4 +2995,16 @@ class AppLocalizations {
|
||||
name: 'connectedToTheInternet'
|
||||
);
|
||||
}
|
||||
|
||||
String get resend {
|
||||
return Intl.message(
|
||||
'Resend',
|
||||
name: 'resend');
|
||||
}
|
||||
|
||||
String get messagesHaveBeenResent {
|
||||
return Intl.message(
|
||||
'Messages have been resent',
|
||||
name: 'messagesHaveBeenResent');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user