From 1a958c97efe8728bcd942595c61d2cdc0d3f5adc Mon Sep 17 00:00:00 2001 From: dab246 Date: Fri, 16 Feb 2024 12:21:01 +0700 Subject: [PATCH] TF-2560 Clear focus when click outside input on web Signed-off-by: dab246 --- .../presentation/composer_view_web.dart | 1094 +++++++++-------- 1 file changed, 553 insertions(+), 541 deletions(-) diff --git a/lib/features/composer/presentation/composer_view_web.dart b/lib/features/composer/presentation/composer_view_web.dart index 147ce8954..22700a080 100644 --- a/lib/features/composer/presentation/composer_view_web.dart +++ b/lib/features/composer/presentation/composer_view_web.dart @@ -12,16 +12,16 @@ import 'package:tmail_ui_user/features/composer/presentation/view/web/desktop_re import 'package:tmail_ui_user/features/composer/presentation/view/web/mobile_responsive_container_view.dart'; import 'package:tmail_ui_user/features/composer/presentation/view/web/tablet_responsive_container_view.dart'; import 'package:tmail_ui_user/features/composer/presentation/view/web/web_editor_view.dart'; -import 'package:tmail_ui_user/features/composer/presentation/widgets/mobile/from_composer_mobile_widget.dart'; -import 'package:tmail_ui_user/features/composer/presentation/widgets/web/from_composer_drop_down_widget.dart'; import 'package:tmail_ui_user/features/composer/presentation/widgets/insert_image_loading_bar_widget.dart'; -import 'package:tmail_ui_user/features/composer/presentation/widgets/web/desktop_app_bar_composer_widget.dart'; -import 'package:tmail_ui_user/features/composer/presentation/widgets/web/attachment_composer_widget.dart'; -import 'package:tmail_ui_user/features/composer/presentation/widgets/web/bottom_bar_composer_widget.dart'; -import 'package:tmail_ui_user/features/composer/presentation/widgets/web/drop_zone_widget.dart'; -import 'package:tmail_ui_user/features/composer/presentation/widgets/web/mobile_responsive_app_bar_composer_widget.dart'; +import 'package:tmail_ui_user/features/composer/presentation/widgets/mobile/from_composer_mobile_widget.dart'; import 'package:tmail_ui_user/features/composer/presentation/widgets/recipient_composer_widget.dart'; import 'package:tmail_ui_user/features/composer/presentation/widgets/subject_composer_widget.dart'; +import 'package:tmail_ui_user/features/composer/presentation/widgets/web/attachment_composer_widget.dart'; +import 'package:tmail_ui_user/features/composer/presentation/widgets/web/bottom_bar_composer_widget.dart'; +import 'package:tmail_ui_user/features/composer/presentation/widgets/web/desktop_app_bar_composer_widget.dart'; +import 'package:tmail_ui_user/features/composer/presentation/widgets/web/drop_zone_widget.dart'; +import 'package:tmail_ui_user/features/composer/presentation/widgets/web/from_composer_drop_down_widget.dart'; +import 'package:tmail_ui_user/features/composer/presentation/widgets/web/mobile_responsive_app_bar_composer_widget.dart'; import 'package:tmail_ui_user/features/composer/presentation/widgets/web/toolbar_rich_text_builder.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart'; @@ -36,26 +36,214 @@ class ComposerView extends GetWidget { responsiveUtils: controller.responsiveUtils, mobile: MobileResponsiveContainerView( childBuilder: (context, constraints) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Obx(() => MobileResponsiveAppBarComposerWidget( - isCodeViewEnabled: controller.richTextWebController.codeViewEnabled, - isFormattingOptionsEnabled: controller.richTextWebController.isFormattingOptionsEnabled, - openRichToolbarAction: controller.richTextWebController.toggleFormattingOptions, - isSendButtonEnabled: controller.isEnableEmailSendButton.value, - onCloseViewAction: () => controller.saveToDraftAndClose(context), - attachFileAction: () => controller.openFilePickerByType(context, FileType.any), - insertImageAction: () => controller.insertImage(context, constraints.maxWidth), - sendMessageAction: () => controller.validateInformationBeforeSending(context), - openContextMenuAction: (position) { - controller.openPopupMenuAction( - context, - position, - _createMoreOptionPopupItems(context), - radius: ComposerStyle.popupMenuRadius - ); + return GestureDetector( + onTap: () => controller.clearFocusEditor(context), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Obx(() => MobileResponsiveAppBarComposerWidget( + isCodeViewEnabled: controller.richTextWebController.codeViewEnabled, + isFormattingOptionsEnabled: controller.richTextWebController.isFormattingOptionsEnabled, + openRichToolbarAction: controller.richTextWebController.toggleFormattingOptions, + isSendButtonEnabled: controller.isEnableEmailSendButton.value, + onCloseViewAction: () => controller.saveToDraftAndClose(context), + attachFileAction: () => controller.openFilePickerByType(context, FileType.any), + insertImageAction: () => controller.insertImage(context, constraints.maxWidth), + sendMessageAction: () => controller.validateInformationBeforeSending(context), + openContextMenuAction: (position) { + controller.openPopupMenuAction( + context, + position, + _createMoreOptionPopupItems(context), + radius: ComposerStyle.popupMenuRadius + ); + }, + )), + ConstrainedBox( + constraints: BoxConstraints( + maxHeight: ComposerStyle.getMaxHeightEmailAddressWidget( + context, + constraints, + controller.responsiveUtils + ) + ), + child: SingleChildScrollView( + controller: controller.scrollControllerEmailAddress, + child: Obx(() => Column( + children: [ + if (controller.fromRecipientState.value == PrefixRecipientState.enabled) + Tooltip( + message: controller.identitySelected.value?.email ?? '', + child: FromComposerMobileWidget( + selectedIdentity: controller.identitySelected.value, + imagePaths: controller.imagePaths, + responsiveUtils: controller.responsiveUtils, + margin: ComposerStyle.mobileRecipientMargin, + padding: ComposerStyle.mobileRecipientPadding, + onTap: () => controller.openSelectIdentityBottomSheet(context) + ), + ), + RecipientComposerWidget( + prefix: PrefixEmailAddress.to, + listEmailAddress: controller.listToEmailAddress, + fromState: controller.fromRecipientState.value, + ccState: controller.ccRecipientState.value, + bccState: controller.bccRecipientState.value, + expandMode: controller.toAddressExpandMode.value, + controller: controller.toEmailAddressController, + focusNode: controller.toAddressFocusNode, + keyTagEditor: controller.keyToEmailTagEditor, + isInitial: controller.isInitialRecipient.value, + padding: ComposerStyle.mobileRecipientPadding, + margin: ComposerStyle.mobileRecipientMargin, + nextFocusNode: controller.getNextFocusOfToEmailAddress(), + onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, + onShowFullListEmailAddressAction: controller.showFullEmailAddress, + onAddEmailAddressTypeAction: controller.addEmailAddressType, + onUpdateListEmailAddressAction: controller.updateListEmailAddress, + onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, + onFocusNextAddressAction: controller.handleFocusNextAddressAction, + onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, + ), + if (controller.ccRecipientState.value == PrefixRecipientState.enabled) + RecipientComposerWidget( + prefix: PrefixEmailAddress.cc, + listEmailAddress: controller.listCcEmailAddress, + expandMode: controller.ccAddressExpandMode.value, + controller: controller.ccEmailAddressController, + focusNode: controller.ccAddressFocusNode, + keyTagEditor: controller.keyCcEmailTagEditor, + isInitial: controller.isInitialRecipient.value, + nextFocusNode: controller.getNextFocusOfCcEmailAddress(), + padding: ComposerStyle.mobileRecipientPadding, + margin: ComposerStyle.mobileRecipientMargin, + onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, + onShowFullListEmailAddressAction: controller.showFullEmailAddress, + onDeleteEmailAddressTypeAction: controller.deleteEmailAddressType, + onUpdateListEmailAddressAction: controller.updateListEmailAddress, + onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, + onFocusNextAddressAction: controller.handleFocusNextAddressAction, + onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, + ), + if (controller.bccRecipientState.value == PrefixRecipientState.enabled) + RecipientComposerWidget( + prefix: PrefixEmailAddress.bcc, + listEmailAddress: controller.listBccEmailAddress, + expandMode: controller.bccAddressExpandMode.value, + controller: controller.bccEmailAddressController, + focusNode: controller.bccAddressFocusNode, + keyTagEditor: controller.keyBccEmailTagEditor, + isInitial: controller.isInitialRecipient.value, + nextFocusNode: controller.subjectEmailInputFocusNode, + padding: ComposerStyle.mobileRecipientPadding, + margin: ComposerStyle.mobileRecipientMargin, + onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, + onShowFullListEmailAddressAction: controller.showFullEmailAddress, + onDeleteEmailAddressTypeAction: controller.deleteEmailAddressType, + onUpdateListEmailAddressAction: controller.updateListEmailAddress, + onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, + onFocusNextAddressAction: controller.handleFocusNextAddressAction, + onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, + ), + ], + )), + ) + ), + SubjectComposerWidget( + focusNode: controller.subjectEmailInputFocusNode, + textController: controller.subjectEmailInputController, + onTextChange: controller.setSubjectEmail, + padding: ComposerStyle.mobileSubjectPadding, + margin: ComposerStyle.mobileSubjectMargin, + ), + Expanded( + child: LayoutBuilder(builder: (context, constraints) { + return Stack( + children: [ + Padding( + padding: ComposerStyle.mobileEditorPadding, + child: Obx(() => WebEditorView( + editorController: controller.richTextWebController.editorController, + arguments: controller.composerArguments.value, + contentViewState: controller.emailContentsViewState.value, + currentWebContent: controller.textEditorWeb, + onInitial: controller.handleInitHtmlEditorWeb, + onChangeContent: controller.onChangeTextEditorWeb, + onFocus: controller.handleOnFocusHtmlEditorWeb, + onUnFocus: controller.handleOnUnFocusHtmlEditorWeb, + onMouseDown: controller.handleOnMouseDownHtmlEditorWeb, + onEditorSettings: controller.richTextWebController.onEditorSettingsChange, + onImageUploadSuccessAction: (fileUpload) => controller.handleImageUploadSuccess(context, fileUpload), + onImageUploadFailureAction: (fileUpload, base64Str, uploadError) { + return controller.handleImageUploadFailure( + context: context, + uploadError: uploadError, + fileUpload: fileUpload, + base64Str: base64Str, + ); + }, + onEditorTextSizeChanged: controller.richTextWebController.onEditorTextSizeChanged, + width: constraints.maxWidth, + height: constraints.maxHeight, + )), + ), + Align( + alignment: AlignmentDirectional.topCenter, + child: Obx(() => InsertImageLoadingBarWidget( + uploadInlineViewState: controller.uploadController.uploadInlineViewState.value, + viewState: controller.viewState.value, + padding: ComposerStyle.insertImageLoadingBarPadding, + )), + ), + ], + ); + }), + ), + Obx(() { + if (controller.uploadController.listUploadAttachments.isNotEmpty) { + return AttachmentComposerWidget( + listFileUploaded: controller.uploadController.listUploadAttachments, + isCollapsed: controller.isAttachmentCollapsed, + onDeleteAttachmentAction: (fileState) => controller.deleteAttachmentUploaded(fileState.uploadTaskId), + onToggleExpandAttachmentAction: (isCollapsed) => controller.isAttachmentCollapsed = isCollapsed, + ); + } else { + return const SizedBox.shrink(); + } + }), + Obx(() { + if (controller.richTextWebController.isFormattingOptionsEnabled) { + return ToolbarRichTextWebBuilder( + richTextWebController: controller.richTextWebController, + padding: ComposerStyle.richToolbarPadding, + decoration: const BoxDecoration( + color: ComposerStyle.richToolbarColor, + boxShadow: ComposerStyle.richToolbarShadow + ), + ); + } else { + return const SizedBox.shrink(); + } + }) + ] + ), + ); + } + ), + desktop: Obx(() => DesktopResponsiveContainerView( + childBuilder: (context, constraints) { + return GestureDetector( + onTap: () => controller.clearFocusEditor(context), + child: Column(children: [ + Obx(() => DesktopAppBarComposerWidget( + emailSubject: controller.subjectEmail.value ?? '', + displayMode: controller.screenDisplayMode.value, + onCloseViewAction: () { + controller.clearFocusEditor(context); + controller.saveToDraftAndClose(context); }, + onChangeDisplayModeAction: controller.displayScreenTypeComposerAction, + constraints: constraints, )), ConstrainedBox( constraints: BoxConstraints( @@ -70,16 +258,14 @@ class ComposerView extends GetWidget { child: Obx(() => Column( children: [ if (controller.fromRecipientState.value == PrefixRecipientState.enabled) - Tooltip( - message: controller.identitySelected.value?.email ?? '', - child: FromComposerMobileWidget( - selectedIdentity: controller.identitySelected.value, - imagePaths: controller.imagePaths, - responsiveUtils: controller.responsiveUtils, - margin: ComposerStyle.mobileRecipientMargin, - padding: ComposerStyle.mobileRecipientPadding, - onTap: () => controller.openSelectIdentityBottomSheet(context) - ), + FromComposerDropDownWidget( + items: controller.listFromIdentities, + itemSelected: controller.identitySelected.value, + dropdownKey: controller.identityDropdownKey, + imagePaths: controller.imagePaths, + padding: ComposerStyle.desktopRecipientPadding, + margin: ComposerStyle.desktopRecipientMargin, + onChangeIdentity: controller.onChangeIdentity, ), RecipientComposerWidget( prefix: PrefixEmailAddress.to, @@ -92,8 +278,8 @@ class ComposerView extends GetWidget { focusNode: controller.toAddressFocusNode, keyTagEditor: controller.keyToEmailTagEditor, isInitial: controller.isInitialRecipient.value, - padding: ComposerStyle.mobileRecipientPadding, - margin: ComposerStyle.mobileRecipientMargin, + padding: ComposerStyle.desktopRecipientPadding, + margin: ComposerStyle.desktopRecipientMargin, nextFocusNode: controller.getNextFocusOfToEmailAddress(), onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, onShowFullListEmailAddressAction: controller.showFullEmailAddress, @@ -113,8 +299,8 @@ class ComposerView extends GetWidget { keyTagEditor: controller.keyCcEmailTagEditor, isInitial: controller.isInitialRecipient.value, nextFocusNode: controller.getNextFocusOfCcEmailAddress(), - padding: ComposerStyle.mobileRecipientPadding, - margin: ComposerStyle.mobileRecipientMargin, + padding: ComposerStyle.desktopRecipientPadding, + margin: ComposerStyle.desktopRecipientMargin, onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, onShowFullListEmailAddressAction: controller.showFullEmailAddress, onDeleteEmailAddressTypeAction: controller.deleteEmailAddressType, @@ -133,8 +319,8 @@ class ComposerView extends GetWidget { keyTagEditor: controller.keyBccEmailTagEditor, isInitial: controller.isInitialRecipient.value, nextFocusNode: controller.subjectEmailInputFocusNode, - padding: ComposerStyle.mobileRecipientPadding, - margin: ComposerStyle.mobileRecipientMargin, + padding: ComposerStyle.desktopRecipientPadding, + margin: ComposerStyle.desktopRecipientMargin, onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, onShowFullListEmailAddressAction: controller.showFullEmailAddress, onDeleteEmailAddressTypeAction: controller.deleteEmailAddressType, @@ -151,308 +337,131 @@ class ComposerView extends GetWidget { focusNode: controller.subjectEmailInputFocusNode, textController: controller.subjectEmailInputController, onTextChange: controller.setSubjectEmail, - padding: ComposerStyle.mobileSubjectPadding, - margin: ComposerStyle.mobileSubjectMargin, + padding: ComposerStyle.desktopSubjectPadding, + margin: ComposerStyle.desktopSubjectMargin, ), Expanded( - child: LayoutBuilder(builder: (context, constraints) { - return Stack( - children: [ - Padding( - padding: ComposerStyle.mobileEditorPadding, - child: Obx(() => WebEditorView( - editorController: controller.richTextWebController.editorController, - arguments: controller.composerArguments.value, - contentViewState: controller.emailContentsViewState.value, - currentWebContent: controller.textEditorWeb, - onInitial: controller.handleInitHtmlEditorWeb, - onChangeContent: controller.onChangeTextEditorWeb, - onFocus: controller.handleOnFocusHtmlEditorWeb, - onUnFocus: controller.handleOnUnFocusHtmlEditorWeb, - onMouseDown: controller.handleOnMouseDownHtmlEditorWeb, - onEditorSettings: controller.richTextWebController.onEditorSettingsChange, - onImageUploadSuccessAction: (fileUpload) => controller.handleImageUploadSuccess(context, fileUpload), - onImageUploadFailureAction: (fileUpload, base64Str, uploadError) { - return controller.handleImageUploadFailure( - context: context, - uploadError: uploadError, - fileUpload: fileUpload, - base64Str: base64Str, - ); - }, - onEditorTextSizeChanged: controller.richTextWebController.onEditorTextSizeChanged, - width: constraints.maxWidth, - height: constraints.maxHeight, - )), - ), - Align( - alignment: AlignmentDirectional.topCenter, - child: Obx(() => InsertImageLoadingBarWidget( - uploadInlineViewState: controller.uploadController.uploadInlineViewState.value, - viewState: controller.viewState.value, - padding: ComposerStyle.insertImageLoadingBarPadding, - )), - ), - ], - ); - }), - ), - Obx(() { - if (controller.uploadController.listUploadAttachments.isNotEmpty) { - return AttachmentComposerWidget( - listFileUploaded: controller.uploadController.listUploadAttachments, - isCollapsed: controller.isAttachmentCollapsed, - onDeleteAttachmentAction: (fileState) => controller.deleteAttachmentUploaded(fileState.uploadTaskId), - onToggleExpandAttachmentAction: (isCollapsed) => controller.isAttachmentCollapsed = isCollapsed, - ); - } else { - return const SizedBox.shrink(); - } - }), - Obx(() { - if (controller.richTextWebController.isFormattingOptionsEnabled) { - return ToolbarRichTextWebBuilder( - richTextWebController: controller.richTextWebController, - padding: ComposerStyle.richToolbarPadding, - decoration: const BoxDecoration( - color: ComposerStyle.richToolbarColor, - boxShadow: ComposerStyle.richToolbarShadow + child: Container( + decoration: const BoxDecoration( + border: Border( + bottom: BorderSide( + color: ComposerStyle.borderColor, + width: 1 + ) ), - ); - } else { - return const SizedBox.shrink(); - } - }) - ] - ); - } - ), - desktop: Obx(() => DesktopResponsiveContainerView( - childBuilder: (context, constraints) { - return Column(children: [ - Obx(() => DesktopAppBarComposerWidget( - emailSubject: controller.subjectEmail.value ?? '', - displayMode: controller.screenDisplayMode.value, - onCloseViewAction: () => controller.saveToDraftAndClose(context), - onChangeDisplayModeAction: controller.displayScreenTypeComposerAction, - constraints: constraints, - )), - ConstrainedBox( - constraints: BoxConstraints( - maxHeight: ComposerStyle.getMaxHeightEmailAddressWidget( - context, - constraints, - controller.responsiveUtils - ) - ), - child: SingleChildScrollView( - controller: controller.scrollControllerEmailAddress, - child: Obx(() => Column( - children: [ - if (controller.fromRecipientState.value == PrefixRecipientState.enabled) - FromComposerDropDownWidget( - items: controller.listFromIdentities, - itemSelected: controller.identitySelected.value, - dropdownKey: controller.identityDropdownKey, - imagePaths: controller.imagePaths, - padding: ComposerStyle.desktopRecipientPadding, - margin: ComposerStyle.desktopRecipientMargin, - onChangeIdentity: controller.onChangeIdentity, - ), - RecipientComposerWidget( - prefix: PrefixEmailAddress.to, - listEmailAddress: controller.listToEmailAddress, - fromState: controller.fromRecipientState.value, - ccState: controller.ccRecipientState.value, - bccState: controller.bccRecipientState.value, - expandMode: controller.toAddressExpandMode.value, - controller: controller.toEmailAddressController, - focusNode: controller.toAddressFocusNode, - keyTagEditor: controller.keyToEmailTagEditor, - isInitial: controller.isInitialRecipient.value, - padding: ComposerStyle.desktopRecipientPadding, - margin: ComposerStyle.desktopRecipientMargin, - nextFocusNode: controller.getNextFocusOfToEmailAddress(), - onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, - onShowFullListEmailAddressAction: controller.showFullEmailAddress, - onAddEmailAddressTypeAction: controller.addEmailAddressType, - onUpdateListEmailAddressAction: controller.updateListEmailAddress, - onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, - onFocusNextAddressAction: controller.handleFocusNextAddressAction, - onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, - ), - if (controller.ccRecipientState.value == PrefixRecipientState.enabled) - RecipientComposerWidget( - prefix: PrefixEmailAddress.cc, - listEmailAddress: controller.listCcEmailAddress, - expandMode: controller.ccAddressExpandMode.value, - controller: controller.ccEmailAddressController, - focusNode: controller.ccAddressFocusNode, - keyTagEditor: controller.keyCcEmailTagEditor, - isInitial: controller.isInitialRecipient.value, - nextFocusNode: controller.getNextFocusOfCcEmailAddress(), - padding: ComposerStyle.desktopRecipientPadding, - margin: ComposerStyle.desktopRecipientMargin, - onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, - onShowFullListEmailAddressAction: controller.showFullEmailAddress, - onDeleteEmailAddressTypeAction: controller.deleteEmailAddressType, - onUpdateListEmailAddressAction: controller.updateListEmailAddress, - onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, - onFocusNextAddressAction: controller.handleFocusNextAddressAction, - onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, - ), - if (controller.bccRecipientState.value == PrefixRecipientState.enabled) - RecipientComposerWidget( - prefix: PrefixEmailAddress.bcc, - listEmailAddress: controller.listBccEmailAddress, - expandMode: controller.bccAddressExpandMode.value, - controller: controller.bccEmailAddressController, - focusNode: controller.bccAddressFocusNode, - keyTagEditor: controller.keyBccEmailTagEditor, - isInitial: controller.isInitialRecipient.value, - nextFocusNode: controller.subjectEmailInputFocusNode, - padding: ComposerStyle.desktopRecipientPadding, - margin: ComposerStyle.desktopRecipientMargin, - onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, - onShowFullListEmailAddressAction: controller.showFullEmailAddress, - onDeleteEmailAddressTypeAction: controller.deleteEmailAddressType, - onUpdateListEmailAddressAction: controller.updateListEmailAddress, - onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, - onFocusNextAddressAction: controller.handleFocusNextAddressAction, - onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, - ), - ], - )), - ) - ), - SubjectComposerWidget( - focusNode: controller.subjectEmailInputFocusNode, - textController: controller.subjectEmailInputController, - onTextChange: controller.setSubjectEmail, - padding: ComposerStyle.desktopSubjectPadding, - margin: ComposerStyle.desktopSubjectMargin, - ), - Expanded( - child: Container( - decoration: const BoxDecoration( - border: Border( - bottom: BorderSide( - color: ComposerStyle.borderColor, - width: 1 - ) + color: ComposerStyle.backgroundEditorColor ), - color: ComposerStyle.backgroundEditorColor - ), - child: LayoutBuilder(builder: (context, constraints) { - return Stack( - children: [ - Column( - children: [ - Expanded( - child: Padding( - padding: ComposerStyle.desktopEditorPadding, - child: Obx(() { - return Stack( - children: [ - WebEditorView( - editorController: controller.richTextWebController.editorController, - arguments: controller.composerArguments.value, - contentViewState: controller.emailContentsViewState.value, - currentWebContent: controller.textEditorWeb, - onInitial: controller.handleInitHtmlEditorWeb, - onChangeContent: controller.onChangeTextEditorWeb, - onFocus: controller.handleOnFocusHtmlEditorWeb, - onUnFocus: controller.handleOnUnFocusHtmlEditorWeb, - onMouseDown: controller.handleOnMouseDownHtmlEditorWeb, - onEditorSettings: controller.richTextWebController.onEditorSettingsChange, - onImageUploadSuccessAction: (fileUpload) => controller.handleImageUploadSuccess(context, fileUpload), - onImageUploadFailureAction: (fileUpload, base64Str, uploadError) { - return controller.handleImageUploadFailure( - context: context, - uploadError: uploadError, - fileUpload: fileUpload, - base64Str: base64Str, - ); - }, - onEditorTextSizeChanged: controller.richTextWebController.onEditorTextSizeChanged, - width: constraints.maxWidth, - height: constraints.maxHeight, - ), - if (controller.mailboxDashBoardController.isDraggableAppActive) - PointerInterceptor( - child: DropZoneWidget( - width: constraints.maxWidth, - height: constraints.maxHeight, - addAttachmentFromDropZone: controller.addAttachmentFromDropZone, + child: LayoutBuilder(builder: (context, constraints) { + return Stack( + children: [ + Column( + children: [ + Expanded( + child: Padding( + padding: ComposerStyle.desktopEditorPadding, + child: Obx(() { + return Stack( + children: [ + WebEditorView( + editorController: controller.richTextWebController.editorController, + arguments: controller.composerArguments.value, + contentViewState: controller.emailContentsViewState.value, + currentWebContent: controller.textEditorWeb, + onInitial: controller.handleInitHtmlEditorWeb, + onChangeContent: controller.onChangeTextEditorWeb, + onFocus: controller.handleOnFocusHtmlEditorWeb, + onUnFocus: controller.handleOnUnFocusHtmlEditorWeb, + onMouseDown: controller.handleOnMouseDownHtmlEditorWeb, + onEditorSettings: controller.richTextWebController.onEditorSettingsChange, + onImageUploadSuccessAction: (fileUpload) => controller.handleImageUploadSuccess(context, fileUpload), + onImageUploadFailureAction: (fileUpload, base64Str, uploadError) { + return controller.handleImageUploadFailure( + context: context, + uploadError: uploadError, + fileUpload: fileUpload, + base64Str: base64Str, + ); + }, + onEditorTextSizeChanged: controller.richTextWebController.onEditorTextSizeChanged, + width: constraints.maxWidth, + height: constraints.maxHeight, + ), + if (controller.mailboxDashBoardController.isDraggableAppActive) + PointerInterceptor( + child: DropZoneWidget( + width: constraints.maxWidth, + height: constraints.maxHeight, + addAttachmentFromDropZone: controller.addAttachmentFromDropZone, + ) ) - ) - ], - ); - }), + ], + ); + }), + ), ), - ), - Obx(() { - if (controller.uploadController.listUploadAttachments.isNotEmpty) { - return AttachmentComposerWidget( - listFileUploaded: controller.uploadController.listUploadAttachments, - isCollapsed: controller.isAttachmentCollapsed, - onDeleteAttachmentAction: (fileState) => controller.deleteAttachmentUploaded(fileState.uploadTaskId), - onToggleExpandAttachmentAction: (isCollapsed) => controller.isAttachmentCollapsed = isCollapsed, - ); - } else { - return const SizedBox.shrink(); - } - }), - Obx(() { - if (controller.richTextWebController.isFormattingOptionsEnabled) { - return ToolbarRichTextWebBuilder( - richTextWebController: controller.richTextWebController, - padding: ComposerStyle.richToolbarPadding, - decoration: const BoxDecoration( - color: ComposerStyle.richToolbarColor, - boxShadow: ComposerStyle.richToolbarShadow - ), - ); - } else { - return const SizedBox.shrink(); - } - }) - ], - ), - Align( - alignment: AlignmentDirectional.topCenter, - child: Obx(() => InsertImageLoadingBarWidget( - uploadInlineViewState: controller.uploadController.uploadInlineViewState.value, - viewState: controller.viewState.value, - padding: ComposerStyle.insertImageLoadingBarPadding, - )), - ), - ], - ); - }), + Obx(() { + if (controller.uploadController.listUploadAttachments.isNotEmpty) { + return AttachmentComposerWidget( + listFileUploaded: controller.uploadController.listUploadAttachments, + isCollapsed: controller.isAttachmentCollapsed, + onDeleteAttachmentAction: (fileState) => controller.deleteAttachmentUploaded(fileState.uploadTaskId), + onToggleExpandAttachmentAction: (isCollapsed) => controller.isAttachmentCollapsed = isCollapsed, + ); + } else { + return const SizedBox.shrink(); + } + }), + Obx(() { + if (controller.richTextWebController.isFormattingOptionsEnabled) { + return ToolbarRichTextWebBuilder( + richTextWebController: controller.richTextWebController, + padding: ComposerStyle.richToolbarPadding, + decoration: const BoxDecoration( + color: ComposerStyle.richToolbarColor, + boxShadow: ComposerStyle.richToolbarShadow + ), + ); + } else { + return const SizedBox.shrink(); + } + }) + ], + ), + Align( + alignment: AlignmentDirectional.topCenter, + child: Obx(() => InsertImageLoadingBarWidget( + uploadInlineViewState: controller.uploadController.uploadInlineViewState.value, + viewState: controller.viewState.value, + padding: ComposerStyle.insertImageLoadingBarPadding, + )), + ), + ], + ); + }), + ), ), - ), - Obx(() => BottomBarComposerWidget( - isCodeViewEnabled: controller.richTextWebController.codeViewEnabled, - isFormattingOptionsEnabled: controller.richTextWebController.isFormattingOptionsEnabled, - openRichToolbarAction: controller.richTextWebController.toggleFormattingOptions, - attachFileAction: () => controller.openFilePickerByType(context, FileType.any), - insertImageAction: () => controller.insertImage(context, constraints.maxWidth), - showCodeViewAction: controller.richTextWebController.toggleCodeView, - deleteComposerAction: () => controller.closeComposer(context), - saveToDraftAction: () => controller.saveToDraftAction(context), - sendMessageAction: () => controller.validateInformationBeforeSending(context), - requestReadReceiptAction: (position) { - controller.openPopupMenuAction( - context, - position, - _createReadReceiptPopupItems(context), - radius: ComposerStyle.popupMenuRadius - ); - }, - isSending: controller.isSendEmailLoading.value, - )), - ]); + Obx(() => BottomBarComposerWidget( + isCodeViewEnabled: controller.richTextWebController.codeViewEnabled, + isFormattingOptionsEnabled: controller.richTextWebController.isFormattingOptionsEnabled, + openRichToolbarAction: controller.richTextWebController.toggleFormattingOptions, + attachFileAction: () => controller.openFilePickerByType(context, FileType.any), + insertImageAction: () => controller.insertImage(context, constraints.maxWidth), + showCodeViewAction: controller.richTextWebController.toggleCodeView, + deleteComposerAction: () => controller.closeComposer(context), + saveToDraftAction: () => controller.saveToDraftAction(context), + sendMessageAction: () => controller.validateInformationBeforeSending(context), + requestReadReceiptAction: (position) { + controller.openPopupMenuAction( + context, + position, + _createReadReceiptPopupItems(context), + radius: ComposerStyle.popupMenuRadius + ); + }, + isSending: controller.isSendEmailLoading.value, + )), + ]), + ); }, displayMode: controller.screenDisplayMode.value, emailSubject: controller.subjectEmail.value ?? '', @@ -461,213 +470,216 @@ class ComposerView extends GetWidget { )), tablet: TabletResponsiveContainerView( childBuilder: (context, constraints) { - return Column(children: [ - Obx(() => DesktopAppBarComposerWidget( - emailSubject: controller.subjectEmail.value ?? '', - onCloseViewAction: () => controller.saveToDraftAndClose(context), - constraints: constraints, - )), - ConstrainedBox( - constraints: BoxConstraints( - maxHeight: ComposerStyle.getMaxHeightEmailAddressWidget( - context, - constraints, - controller.responsiveUtils + return GestureDetector( + onTap: () => controller.clearFocusEditor(context), + child: Column(children: [ + Obx(() => DesktopAppBarComposerWidget( + emailSubject: controller.subjectEmail.value ?? '', + onCloseViewAction: () => controller.saveToDraftAndClose(context), + constraints: constraints, + )), + ConstrainedBox( + constraints: BoxConstraints( + maxHeight: ComposerStyle.getMaxHeightEmailAddressWidget( + context, + constraints, + controller.responsiveUtils + ) + ), + child: SingleChildScrollView( + controller: controller.scrollControllerEmailAddress, + child: Obx(() => Column( + children: [ + if (controller.fromRecipientState.value == PrefixRecipientState.enabled) + FromComposerDropDownWidget( + items: controller.listFromIdentities, + itemSelected: controller.identitySelected.value, + dropdownKey: controller.identityDropdownKey, + imagePaths: controller.imagePaths, + padding: ComposerStyle.tabletRecipientPadding, + margin: ComposerStyle.tabletRecipientMargin, + onChangeIdentity: controller.onChangeIdentity, + ), + RecipientComposerWidget( + prefix: PrefixEmailAddress.to, + listEmailAddress: controller.listToEmailAddress, + fromState: controller.fromRecipientState.value, + ccState: controller.ccRecipientState.value, + bccState: controller.bccRecipientState.value, + expandMode: controller.toAddressExpandMode.value, + controller: controller.toEmailAddressController, + focusNode: controller.toAddressFocusNode, + keyTagEditor: controller.keyToEmailTagEditor, + isInitial: controller.isInitialRecipient.value, + padding: ComposerStyle.tabletRecipientPadding, + margin: ComposerStyle.tabletRecipientMargin, + nextFocusNode: controller.getNextFocusOfToEmailAddress(), + onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, + onShowFullListEmailAddressAction: controller.showFullEmailAddress, + onAddEmailAddressTypeAction: controller.addEmailAddressType, + onUpdateListEmailAddressAction: controller.updateListEmailAddress, + onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, + onFocusNextAddressAction: controller.handleFocusNextAddressAction, + onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, + ), + if (controller.ccRecipientState.value == PrefixRecipientState.enabled) + RecipientComposerWidget( + prefix: PrefixEmailAddress.cc, + listEmailAddress: controller.listCcEmailAddress, + expandMode: controller.ccAddressExpandMode.value, + controller: controller.ccEmailAddressController, + focusNode: controller.ccAddressFocusNode, + keyTagEditor: controller.keyCcEmailTagEditor, + isInitial: controller.isInitialRecipient.value, + nextFocusNode: controller.getNextFocusOfCcEmailAddress(), + padding: ComposerStyle.tabletRecipientPadding, + margin: ComposerStyle.tabletRecipientMargin, + onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, + onShowFullListEmailAddressAction: controller.showFullEmailAddress, + onDeleteEmailAddressTypeAction: controller.deleteEmailAddressType, + onUpdateListEmailAddressAction: controller.updateListEmailAddress, + onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, + onFocusNextAddressAction: controller.handleFocusNextAddressAction, + onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, + ), + if (controller.bccRecipientState.value == PrefixRecipientState.enabled) + RecipientComposerWidget( + prefix: PrefixEmailAddress.bcc, + listEmailAddress: controller.listBccEmailAddress, + expandMode: controller.bccAddressExpandMode.value, + controller: controller.bccEmailAddressController, + focusNode: controller.bccAddressFocusNode, + keyTagEditor: controller.keyBccEmailTagEditor, + isInitial: controller.isInitialRecipient.value, + nextFocusNode: controller.subjectEmailInputFocusNode, + padding: ComposerStyle.tabletRecipientPadding, + margin: ComposerStyle.tabletRecipientMargin, + onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, + onShowFullListEmailAddressAction: controller.showFullEmailAddress, + onDeleteEmailAddressTypeAction: controller.deleteEmailAddressType, + onUpdateListEmailAddressAction: controller.updateListEmailAddress, + onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, + onFocusNextAddressAction: controller.handleFocusNextAddressAction, + onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, + ), + ], + )), ) ), - child: SingleChildScrollView( - controller: controller.scrollControllerEmailAddress, - child: Obx(() => Column( - children: [ - if (controller.fromRecipientState.value == PrefixRecipientState.enabled) - FromComposerDropDownWidget( - items: controller.listFromIdentities, - itemSelected: controller.identitySelected.value, - dropdownKey: controller.identityDropdownKey, - imagePaths: controller.imagePaths, - padding: ComposerStyle.tabletRecipientPadding, - margin: ComposerStyle.tabletRecipientMargin, - onChangeIdentity: controller.onChangeIdentity, - ), - RecipientComposerWidget( - prefix: PrefixEmailAddress.to, - listEmailAddress: controller.listToEmailAddress, - fromState: controller.fromRecipientState.value, - ccState: controller.ccRecipientState.value, - bccState: controller.bccRecipientState.value, - expandMode: controller.toAddressExpandMode.value, - controller: controller.toEmailAddressController, - focusNode: controller.toAddressFocusNode, - keyTagEditor: controller.keyToEmailTagEditor, - isInitial: controller.isInitialRecipient.value, - padding: ComposerStyle.tabletRecipientPadding, - margin: ComposerStyle.tabletRecipientMargin, - nextFocusNode: controller.getNextFocusOfToEmailAddress(), - onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, - onShowFullListEmailAddressAction: controller.showFullEmailAddress, - onAddEmailAddressTypeAction: controller.addEmailAddressType, - onUpdateListEmailAddressAction: controller.updateListEmailAddress, - onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, - onFocusNextAddressAction: controller.handleFocusNextAddressAction, - onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, - ), - if (controller.ccRecipientState.value == PrefixRecipientState.enabled) - RecipientComposerWidget( - prefix: PrefixEmailAddress.cc, - listEmailAddress: controller.listCcEmailAddress, - expandMode: controller.ccAddressExpandMode.value, - controller: controller.ccEmailAddressController, - focusNode: controller.ccAddressFocusNode, - keyTagEditor: controller.keyCcEmailTagEditor, - isInitial: controller.isInitialRecipient.value, - nextFocusNode: controller.getNextFocusOfCcEmailAddress(), - padding: ComposerStyle.tabletRecipientPadding, - margin: ComposerStyle.tabletRecipientMargin, - onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, - onShowFullListEmailAddressAction: controller.showFullEmailAddress, - onDeleteEmailAddressTypeAction: controller.deleteEmailAddressType, - onUpdateListEmailAddressAction: controller.updateListEmailAddress, - onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, - onFocusNextAddressAction: controller.handleFocusNextAddressAction, - onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, - ), - if (controller.bccRecipientState.value == PrefixRecipientState.enabled) - RecipientComposerWidget( - prefix: PrefixEmailAddress.bcc, - listEmailAddress: controller.listBccEmailAddress, - expandMode: controller.bccAddressExpandMode.value, - controller: controller.bccEmailAddressController, - focusNode: controller.bccAddressFocusNode, - keyTagEditor: controller.keyBccEmailTagEditor, - isInitial: controller.isInitialRecipient.value, - nextFocusNode: controller.subjectEmailInputFocusNode, - padding: ComposerStyle.tabletRecipientPadding, - margin: ComposerStyle.tabletRecipientMargin, - onFocusEmailAddressChangeAction: controller.onEmailAddressFocusChange, - onShowFullListEmailAddressAction: controller.showFullEmailAddress, - onDeleteEmailAddressTypeAction: controller.deleteEmailAddressType, - onUpdateListEmailAddressAction: controller.updateListEmailAddress, - onSuggestionEmailAddress: controller.getAutoCompleteSuggestion, - onFocusNextAddressAction: controller.handleFocusNextAddressAction, - onRemoveDraggableEmailAddressAction: controller.removeDraggableEmailAddress, - ), - ], - )), - ) - ), - SubjectComposerWidget( - focusNode: controller.subjectEmailInputFocusNode, - textController: controller.subjectEmailInputController, - onTextChange: controller.setSubjectEmail, - padding: ComposerStyle.tabletSubjectPadding, - margin: ComposerStyle.tabletSubjectMargin, - ), - Expanded( - child: Container( - decoration: const BoxDecoration( - border: Border( - bottom: BorderSide( - color: ComposerStyle.borderColor, - width: 1 - ) - ), - color: ComposerStyle.backgroundEditorColor - ), - child: LayoutBuilder(builder: (context, constraints) { - return Stack( - children: [ - Column( - children: [ - Expanded( - child: Padding( - padding: ComposerStyle.tabletEditorPadding, - child: Obx(() => WebEditorView( - editorController: controller.richTextWebController.editorController, - arguments: controller.composerArguments.value, - contentViewState: controller.emailContentsViewState.value, - currentWebContent: controller.textEditorWeb, - onInitial: controller.handleInitHtmlEditorWeb, - onChangeContent: controller.onChangeTextEditorWeb, - onFocus: controller.handleOnFocusHtmlEditorWeb, - onUnFocus: controller.handleOnUnFocusHtmlEditorWeb, - onMouseDown: controller.handleOnMouseDownHtmlEditorWeb, - onEditorSettings: controller.richTextWebController.onEditorSettingsChange, - onImageUploadSuccessAction: (fileUpload) => controller.handleImageUploadSuccess(context, fileUpload), - onImageUploadFailureAction: (fileUpload, base64Str, uploadError) { - return controller.handleImageUploadFailure( - context: context, - uploadError: uploadError, - fileUpload: fileUpload, - base64Str: base64Str, - ); - }, - onEditorTextSizeChanged: controller.richTextWebController.onEditorTextSizeChanged, - width: constraints.maxWidth, - height: constraints.maxHeight, - )), - ), - ), - Obx(() { - if (controller.uploadController.listUploadAttachments.isNotEmpty) { - return AttachmentComposerWidget( - listFileUploaded: controller.uploadController.listUploadAttachments, - isCollapsed: controller.isAttachmentCollapsed, - onDeleteAttachmentAction: (fileState) => controller.deleteAttachmentUploaded(fileState.uploadTaskId), - onToggleExpandAttachmentAction: (isCollapsed) => controller.isAttachmentCollapsed = isCollapsed, - ); - } else { - return const SizedBox.shrink(); - } - }), - Obx(() { - if (controller.richTextWebController.isFormattingOptionsEnabled) { - return ToolbarRichTextWebBuilder( - richTextWebController: controller.richTextWebController, - padding: ComposerStyle.richToolbarPadding, - decoration: const BoxDecoration( - color: ComposerStyle.richToolbarColor, - boxShadow: ComposerStyle.richToolbarShadow - ), - ); - } else { - return const SizedBox.shrink(); - } - }) - ], - ), - Align( - alignment: AlignmentDirectional.topCenter, - child: Obx(() => InsertImageLoadingBarWidget( - uploadInlineViewState: controller.uploadController.uploadInlineViewState.value, - viewState: controller.viewState.value, - padding: ComposerStyle.insertImageLoadingBarPadding, - )), - ), - ], - ); - }), + SubjectComposerWidget( + focusNode: controller.subjectEmailInputFocusNode, + textController: controller.subjectEmailInputController, + onTextChange: controller.setSubjectEmail, + padding: ComposerStyle.tabletSubjectPadding, + margin: ComposerStyle.tabletSubjectMargin, ), - ), - Obx(() => BottomBarComposerWidget( - isCodeViewEnabled: controller.richTextWebController.codeViewEnabled, - isFormattingOptionsEnabled: controller.richTextWebController.isFormattingOptionsEnabled, - openRichToolbarAction: controller.richTextWebController.toggleFormattingOptions, - attachFileAction: () => controller.openFilePickerByType(context, FileType.any), - insertImageAction: () => controller.insertImage(context, constraints.maxWidth), - showCodeViewAction: controller.richTextWebController.toggleCodeView, - deleteComposerAction: () => controller.closeComposer(context), - saveToDraftAction: () => controller.saveToDraftAction(context), - sendMessageAction: () => controller.validateInformationBeforeSending(context), - requestReadReceiptAction: (position) { - controller.openPopupMenuAction( - context, - position, - _createReadReceiptPopupItems(context), - radius: ComposerStyle.popupMenuRadius - ); - }, - )), - ]); + Expanded( + child: Container( + decoration: const BoxDecoration( + border: Border( + bottom: BorderSide( + color: ComposerStyle.borderColor, + width: 1 + ) + ), + color: ComposerStyle.backgroundEditorColor + ), + child: LayoutBuilder(builder: (context, constraints) { + return Stack( + children: [ + Column( + children: [ + Expanded( + child: Padding( + padding: ComposerStyle.tabletEditorPadding, + child: Obx(() => WebEditorView( + editorController: controller.richTextWebController.editorController, + arguments: controller.composerArguments.value, + contentViewState: controller.emailContentsViewState.value, + currentWebContent: controller.textEditorWeb, + onInitial: controller.handleInitHtmlEditorWeb, + onChangeContent: controller.onChangeTextEditorWeb, + onFocus: controller.handleOnFocusHtmlEditorWeb, + onUnFocus: controller.handleOnUnFocusHtmlEditorWeb, + onMouseDown: controller.handleOnMouseDownHtmlEditorWeb, + onEditorSettings: controller.richTextWebController.onEditorSettingsChange, + onImageUploadSuccessAction: (fileUpload) => controller.handleImageUploadSuccess(context, fileUpload), + onImageUploadFailureAction: (fileUpload, base64Str, uploadError) { + return controller.handleImageUploadFailure( + context: context, + uploadError: uploadError, + fileUpload: fileUpload, + base64Str: base64Str, + ); + }, + onEditorTextSizeChanged: controller.richTextWebController.onEditorTextSizeChanged, + width: constraints.maxWidth, + height: constraints.maxHeight, + )), + ), + ), + Obx(() { + if (controller.uploadController.listUploadAttachments.isNotEmpty) { + return AttachmentComposerWidget( + listFileUploaded: controller.uploadController.listUploadAttachments, + isCollapsed: controller.isAttachmentCollapsed, + onDeleteAttachmentAction: (fileState) => controller.deleteAttachmentUploaded(fileState.uploadTaskId), + onToggleExpandAttachmentAction: (isCollapsed) => controller.isAttachmentCollapsed = isCollapsed, + ); + } else { + return const SizedBox.shrink(); + } + }), + Obx(() { + if (controller.richTextWebController.isFormattingOptionsEnabled) { + return ToolbarRichTextWebBuilder( + richTextWebController: controller.richTextWebController, + padding: ComposerStyle.richToolbarPadding, + decoration: const BoxDecoration( + color: ComposerStyle.richToolbarColor, + boxShadow: ComposerStyle.richToolbarShadow + ), + ); + } else { + return const SizedBox.shrink(); + } + }) + ], + ), + Align( + alignment: AlignmentDirectional.topCenter, + child: Obx(() => InsertImageLoadingBarWidget( + uploadInlineViewState: controller.uploadController.uploadInlineViewState.value, + viewState: controller.viewState.value, + padding: ComposerStyle.insertImageLoadingBarPadding, + )), + ), + ], + ); + }), + ), + ), + Obx(() => BottomBarComposerWidget( + isCodeViewEnabled: controller.richTextWebController.codeViewEnabled, + isFormattingOptionsEnabled: controller.richTextWebController.isFormattingOptionsEnabled, + openRichToolbarAction: controller.richTextWebController.toggleFormattingOptions, + attachFileAction: () => controller.openFilePickerByType(context, FileType.any), + insertImageAction: () => controller.insertImage(context, constraints.maxWidth), + showCodeViewAction: controller.richTextWebController.toggleCodeView, + deleteComposerAction: () => controller.closeComposer(context), + saveToDraftAction: () => controller.saveToDraftAction(context), + sendMessageAction: () => controller.validateInformationBeforeSending(context), + requestReadReceiptAction: (position) { + controller.openPopupMenuAction( + context, + position, + _createReadReceiptPopupItems(context), + radius: ComposerStyle.popupMenuRadius + ); + }, + )), + ]), + ); }, ) );