TF-2667 Add cancel button in progress saving message to drafts dialog

This commit is contained in:
dab246
2024-03-12 13:43:14 +07:00
committed by Dat H. Pham
parent f2b70aec48
commit c013e0306c
14 changed files with 297 additions and 94 deletions
@@ -1129,10 +1129,11 @@ class ComposerController extends BaseController with DragDropFileMixin {
}
final emailContent = await _getContentInEditor();
final cancelToken = CancelToken();
final resultState = await _showSavingMessageToDraftsDialog(
emailContent: emailContent,
draftEmailId: _emailIdEditing
draftEmailId: _emailIdEditing,
cancelToken: cancelToken
);
if (resultState is SaveEmailAsDraftsSuccess) {
@@ -1143,6 +1144,9 @@ class ComposerController extends BaseController with DragDropFileMixin {
_saveToDraftButtonState = ButtonState.enabled;
_emailIdEditing = resultState.emailId;
mailboxDashBoardController.consumeState(Stream.value(Right<Failure, Success>(resultState)));
} else if ((resultState is SaveEmailAsDraftsFailure && resultState.exception is SavingEmailToDraftsCanceledException) ||
(resultState is UpdateEmailDraftsFailure && resultState.exception is SavingEmailToDraftsCanceledException)) {
_saveToDraftButtonState = ButtonState.enabled;
} else if ((resultState is SaveEmailAsDraftsFailure ||
resultState is UpdateEmailDraftsFailure ||
resultState is GenerateEmailFailure) &&
@@ -2035,14 +2039,20 @@ class ComposerController extends BaseController with DragDropFileMixin {
final emailContent = await _getContentInEditor();
final draftEmailId = _getDraftEmailId();
log('ComposerController::_handleSaveMessageToDraft: draftEmailId = $draftEmailId');
final cancelToken = CancelToken();
final resultState = await _showSavingMessageToDraftsDialog(
emailContent: emailContent,
draftEmailId: draftEmailId
draftEmailId: draftEmailId,
cancelToken: cancelToken
);
if (resultState is SaveEmailAsDraftsSuccess || resultState is UpdateEmailDraftsSuccess) {
_closeComposerButtonState = ButtonState.enabled;
_closeComposerAction(result: resultState);
} else if ((resultState is SaveEmailAsDraftsFailure && resultState.exception is SavingEmailToDraftsCanceledException) ||
(resultState is UpdateEmailDraftsFailure && resultState.exception is SavingEmailToDraftsCanceledException)) {
_closeComposerButtonState = ButtonState.enabled;
_closeComposerAction();
} else if ((resultState is SaveEmailAsDraftsFailure ||
resultState is UpdateEmailDraftsFailure ||
resultState is GenerateEmailFailure) &&
@@ -2071,6 +2081,7 @@ class ComposerController extends BaseController with DragDropFileMixin {
Future<dynamic> _showSavingMessageToDraftsDialog({
required String emailContent,
EmailId? draftEmailId,
CancelToken? cancelToken,
}) {
return Get.dialog(
PointerInterceptor(
@@ -2098,13 +2109,19 @@ class ComposerController extends BaseController with DragDropFileMixin {
references: composerArguments.value!.references,
emailSendingQueue: composerArguments.value!.sendingEmail
),
createNewAndSaveEmailToDraftsInteractor: _createNewAndSaveEmailToDraftsInteractor
createNewAndSaveEmailToDraftsInteractor: _createNewAndSaveEmailToDraftsInteractor,
onCancelSavingEmailToDraftsAction: _handleCancelSavingMessageToDrafts,
cancelToken: cancelToken,
),
),
barrierColor: AppColor.colorDefaultCupertinoActionSheet,
);
}
void _handleCancelSavingMessageToDrafts({CancelToken? cancelToken}) {
cancelToken?.cancel([SavingEmailToDraftsCanceledException()]);
}
void _showConfirmDialogWhenSaveMessageToDraftsFailure({
required BuildContext context,
required FeatureFailure failure,
@@ -5,27 +5,37 @@ 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/save_email_as_drafts_state.dart';
import 'package:tmail_ui_user/features/composer/domain/state/update_email_drafts_state.dart';
import 'package:tmail_ui_user/features/composer/domain/usecases/create_new_and_save_email_to_drafts_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 OnCancelSavingEmailToDraftsAction = Function({CancelToken? cancelToken});
class SavingMessageDialogView extends StatefulWidget {
final CreateEmailRequest createEmailRequest;
final CreateNewAndSaveEmailToDraftsInteractor createNewAndSaveEmailToDraftsInteractor;
final OnCancelSavingEmailToDraftsAction? onCancelSavingEmailToDraftsAction;
final CancelToken? cancelToken;
const SavingMessageDialogView({
super.key,
required this.createEmailRequest,
required this.createNewAndSaveEmailToDraftsInteractor,
this.onCancelSavingEmailToDraftsAction,
this.cancelToken,
});
@override
@@ -41,7 +51,10 @@ class _SavingMessageDialogViewState extends State<SavingMessageDialogView> {
void initState() {
super.initState();
_streamSubscription = widget.createNewAndSaveEmailToDraftsInteractor
.execute(widget.createEmailRequest)
.execute(
createEmailRequest: widget.createEmailRequest,
cancelToken: widget.cancelToken
)
.listen(
_handleDataStream,
onError: _handleErrorStream
@@ -69,7 +82,11 @@ class _SavingMessageDialogViewState extends State<SavingMessageDialogView> {
void _handleErrorStream(Object error, StackTrace stackTrace) {
logError('_SavingMessageDialogViewState::_handleErrorStream: Exception = $error');
popBack(result: SaveEmailAsDraftsFailure(error));
if (error is UnknownError && error.message is List<SavingEmailToDraftsCanceledException>) {
popBack(result: SaveEmailAsDraftsFailure(SavingEmailToDraftsCanceledException()));
} else {
popBack(result: SaveEmailAsDraftsFailure(error));
}
}
@override
@@ -137,23 +154,13 @@ class _SavingMessageDialogViewState extends State<SavingMessageDialogView> {
return value.fold(
(failure) => child!,
(success) {
if (success is GenerateEmailLoading) {
return Text(
'${AppLocalizations.of(context).creatingMessage}...',
style: Theme.of(context).textTheme.labelSmall?.copyWith(
color: AppColor.labelColor,
fontSize: 14
),
);
} else {
return Text(
'${AppLocalizations.of(context).savingMessageToDraftFolder}...',
style: Theme.of(context).textTheme.labelSmall?.copyWith(
color: AppColor.labelColor,
fontSize: 14
),
);
}
return Text(
'${_getStatusMessage(success)}...',
style: Theme.of(context).textTheme.labelSmall?.copyWith(
color: AppColor.labelColor,
fontSize: 14
),
);
}
);
},
@@ -170,7 +177,7 @@ class _SavingMessageDialogViewState extends State<SavingMessageDialogView> {
),
),
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(
@@ -191,7 +198,24 @@ class _SavingMessageDialogViewState extends State<SavingMessageDialogView> {
)
],
),
)
),
if (widget.onCancelSavingEmailToDraftsAction != 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>(CancelSavingEmailToDrafts());
widget.onCancelSavingEmailToDraftsAction!(cancelToken: widget.cancelToken);
},
),
)
],
)
],
@@ -200,6 +224,16 @@ class _SavingMessageDialogViewState extends State<SavingMessageDialogView> {
);
}
String _getStatusMessage(Success success) {
if (success is GenerateEmailLoading) {
return AppLocalizations.of(context).creatingMessage;
} else if (success is CancelSavingEmailToDrafts) {
return AppLocalizations.of(context).canceling;
} else {
return AppLocalizations.of(context).savingMessageToDraftFolder;
}
}
@override
void dispose() {
_streamSubscription?.cancel();
@@ -151,31 +151,13 @@ class _SendingMessageDialogViewState extends State<SendingMessageDialogView> {
return value.fold(
(failure) => child!,
(success) {
if (success is GenerateEmailLoading) {
return Text(
'${AppLocalizations.of(context).creatingMessage}...',
style: Theme.of(context).textTheme.labelSmall?.copyWith(
color: AppColor.labelColor,
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}...',
style: Theme.of(context).textTheme.labelSmall?.copyWith(
color: AppColor.labelColor,
fontSize: 14
),
);
}
return Text(
'${_getStatusMessage(success)}...',
style: Theme.of(context).textTheme.labelSmall?.copyWith(
color: AppColor.labelColor,
fontSize: 14
),
);
}
);
},
@@ -239,6 +221,16 @@ class _SendingMessageDialogViewState extends State<SendingMessageDialogView> {
);
}
String _getStatusMessage(Success success) {
if (success is GenerateEmailLoading) {
return AppLocalizations.of(context).creatingMessage;
} else if (success is CancelSendingEmail) {
return AppLocalizations.of(context).canceling;
} else {
return AppLocalizations.of(context).sendingMessage;
}
}
@override
void dispose() {
_streamSubscription?.cancel();