TF-2667 Add cancel button in progress send message dialog
This commit is contained in:
@@ -0,0 +1 @@
|
||||
class SendingEmailCanceledException implements Exception {}
|
||||
@@ -53,4 +53,6 @@ class SendEmailFailure extends FeatureFailure {
|
||||
mailboxRequest,
|
||||
sendingEmailActionType,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
class CancelSendingEmail extends LoadingState {}
|
||||
@@ -2,10 +2,12 @@ import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:dartz/dartz.dart' as dartz;
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:jmap_dart_client/jmap/account_id.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/state.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/exceptions/compose_email_exception.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/repository/composer_repository.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/state/generate_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
|
||||
@@ -15,6 +17,7 @@ import 'package:tmail_ui_user/features/email/domain/exceptions/email_exceptions.
|
||||
import 'package:tmail_ui_user/features/email/domain/repository/email_repository.dart';
|
||||
import 'package:tmail_ui_user/features/mailbox/domain/repository/mailbox_repository.dart';
|
||||
import 'package:tmail_ui_user/features/sending_queue/presentation/model/sending_email_arguments.dart';
|
||||
import 'package:tmail_ui_user/main/exceptions/remote_exception.dart';
|
||||
|
||||
class CreateNewAndSendEmailInteractor {
|
||||
final EmailRepository _emailRepository;
|
||||
@@ -27,7 +30,10 @@ class CreateNewAndSendEmailInteractor {
|
||||
this._composerRepository,
|
||||
);
|
||||
|
||||
Stream<dartz.Either<Failure, Success>> execute(CreateEmailRequest createEmailRequest) async* {
|
||||
Stream<dartz.Either<Failure, Success>> execute({
|
||||
required CreateEmailRequest createEmailRequest,
|
||||
CancelToken? cancelToken
|
||||
}) async* {
|
||||
SendingEmailArguments? sendingEmailArguments;
|
||||
try {
|
||||
yield dartz.Right<Failure, Success>(GenerateEmailLoading());
|
||||
@@ -46,14 +52,16 @@ class CreateNewAndSendEmailInteractor {
|
||||
sendingEmailArguments.session,
|
||||
sendingEmailArguments.accountId,
|
||||
sendingEmailArguments.emailRequest,
|
||||
mailboxRequest: sendingEmailArguments.mailboxRequest
|
||||
mailboxRequest: sendingEmailArguments.mailboxRequest,
|
||||
cancelToken: cancelToken
|
||||
);
|
||||
|
||||
if (sendingEmailArguments.emailRequest.emailIdDestroyed != null) {
|
||||
await _deleteOldDraftsEmail(
|
||||
session: sendingEmailArguments.session,
|
||||
accountId: sendingEmailArguments.accountId,
|
||||
draftEmailId: sendingEmailArguments.emailRequest.emailIdDestroyed!
|
||||
draftEmailId: sendingEmailArguments.emailRequest.emailIdDestroyed!,
|
||||
cancelToken: cancelToken
|
||||
);
|
||||
}
|
||||
|
||||
@@ -69,13 +77,23 @@ class CreateNewAndSendEmailInteractor {
|
||||
}
|
||||
} catch (e) {
|
||||
logError('CreateNewAndSendEmailInteractor::execute: Exception: $e');
|
||||
yield dartz.Left<Failure, Success>(SendEmailFailure(
|
||||
exception: e,
|
||||
session: sendingEmailArguments?.session,
|
||||
accountId: sendingEmailArguments?.accountId,
|
||||
emailRequest: sendingEmailArguments?.emailRequest,
|
||||
mailboxRequest: sendingEmailArguments?.mailboxRequest,
|
||||
));
|
||||
if (e is UnknownError && e.message is List<SendingEmailCanceledException>) {
|
||||
yield dartz.Left<Failure, Success>(SendEmailFailure(
|
||||
exception: SendingEmailCanceledException(),
|
||||
session: sendingEmailArguments?.session,
|
||||
accountId: sendingEmailArguments?.accountId,
|
||||
emailRequest: sendingEmailArguments?.emailRequest,
|
||||
mailboxRequest: sendingEmailArguments?.mailboxRequest,
|
||||
));
|
||||
} else {
|
||||
yield dartz.Left<Failure, Success>(SendEmailFailure(
|
||||
exception: e,
|
||||
session: sendingEmailArguments?.session,
|
||||
accountId: sendingEmailArguments?.accountId,
|
||||
emailRequest: sendingEmailArguments?.emailRequest,
|
||||
mailboxRequest: sendingEmailArguments?.mailboxRequest,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,13 +131,15 @@ class CreateNewAndSendEmailInteractor {
|
||||
Future<void> _deleteOldDraftsEmail({
|
||||
required Session session,
|
||||
required AccountId accountId,
|
||||
required EmailId draftEmailId
|
||||
required EmailId draftEmailId,
|
||||
CancelToken? cancelToken
|
||||
}) async {
|
||||
try {
|
||||
await _emailRepository.deleteEmailPermanently(
|
||||
session,
|
||||
accountId,
|
||||
draftEmailId
|
||||
draftEmailId,
|
||||
cancelToken: cancelToken
|
||||
);
|
||||
} catch (e) {
|
||||
logError('CreateNewAndSendEmailInteractor::_deleteOldDraftsEmail: Exception: $e');
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:core/core.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:desktop_drop/desktop_drop.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:filesize/filesize.dart';
|
||||
@@ -29,6 +30,7 @@ import 'package:super_tag_editor/tag_editor.dart';
|
||||
import 'package:tmail_ui_user/features/base/base_controller.dart';
|
||||
import 'package:tmail_ui_user/features/base/state/base_ui_state.dart';
|
||||
import 'package:tmail_ui_user/features/base/state/button_state.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/exceptions/compose_email_exception.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/model/contact_suggestion_source.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/state/download_image_as_base64_state.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/state/generate_email_state.dart';
|
||||
@@ -802,12 +804,17 @@ class ComposerController extends BaseController with DragDropFileMixin {
|
||||
}
|
||||
|
||||
final emailContent = await _getContentInEditor();
|
||||
|
||||
final resultState = await _showSendingMessageDialog(emailContent: emailContent);
|
||||
|
||||
final cancelToken = CancelToken();
|
||||
final resultState = await _showSendingMessageDialog(
|
||||
emailContent: emailContent,
|
||||
cancelToken: cancelToken
|
||||
);
|
||||
log('ComposerController::_handleSendMessages: resultState = $resultState');
|
||||
if (resultState is SendEmailSuccess) {
|
||||
_sendButtonState = ButtonState.enabled;
|
||||
_closeComposerAction(result: resultState);
|
||||
} else if (resultState is SendEmailFailure && resultState.exception is SendingEmailCanceledException) {
|
||||
_sendButtonState = ButtonState.enabled;
|
||||
} else if ((resultState is SendEmailFailure || resultState is GenerateEmailFailure) && context.mounted) {
|
||||
_showConfirmDialogWhenSendMessageFailure(
|
||||
context: context,
|
||||
@@ -818,7 +825,10 @@ class ComposerController extends BaseController with DragDropFileMixin {
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> _showSendingMessageDialog({required String emailContent}) {
|
||||
Future<dynamic> _showSendingMessageDialog({
|
||||
required String emailContent,
|
||||
CancelToken? cancelToken
|
||||
}) {
|
||||
return Get.dialog(
|
||||
PointerInterceptor(
|
||||
child: SendingMessageDialogView(
|
||||
@@ -847,13 +857,19 @@ class ComposerController extends BaseController with DragDropFileMixin {
|
||||
references: composerArguments.value!.references,
|
||||
emailSendingQueue: composerArguments.value!.sendingEmail
|
||||
),
|
||||
createNewAndSendEmailInteractor: _createNewAndSendEmailInteractor
|
||||
createNewAndSendEmailInteractor: _createNewAndSendEmailInteractor,
|
||||
onCancelSendingEmailAction: _handleCancelSendingMessage,
|
||||
cancelToken: cancelToken,
|
||||
),
|
||||
),
|
||||
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
|
||||
);
|
||||
}
|
||||
|
||||
void _handleCancelSendingMessage({CancelToken? cancelToken}) {
|
||||
cancelToken?.cancel([SendingEmailCanceledException()]);
|
||||
}
|
||||
|
||||
void _showConfirmDialogWhenSendMessageFailure({
|
||||
required BuildContext context,
|
||||
required FeatureFailure failure
|
||||
|
||||
@@ -5,26 +5,36 @@ import 'package:core/presentation/extensions/capitalize_extension.dart';
|
||||
import 'package:core/presentation/extensions/color_extension.dart';
|
||||
import 'package:core/presentation/state/failure.dart';
|
||||
import 'package:core/presentation/state/success.dart';
|
||||
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||
import 'package:core/utils/app_logger.dart';
|
||||
import 'package:dartz/dartz.dart' as dartz;
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/exceptions/compose_email_exception.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/state/generate_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/state/send_email_state.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/usecases/create_new_and_send_email_interactor.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/model/create_email_request.dart';
|
||||
import 'package:tmail_ui_user/main/exceptions/remote_exception.dart';
|
||||
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
|
||||
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
|
||||
|
||||
typedef OnCancelSendingEmailAction = Function({CancelToken? cancelToken});
|
||||
|
||||
class SendingMessageDialogView extends StatefulWidget {
|
||||
|
||||
final CreateEmailRequest createEmailRequest;
|
||||
final CreateNewAndSendEmailInteractor createNewAndSendEmailInteractor;
|
||||
final OnCancelSendingEmailAction? onCancelSendingEmailAction;
|
||||
final CancelToken? cancelToken;
|
||||
|
||||
const SendingMessageDialogView({
|
||||
super.key,
|
||||
required this.createEmailRequest,
|
||||
required this.createNewAndSendEmailInteractor,
|
||||
this.onCancelSendingEmailAction,
|
||||
this.cancelToken,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -40,7 +50,10 @@ class _SendingMessageDialogViewState extends State<SendingMessageDialogView> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
_streamSubscription = widget.createNewAndSendEmailInteractor
|
||||
.execute(widget.createEmailRequest)
|
||||
.execute(
|
||||
createEmailRequest: widget.createEmailRequest,
|
||||
cancelToken: widget.cancelToken
|
||||
)
|
||||
.listen(
|
||||
_handleDataStream,
|
||||
onError: _handleErrorStream
|
||||
@@ -66,7 +79,11 @@ class _SendingMessageDialogViewState extends State<SendingMessageDialogView> {
|
||||
|
||||
void _handleErrorStream(Object error, StackTrace stackTrace) {
|
||||
logError('_SendingMessageDialogViewState::_handleErrorStream: Exception = $error');
|
||||
popBack(result: SendEmailFailure(exception: error));
|
||||
if (error is UnknownError && error.message is List<SendingEmailCanceledException>) {
|
||||
popBack(result: SendEmailFailure(exception: SendingEmailCanceledException()));
|
||||
} else {
|
||||
popBack(result: SendEmailFailure(exception: error));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -142,6 +159,14 @@ class _SendingMessageDialogViewState extends State<SendingMessageDialogView> {
|
||||
fontSize: 14
|
||||
),
|
||||
);
|
||||
} else if (success is CancelSendingEmail) {
|
||||
return Text(
|
||||
'${AppLocalizations.of(context).canceling}...',
|
||||
style: Theme.of(context).textTheme.labelSmall?.copyWith(
|
||||
color: AppColor.labelColor,
|
||||
fontSize: 14
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Text(
|
||||
'${AppLocalizations.of(context).sendingMessage}...',
|
||||
@@ -167,7 +192,7 @@ class _SendingMessageDialogViewState extends State<SendingMessageDialogView> {
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsetsDirectional.only(start: 16, end: 16, top: 4, bottom: 24),
|
||||
padding: const EdgeInsetsDirectional.only(start: 16, end: 16, top: 4, bottom: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
@@ -188,7 +213,24 @@ class _SendingMessageDialogViewState extends State<SendingMessageDialogView> {
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
),
|
||||
if (widget.onCancelSendingEmailAction != null)
|
||||
Align(
|
||||
alignment: AlignmentDirectional.centerEnd,
|
||||
child: TMailButtonWidget.fromText(
|
||||
text: AppLocalizations.of(context).cancel,
|
||||
textStyle: Theme.of(context).textTheme.labelSmall?.copyWith(
|
||||
color: Colors.black87,
|
||||
fontSize: 15
|
||||
),
|
||||
padding: const EdgeInsetsDirectional.symmetric(horizontal: 20, vertical: 8),
|
||||
margin: const EdgeInsetsDirectional.only(start: 12, end: 12, bottom: 16),
|
||||
onTapActionCallback: () {
|
||||
_viewStateNotifier.value = dartz.Right<Failure, Success>(CancelSendingEmail());
|
||||
widget.onCancelSendingEmailAction!(cancelToken: widget.cancelToken);
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
],
|
||||
|
||||
@@ -32,7 +32,10 @@ abstract class EmailDataSource {
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
EmailRequest emailRequest,
|
||||
{CreateNewMailboxRequest? mailboxRequest}
|
||||
{
|
||||
CreateNewMailboxRequest? mailboxRequest,
|
||||
CancelToken? cancelToken
|
||||
}
|
||||
);
|
||||
|
||||
Future<List<Email>> markAsRead(Session session, AccountId accountId, List<Email> emails, ReadActions readActions);
|
||||
@@ -79,7 +82,12 @@ abstract class EmailDataSource {
|
||||
|
||||
Future<List<EmailId>> deleteMultipleEmailsPermanently(Session session, AccountId accountId, List<EmailId> emailIds);
|
||||
|
||||
Future<bool> deleteEmailPermanently(Session session, AccountId accountId, EmailId emailId);
|
||||
Future<bool> deleteEmailPermanently(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
{CancelToken? cancelToken}
|
||||
);
|
||||
|
||||
Future<void> storeDetailedNewEmail(Session session, AccountId accountId, DetailedEmail detailedEmail);
|
||||
|
||||
|
||||
@@ -46,10 +46,19 @@ class EmailDataSourceImpl extends EmailDataSource {
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
EmailRequest emailRequest,
|
||||
{CreateNewMailboxRequest? mailboxRequest}
|
||||
{
|
||||
CreateNewMailboxRequest? mailboxRequest,
|
||||
CancelToken? cancelToken,
|
||||
}
|
||||
) async {
|
||||
try {
|
||||
return await emailAPI.sendEmail(session, accountId, emailRequest, mailboxRequest: mailboxRequest);
|
||||
return await emailAPI.sendEmail(
|
||||
session,
|
||||
accountId,
|
||||
emailRequest,
|
||||
mailboxRequest: mailboxRequest,
|
||||
cancelToken: cancelToken
|
||||
);
|
||||
} catch (error, stackTrace) {
|
||||
return await _sendEmailExceptionThrower.throwException(error, stackTrace);
|
||||
}
|
||||
@@ -157,9 +166,19 @@ class EmailDataSourceImpl extends EmailDataSource {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> deleteEmailPermanently(Session session, AccountId accountId, EmailId emailId) {
|
||||
Future<bool> deleteEmailPermanently(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
{CancelToken? cancelToken}
|
||||
) {
|
||||
return Future.sync(() async {
|
||||
return await emailAPI.deleteEmailPermanently(session, accountId, emailId);
|
||||
return await emailAPI.deleteEmailPermanently(
|
||||
session,
|
||||
accountId,
|
||||
emailId,
|
||||
cancelToken: cancelToken
|
||||
);
|
||||
}).catchError(_exceptionThrower.throwException);
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,12 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
|
||||
);
|
||||
|
||||
@override
|
||||
Future<bool> deleteEmailPermanently(Session session, AccountId accountId, EmailId emailId) {
|
||||
Future<bool> deleteEmailPermanently(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
{CancelToken? cancelToken}
|
||||
) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@@ -134,7 +139,15 @@ class EmailHiveCacheDataSourceImpl extends EmailDataSource {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> sendEmail(Session session, AccountId accountId, EmailRequest emailRequest, {CreateNewMailboxRequest? mailboxRequest}) {
|
||||
Future<bool> sendEmail(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
EmailRequest emailRequest,
|
||||
{
|
||||
CreateNewMailboxRequest? mailboxRequest,
|
||||
CancelToken? cancelToken
|
||||
}
|
||||
) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,10 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
EmailRequest emailRequest,
|
||||
{CreateNewMailboxRequest? mailboxRequest}
|
||||
{
|
||||
CreateNewMailboxRequest? mailboxRequest,
|
||||
CancelToken? cancelToken,
|
||||
}
|
||||
) async {
|
||||
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
|
||||
|
||||
@@ -199,7 +202,7 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
final response = await (requestBuilder
|
||||
..usings(capabilities))
|
||||
.build()
|
||||
.execute();
|
||||
.execute(cancelToken: cancelToken);
|
||||
|
||||
final setEmailResponse = response.parse<SetEmailResponse>(
|
||||
setEmailInvocation.methodCallId,
|
||||
@@ -606,7 +609,12 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
return List.empty();
|
||||
}
|
||||
|
||||
Future<bool> deleteEmailPermanently(Session session, AccountId accountId, EmailId emailId) async {
|
||||
Future<bool> deleteEmailPermanently(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
{CancelToken? cancelToken}
|
||||
) async {
|
||||
final requestBuilder = JmapRequestBuilder(_httpClient, ProcessingInvocation());
|
||||
final setEmailMethod = SetEmailMethod(accountId)
|
||||
..addDestroy({emailId.id});
|
||||
@@ -619,7 +627,7 @@ class EmailAPI with HandleSetErrorMixin {
|
||||
final response = await (requestBuilder
|
||||
..usings(capabilities))
|
||||
.build()
|
||||
.execute();
|
||||
.execute(cancelToken: cancelToken);
|
||||
|
||||
final setEmailResponse = response.parse<SetEmailResponse>(
|
||||
setEmailInvocation.methodCallId,
|
||||
|
||||
@@ -58,9 +58,18 @@ class EmailRepositoryImpl extends EmailRepository {
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
EmailRequest emailRequest,
|
||||
{CreateNewMailboxRequest? mailboxRequest}
|
||||
{
|
||||
CreateNewMailboxRequest? mailboxRequest,
|
||||
CancelToken? cancelToken
|
||||
}
|
||||
) {
|
||||
return emailDataSource[DataSourceType.network]!.sendEmail(session, accountId, emailRequest, mailboxRequest: mailboxRequest);
|
||||
return emailDataSource[DataSourceType.network]!.sendEmail(
|
||||
session,
|
||||
accountId,
|
||||
emailRequest,
|
||||
mailboxRequest: mailboxRequest,
|
||||
cancelToken: cancelToken,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -172,8 +181,18 @@ class EmailRepositoryImpl extends EmailRepository {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> deleteEmailPermanently(Session session, AccountId accountId, EmailId emailId) {
|
||||
return emailDataSource[DataSourceType.network]!.deleteEmailPermanently(session, accountId, emailId);
|
||||
Future<bool> deleteEmailPermanently(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
{CancelToken? cancelToken}
|
||||
) {
|
||||
return emailDataSource[DataSourceType.network]!.deleteEmailPermanently(
|
||||
session,
|
||||
accountId,
|
||||
emailId,
|
||||
cancelToken: cancelToken
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -34,7 +34,10 @@ abstract class EmailRepository {
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
EmailRequest emailRequest,
|
||||
{CreateNewMailboxRequest? mailboxRequest}
|
||||
{
|
||||
CreateNewMailboxRequest? mailboxRequest,
|
||||
CancelToken? cancelToken
|
||||
}
|
||||
);
|
||||
|
||||
Future<List<Email>> markAsRead(Session session, AccountId accountId, List<Email> emails, ReadActions readActions);
|
||||
@@ -87,7 +90,12 @@ abstract class EmailRepository {
|
||||
|
||||
Future<List<EmailId>> deleteMultipleEmailsPermanently(Session session, AccountId accountId, List<EmailId> emailIds);
|
||||
|
||||
Future<bool> deleteEmailPermanently(Session session, AccountId accountId, EmailId emailId);
|
||||
Future<bool> deleteEmailPermanently(
|
||||
Session session,
|
||||
AccountId accountId,
|
||||
EmailId emailId,
|
||||
{CancelToken? cancelToken}
|
||||
);
|
||||
|
||||
Future<jmap.State?> getEmailState(Session session, AccountId accountId);
|
||||
|
||||
|
||||
@@ -415,10 +415,10 @@ class ThreadController extends BaseController with EmailActionController {
|
||||
}
|
||||
_getAllEmailAction();
|
||||
} else if (error is MethodLevelErrors) {
|
||||
if (currentOverlayContext != null && error.message?.isNotEmpty == true) {
|
||||
if (currentOverlayContext != null && error.message != null) {
|
||||
appToast.showToastErrorMessage(
|
||||
currentOverlayContext!,
|
||||
error.message!
|
||||
error.message?.toString() ?? ''
|
||||
);
|
||||
}
|
||||
clearState();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"@@last_modified": "2024-03-06T02:46:19.947772",
|
||||
"@@last_modified": "2024-03-12T12:50:35.525381",
|
||||
"initializing_data": "Initializing data...",
|
||||
"@initializing_data": {
|
||||
"type": "text",
|
||||
@@ -3845,5 +3845,11 @@
|
||||
"type": "text",
|
||||
"placeholders_order": [],
|
||||
"placeholders": {}
|
||||
},
|
||||
"canceling": "Canceling",
|
||||
"@canceling": {
|
||||
"type": "text",
|
||||
"placeholders_order": [],
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ abstract class RemoteException with EquatableMixin implements Exception {
|
||||
static const badCredentials = 'Bad credentials';
|
||||
static const socketException = 'Socket exception';
|
||||
|
||||
final String? message;
|
||||
final Object? message;
|
||||
final int? code;
|
||||
|
||||
const RemoteException({this.code, this.message});
|
||||
@@ -25,7 +25,7 @@ class BadCredentialsException extends RemoteException {
|
||||
}
|
||||
|
||||
class UnknownError extends RemoteException {
|
||||
const UnknownError({int? code, String? message}) : super(code: code, message: message);
|
||||
const UnknownError({int? code, Object? message}) : super(code: code, message: message);
|
||||
|
||||
@override
|
||||
List<Object?> get props => [code, message];
|
||||
|
||||
@@ -53,7 +53,7 @@ class RemoteExceptionThrower extends ExceptionThrower {
|
||||
if (error.error is SocketException) {
|
||||
throw const SocketError();
|
||||
} else if (error.error != null) {
|
||||
throw UnknownError(message: error.error!.toString());
|
||||
throw UnknownError(message: error.error);
|
||||
} else {
|
||||
throw const UnknownError();
|
||||
}
|
||||
|
||||
@@ -4016,4 +4016,11 @@ class AppLocalizations {
|
||||
'Saving of the message to drafts folder failed.\nAn error occurred while saving mail.',
|
||||
name: 'warningMessageWhenSaveEmailToDraftsFailure');
|
||||
}
|
||||
|
||||
String get canceling {
|
||||
return Intl.message(
|
||||
'Canceling',
|
||||
name: 'canceling'
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user