TF-2597 Handles the ability to click the editor close button only once
Signed-off-by: dab246 <tdvu@linagora.com>
This commit is contained in:
@@ -34,6 +34,7 @@ import 'package:rich_text_composer/rich_text_composer.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
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/button_state.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/model/contact_suggestion_source.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/model/email_request.dart';
|
||||
import 'package:tmail_ui_user/features/composer/domain/state/download_image_as_base64_state.dart';
|
||||
@@ -167,9 +168,11 @@ class ComposerController extends BaseController {
|
||||
double? maxWithEditor;
|
||||
EmailId? _emailIdEditing;
|
||||
bool isAttachmentCollapsed = false;
|
||||
ButtonState _closeComposerButtonState = ButtonState.enabled;
|
||||
|
||||
late Worker uploadInlineImageWorker;
|
||||
late Worker dashboardViewStateWorker;
|
||||
late bool _isEmailBodyLoaded;
|
||||
|
||||
ComposerController(
|
||||
this._deviceInfoPlugin,
|
||||
@@ -408,12 +411,14 @@ class ComposerController extends BaseController {
|
||||
}
|
||||
|
||||
void onLoadCompletedMobileEditorAction(HtmlEditorApi editorApi, WebUri? url) {
|
||||
_isEmailBodyLoaded = true;
|
||||
if (identitySelected.value == null) {
|
||||
_getAllIdentities();
|
||||
}
|
||||
}
|
||||
|
||||
void _initEmail() {
|
||||
_isEmailBodyLoaded = false;
|
||||
final arguments = PlatformInfo.isWeb
|
||||
? mailboxDashBoardController.composerArguments
|
||||
: Get.arguments;
|
||||
@@ -785,7 +790,7 @@ class ComposerController extends BaseController {
|
||||
return;
|
||||
}
|
||||
|
||||
clearFocusEditor(context);
|
||||
clearFocus(context);
|
||||
|
||||
isSendEmailLoading.value = true;
|
||||
|
||||
@@ -1025,7 +1030,7 @@ class ComposerController extends BaseController {
|
||||
}
|
||||
|
||||
void openPickAttachmentMenu(BuildContext context, List<Widget> actionTiles) {
|
||||
clearFocusEditor(context);
|
||||
clearFocus(context);
|
||||
|
||||
(ContextMenuBuilder(context)
|
||||
..addHeader((ContextMenuHeaderBuilder(const Key('attachment_picker_context_menu_header_builder'))
|
||||
@@ -1083,18 +1088,16 @@ class ComposerController extends BaseController {
|
||||
uploadController.deleteFileUploaded(uploadId);
|
||||
}
|
||||
|
||||
Future<bool> _isEmailChanged({
|
||||
Future<bool> _validateEmailChange({
|
||||
required BuildContext context,
|
||||
required EmailActionType emailActionType,
|
||||
PresentationEmail? presentationEmail,
|
||||
Role? mailboxRole,
|
||||
}) async {
|
||||
final newEmailBody = await _getEmailBodyText(context, asDrafts: true);
|
||||
log('ComposerController::_isEmailChanged(): newEmailBody: $newEmailBody');
|
||||
final oldEmailBody = _initTextEditor ?? '';
|
||||
log('ComposerController::_isEmailChanged(): oldEmailBody: $oldEmailBody');
|
||||
final isEmailBodyChanged = !oldEmailBody.trim().isSame(newEmailBody.trim());
|
||||
log('ComposerController::_isEmailChanged(): isEmailBodyChanged: $isEmailBodyChanged');
|
||||
|
||||
final newEmailSubject = subjectEmail.value ?? '';
|
||||
final oldEmailSubject = emailActionType == EmailActionType.editDraft
|
||||
? presentationEmail?.getEmailTitle().trim() ?? ''
|
||||
@@ -1120,7 +1123,7 @@ class ComposerController extends BaseController {
|
||||
final isBccEmailAddressChanged = !oldBccEmailAddress.isSame(newBccEmailAddress);
|
||||
|
||||
final isAttachmentsChanged = !initialAttachments.isSame(uploadController.attachmentsUploaded.toList());
|
||||
|
||||
log('ComposerController::_validateChangeEmail: isEmailBodyChanged = $isEmailBodyChanged | isEmailSubjectChanged = $isEmailSubjectChanged | isToEmailAddressChanged = $isToEmailAddressChanged | isCcEmailAddressChanged = $isCcEmailAddressChanged | isBccEmailAddressChanged = $isBccEmailAddressChanged | isAttachmentsChanged = $isAttachmentsChanged');
|
||||
if (isEmailBodyChanged || isEmailSubjectChanged
|
||||
|| isToEmailAddressChanged || isCcEmailAddressChanged
|
||||
|| isBccEmailAddressChanged || isAttachmentsChanged) {
|
||||
@@ -1130,10 +1133,8 @@ class ComposerController extends BaseController {
|
||||
return false;
|
||||
}
|
||||
|
||||
void saveToDraftAndClose(BuildContext context) async {
|
||||
log('ComposerController::saveToDraftAndClose:');
|
||||
clearFocusEditor(context);
|
||||
|
||||
Future<SaveToDraftArguments?> _handleSaveAsDrafts(BuildContext context) async {
|
||||
log('ComposerController::_handleSaveAsDrafts:');
|
||||
final arguments = composerArguments.value;
|
||||
final userProfile = mailboxDashBoardController.userProfile.value;
|
||||
final accountId = mailboxDashBoardController.accountId.value;
|
||||
@@ -1146,9 +1147,7 @@ class ComposerController extends BaseController {
|
||||
session == null ||
|
||||
accountId == null
|
||||
) {
|
||||
logError('ComposerController::saveToDraftAndClose: Param is NULL');
|
||||
_closeComposerAction();
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_emailIdEditing != null && _emailIdEditing != arguments.presentationEmail?.id) {
|
||||
@@ -1160,20 +1159,19 @@ class ComposerController extends BaseController {
|
||||
arguments: arguments,
|
||||
);
|
||||
|
||||
_closeComposerAction(result: SaveToDraftArguments(
|
||||
return SaveToDraftArguments(
|
||||
session: session,
|
||||
accountId: accountId,
|
||||
newEmail: newEmail,
|
||||
oldEmailId: _emailIdEditing!
|
||||
));
|
||||
oldEmailId: _emailIdEditing!);
|
||||
} else {
|
||||
final isChanged = await _isEmailChanged(
|
||||
final isChanged = await _validateEmailChange(
|
||||
context: context,
|
||||
emailActionType: arguments.emailActionType,
|
||||
presentationEmail: arguments.presentationEmail,
|
||||
mailboxRole: arguments.mailboxRole
|
||||
);
|
||||
log('ComposerController::saveToDraftAndClose: isChanged: $isChanged');
|
||||
|
||||
if (isChanged && context.mounted) {
|
||||
final newEmail = await _generateEmail(
|
||||
context,
|
||||
@@ -1183,16 +1181,15 @@ class ComposerController extends BaseController {
|
||||
arguments: arguments,
|
||||
);
|
||||
|
||||
_closeComposerAction(result: SaveToDraftArguments(
|
||||
return SaveToDraftArguments(
|
||||
session: session,
|
||||
accountId: accountId,
|
||||
newEmail: newEmail,
|
||||
oldEmailId: arguments.emailActionType == EmailActionType.editDraft
|
||||
? arguments.presentationEmail?.id
|
||||
: null
|
||||
));
|
||||
: null);
|
||||
} else {
|
||||
_closeComposerAction();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1413,7 +1410,8 @@ class ComposerController extends BaseController {
|
||||
return '';
|
||||
}
|
||||
|
||||
void clearFocusEditor(BuildContext context) {
|
||||
void clearFocus(BuildContext context) {
|
||||
log('ComposerController::clearFocus:');
|
||||
if (PlatformInfo.isMobile) {
|
||||
htmlEditorApi?.unfocus();
|
||||
KeyboardUtils.hideSystemKeyboardMobile();
|
||||
@@ -1422,21 +1420,16 @@ class ComposerController extends BaseController {
|
||||
}
|
||||
|
||||
void _closeComposerAction({dynamic result}) {
|
||||
uploadController.clearInlineFileUploaded();
|
||||
log('ComposerController::_closeComposerAction:');
|
||||
isSendEmailLoading.value = false;
|
||||
|
||||
if (PlatformInfo.isWeb) {
|
||||
_closeComposerWeb(result: result);
|
||||
mailboxDashBoardController.closeComposerOverlay(result: result);
|
||||
} else {
|
||||
isSendEmailLoading.value = false;
|
||||
popBack(result: result);
|
||||
}
|
||||
}
|
||||
|
||||
void _closeComposerWeb({dynamic result}) {
|
||||
isSendEmailLoading.value = false;
|
||||
mailboxDashBoardController.closeComposerOverlay(result: result);
|
||||
}
|
||||
|
||||
void displayScreenTypeComposerAction(ScreenDisplayMode displayMode) async {
|
||||
createFocusNodeInput();
|
||||
_updateTextForEditor();
|
||||
@@ -1722,7 +1715,7 @@ class ComposerController extends BaseController {
|
||||
}
|
||||
|
||||
void insertImage(BuildContext context, double maxWith) async {
|
||||
clearFocusEditor(context);
|
||||
clearFocus(context);
|
||||
|
||||
if (responsiveUtils.isMobile(context)) {
|
||||
maxWithEditor = maxWith - 40;
|
||||
@@ -1915,6 +1908,8 @@ class ComposerController extends BaseController {
|
||||
subjectEmailInputFocusNode?.hasFocus == true;
|
||||
|
||||
void handleInitHtmlEditorWeb(String initContent) {
|
||||
log('ComposerController::handleInitHtmlEditorWeb:');
|
||||
_isEmailBodyLoaded = true;
|
||||
richTextWebController.editorController.setFullScreen();
|
||||
onChangeTextEditorWeb(initContent);
|
||||
richTextWebController.setEnableCodeView();
|
||||
@@ -2156,4 +2151,25 @@ class ComposerController extends BaseController {
|
||||
..onTextSearchChangedAction((searchText) => _searchIdentities(searchText))
|
||||
).build();
|
||||
}
|
||||
|
||||
void handleClickCloseComposer(BuildContext context) async {
|
||||
log('ComposerController::handleClickCloseComposer:');
|
||||
if (_closeComposerButtonState == ButtonState.disabled) {
|
||||
log('ComposerController::handleClickCloseComposer: _closeComposerButtonState = disabled');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_isEmailBodyLoaded) {
|
||||
log('ComposerController::handleClickCloseComposer: _isEmailBodyLoaded = false');
|
||||
clearFocus(context);
|
||||
_closeComposerAction();
|
||||
return;
|
||||
}
|
||||
|
||||
_closeComposerButtonState = ButtonState.disabled;
|
||||
clearFocus(context);
|
||||
final draftArgs = await _handleSaveAsDrafts(context);
|
||||
_closeComposerAction(result: draftArgs);
|
||||
_closeComposerButtonState = ButtonState.enabled;
|
||||
}
|
||||
}
|
||||
@@ -37,8 +37,8 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
responsiveUtils: controller.responsiveUtils,
|
||||
mobile: MobileContainerView(
|
||||
keyboardRichTextController: controller.keyboardRichTextController,
|
||||
onCloseViewAction: () => controller.saveToDraftAndClose(context),
|
||||
onClearFocusAction: () => controller.clearFocusEditor(context),
|
||||
onCloseViewAction: () => controller.handleClickCloseComposer(context),
|
||||
onClearFocusAction: () => controller.clearFocus(context),
|
||||
onAttachFileAction: () => controller.isNetworkConnectionAvailable
|
||||
? controller.openPickAttachmentMenu(
|
||||
context,
|
||||
@@ -59,7 +59,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
if (controller.responsiveUtils.isLandscapeMobile(context))
|
||||
Obx(() => LandscapeAppBarComposerWidget(
|
||||
isSendButtonEnabled: controller.isEnableEmailSendButton.value,
|
||||
onCloseViewAction: () => controller.saveToDraftAndClose(context),
|
||||
onCloseViewAction: () => controller.handleClickCloseComposer(context),
|
||||
sendMessageAction: () => controller.validateInformationBeforeSending(context),
|
||||
openContextMenuAction: (position) {
|
||||
controller.openPopupMenuAction(
|
||||
@@ -73,7 +73,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
else
|
||||
Obx(() => AppBarComposerWidget(
|
||||
isSendButtonEnabled: controller.isEnableEmailSendButton.value,
|
||||
onCloseViewAction: () => controller.saveToDraftAndClose(context),
|
||||
onCloseViewAction: () => controller.handleClickCloseComposer(context),
|
||||
sendMessageAction: () => controller.validateInformationBeforeSending(context),
|
||||
openContextMenuAction: (position) {
|
||||
controller.openPopupMenuAction(
|
||||
@@ -222,8 +222,8 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
),
|
||||
tablet: TabletContainerView(
|
||||
keyboardRichTextController: controller.keyboardRichTextController,
|
||||
onCloseViewAction: () => controller.saveToDraftAndClose(context),
|
||||
onClearFocusAction: () => controller.clearFocusEditor(context),
|
||||
onCloseViewAction: () => controller.handleClickCloseComposer(context),
|
||||
onClearFocusAction: () => controller.clearFocus(context),
|
||||
onAttachFileAction: () => controller.isNetworkConnectionAvailable
|
||||
? controller.openPickAttachmentMenu(
|
||||
context,
|
||||
@@ -239,7 +239,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
children: [
|
||||
Obx(() => DesktopAppBarComposerWidget(
|
||||
emailSubject: controller.subjectEmail.value ?? '',
|
||||
onCloseViewAction: () => controller.saveToDraftAndClose(context),
|
||||
onCloseViewAction: () => controller.handleClickCloseComposer(context),
|
||||
constraints: constraints,
|
||||
)),
|
||||
Expanded(
|
||||
|
||||
@@ -37,7 +37,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
mobile: MobileResponsiveContainerView(
|
||||
childBuilder: (context, constraints) {
|
||||
return GestureDetector(
|
||||
onTap: () => controller.clearFocusEditor(context),
|
||||
onTap: () => controller.clearFocus(context),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -46,7 +46,7 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
isFormattingOptionsEnabled: controller.richTextWebController.isFormattingOptionsEnabled,
|
||||
openRichToolbarAction: controller.richTextWebController.toggleFormattingOptions,
|
||||
isSendButtonEnabled: controller.isEnableEmailSendButton.value,
|
||||
onCloseViewAction: () => controller.saveToDraftAndClose(context),
|
||||
onCloseViewAction: () => controller.handleClickCloseComposer(context),
|
||||
attachFileAction: () => controller.openFilePickerByType(context, FileType.any),
|
||||
insertImageAction: () => controller.insertImage(context, constraints.maxWidth),
|
||||
sendMessageAction: () => controller.validateInformationBeforeSending(context),
|
||||
@@ -231,15 +231,12 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
desktop: Obx(() => DesktopResponsiveContainerView(
|
||||
childBuilder: (context, constraints) {
|
||||
return GestureDetector(
|
||||
onTap: () => controller.clearFocusEditor(context),
|
||||
onTap: () => controller.clearFocus(context),
|
||||
child: Column(children: [
|
||||
Obx(() => DesktopAppBarComposerWidget(
|
||||
emailSubject: controller.subjectEmail.value ?? '',
|
||||
displayMode: controller.screenDisplayMode.value,
|
||||
onCloseViewAction: () {
|
||||
controller.clearFocusEditor(context);
|
||||
controller.saveToDraftAndClose(context);
|
||||
},
|
||||
onCloseViewAction: () => controller.handleClickCloseComposer(context),
|
||||
onChangeDisplayModeAction: controller.displayScreenTypeComposerAction,
|
||||
constraints: constraints,
|
||||
)),
|
||||
@@ -461,17 +458,17 @@ class ComposerView extends GetWidget<ComposerController> {
|
||||
},
|
||||
displayMode: controller.screenDisplayMode.value,
|
||||
emailSubject: controller.subjectEmail.value ?? '',
|
||||
onCloseViewAction: () => controller.saveToDraftAndClose(context),
|
||||
onCloseViewAction: () => controller.handleClickCloseComposer(context),
|
||||
onChangeDisplayModeAction: controller.displayScreenTypeComposerAction,
|
||||
)),
|
||||
tablet: TabletResponsiveContainerView(
|
||||
childBuilder: (context, constraints) {
|
||||
return GestureDetector(
|
||||
onTap: () => controller.clearFocusEditor(context),
|
||||
onTap: () => controller.clearFocus(context),
|
||||
child: Column(children: [
|
||||
Obx(() => DesktopAppBarComposerWidget(
|
||||
emailSubject: controller.subjectEmail.value ?? '',
|
||||
onCloseViewAction: () => controller.saveToDraftAndClose(context),
|
||||
onCloseViewAction: () => controller.handleClickCloseComposer(context),
|
||||
constraints: constraints,
|
||||
)),
|
||||
ConstrainedBox(
|
||||
|
||||
@@ -304,10 +304,6 @@ class UploadController extends BaseController {
|
||||
_uploadingStateInlineFiles.deleteElementByUploadTaskId(uploadId);
|
||||
}
|
||||
|
||||
void clearInlineFileUploaded() {
|
||||
_uploadingStateInlineFiles.clear();
|
||||
}
|
||||
|
||||
void _handleUploadInlineAttachmentsSuccess(SuccessAttachmentUploadState success) {
|
||||
uploadInlineViewState.value = Right(success);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user