TF-2989 Fix drag and drop text within composer is broken
This commit is contained in:
@@ -385,22 +385,42 @@ class ComposerController extends BaseController with DragDropFileMixin implement
|
|||||||
});
|
});
|
||||||
|
|
||||||
_subscriptionOnDragEnter = html.window.onDragEnter.listen((event) {
|
_subscriptionOnDragEnter = html.window.onDragEnter.listen((event) {
|
||||||
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.active;
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (_validateFilesTransfer(event.dataTransfer.types)) {
|
||||||
|
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.active;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_subscriptionOnDragOver = html.window.onDragOver.listen((event) {
|
_subscriptionOnDragOver = html.window.onDragOver.listen((event) {
|
||||||
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.active;
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (_validateFilesTransfer(event.dataTransfer.types)) {
|
||||||
|
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.active;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_subscriptionOnDragLeave = html.window.onDragLeave.listen((event) {
|
_subscriptionOnDragLeave = html.window.onDragLeave.listen((event) {
|
||||||
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.inActive;
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (_validateFilesTransfer(event.dataTransfer.types)) {
|
||||||
|
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.inActive;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_subscriptionOnDrop = html.window.onDrop.listen((event) {
|
_subscriptionOnDrop = html.window.onDrop.listen((event) {
|
||||||
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.inActive;
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (_validateFilesTransfer(event.dataTransfer.types)) {
|
||||||
|
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.inActive;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _validateFilesTransfer(List<dynamic>? types) {
|
||||||
|
return types?.any((type) => type == 'Files') ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _saveComposerCacheOnWebAction() async {
|
Future<void> _saveComposerCacheOnWebAction() async {
|
||||||
_autoCreateEmailTag();
|
_autoCreateEmailTag();
|
||||||
|
|
||||||
@@ -2091,8 +2111,10 @@ class ComposerController extends BaseController with DragDropFileMixin implement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleOnDragEnterHtmlEditorWeb() {
|
void handleOnDragEnterHtmlEditorWeb(List<dynamic>? types) {
|
||||||
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.active;
|
if (_validateFilesTransfer(types)) {
|
||||||
|
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.active;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onLocalFileDropZoneListener({
|
void onLocalFileDropZoneListener({
|
||||||
|
|||||||
@@ -653,133 +653,139 @@ class ComposerView extends GetWidget<ComposerController> {
|
|||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: LayoutBuilder(
|
child: LayoutBuilder(
|
||||||
builder: (context, constraintsEditor) {
|
builder: (context, constraintsBody) {
|
||||||
return Container(
|
return Stack(
|
||||||
decoration: const BoxDecoration(
|
children: [
|
||||||
border: Border(
|
Column(
|
||||||
bottom: BorderSide(
|
children: [
|
||||||
color: ComposerStyle.borderColor,
|
Expanded(
|
||||||
width: 1
|
child: Container(
|
||||||
)
|
decoration: const BoxDecoration(
|
||||||
),
|
border: Border(
|
||||||
color: ComposerStyle.backgroundEditorColor
|
bottom: BorderSide(
|
||||||
),
|
color: ComposerStyle.borderColor,
|
||||||
child: Stack(
|
width: 1
|
||||||
children: [
|
)
|
||||||
Column(
|
),
|
||||||
children: [
|
color: ComposerStyle.backgroundEditorColor
|
||||||
Expanded(
|
),
|
||||||
child: Padding(
|
child: Column(
|
||||||
padding: ComposerStyle.tabletEditorPadding,
|
children: [
|
||||||
child: Obx(() => WebEditorView(
|
Expanded(
|
||||||
editorController: controller.richTextWebController!.editorController,
|
child: Padding(
|
||||||
arguments: controller.composerArguments.value,
|
padding: ComposerStyle.tabletEditorPadding,
|
||||||
contentViewState: controller.emailContentsViewState.value,
|
child: Obx(() => WebEditorView(
|
||||||
currentWebContent: controller.textEditorWeb,
|
editorController: controller.richTextWebController!.editorController,
|
||||||
onInitial: controller.handleInitHtmlEditorWeb,
|
arguments: controller.composerArguments.value,
|
||||||
onChangeContent: controller.onChangeTextEditorWeb,
|
contentViewState: controller.emailContentsViewState.value,
|
||||||
onFocus: controller.handleOnFocusHtmlEditorWeb,
|
currentWebContent: controller.textEditorWeb,
|
||||||
onMouseDown: controller.handleOnMouseDownHtmlEditorWeb,
|
onInitial: controller.handleInitHtmlEditorWeb,
|
||||||
onEditorSettings: controller.richTextWebController!.onEditorSettingsChange,
|
onChangeContent: controller.onChangeTextEditorWeb,
|
||||||
onEditorTextSizeChanged: controller.richTextWebController!.onEditorTextSizeChanged,
|
onFocus: controller.handleOnFocusHtmlEditorWeb,
|
||||||
width: constraints.maxWidth,
|
onMouseDown: controller.handleOnMouseDownHtmlEditorWeb,
|
||||||
height: constraints.maxHeight,
|
onEditorSettings: controller.richTextWebController!.onEditorSettingsChange,
|
||||||
onDragEnter: controller.handleOnDragEnterHtmlEditorWeb,
|
onEditorTextSizeChanged: controller.richTextWebController!.onEditorTextSizeChanged,
|
||||||
)),
|
width: constraints.maxWidth,
|
||||||
|
height: constraints.maxHeight,
|
||||||
|
onDragEnter: controller.handleOnDragEnterHtmlEditorWeb,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Obx(() {
|
||||||
|
if (controller.uploadController.listUploadAttachments.isNotEmpty) {
|
||||||
|
return AttachmentComposerWidget(
|
||||||
|
listFileUploaded: controller.uploadController.listUploadAttachments,
|
||||||
|
isCollapsed: controller.isAttachmentCollapsed,
|
||||||
|
onDeleteAttachmentAction: controller.deleteAttachmentUploaded,
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Obx(() {
|
),
|
||||||
if (controller.uploadController.listUploadAttachments.isNotEmpty) {
|
Obx(() => BottomBarComposerWidget(
|
||||||
return AttachmentComposerWidget(
|
isCodeViewEnabled: controller.richTextWebController!.codeViewEnabled,
|
||||||
listFileUploaded: controller.uploadController.listUploadAttachments,
|
isFormattingOptionsEnabled: controller.richTextWebController!.isFormattingOptionsEnabled,
|
||||||
isCollapsed: controller.isAttachmentCollapsed,
|
hasReadReceipt: controller.hasRequestReadReceipt.value,
|
||||||
onDeleteAttachmentAction: controller.deleteAttachmentUploaded,
|
openRichToolbarAction: controller.richTextWebController!.toggleFormattingOptions,
|
||||||
onToggleExpandAttachmentAction: (isCollapsed) => controller.isAttachmentCollapsed = isCollapsed,
|
attachFileAction: () => controller.openFilePickerByType(context, FileType.any),
|
||||||
);
|
insertImageAction: () => controller.insertImage(context, constraints.maxWidth),
|
||||||
} else {
|
showCodeViewAction: controller.richTextWebController!.toggleCodeView,
|
||||||
return const SizedBox.shrink();
|
deleteComposerAction: () => controller.handleClickDeleteComposer(context),
|
||||||
}
|
saveToDraftAction: () => controller.handleClickSaveAsDraftsButton(context),
|
||||||
}),
|
sendMessageAction: () => controller.handleClickSendButton(context),
|
||||||
Obx(() {
|
requestReadReceiptAction: () => controller.toggleRequestReadReceipt(context),
|
||||||
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.mailboxDashBoardController.isAttachmentDraggableAppActive) {
|
Align(
|
||||||
return Positioned.fill(
|
alignment: AlignmentDirectional.topCenter,
|
||||||
child: PointerInterceptor(
|
child: Obx(() => InsertImageLoadingBarWidget(
|
||||||
child: AttachmentDropZoneWidget(
|
uploadInlineViewState: controller.uploadController.uploadInlineViewState.value,
|
||||||
imagePaths: controller.imagePaths,
|
viewState: controller.viewState.value,
|
||||||
width: constraintsEditor.maxWidth,
|
padding: ComposerStyle.insertImageLoadingBarPadding,
|
||||||
height: constraintsEditor.maxHeight,
|
)),
|
||||||
onAttachmentDropZoneListener: controller.onAttachmentDropZoneListener,
|
),
|
||||||
)
|
Obx(() {
|
||||||
),
|
if (controller.mailboxDashBoardController.isAttachmentDraggableAppActive) {
|
||||||
);
|
return Positioned.fill(
|
||||||
} else {
|
child: PointerInterceptor(
|
||||||
return const SizedBox.shrink();
|
child: AttachmentDropZoneWidget(
|
||||||
}
|
imagePaths: controller.imagePaths,
|
||||||
}),
|
width: constraintsBody.maxWidth,
|
||||||
Obx(() {
|
height: constraintsBody.maxHeight,
|
||||||
if (controller.mailboxDashBoardController.isLocalFileDraggableAppActive) {
|
onAttachmentDropZoneListener: controller.onAttachmentDropZoneListener,
|
||||||
return Positioned.fill(
|
)
|
||||||
child: PointerInterceptor(
|
),
|
||||||
child: LocalFileDropZoneWidget(
|
);
|
||||||
imagePaths: controller.imagePaths,
|
} else {
|
||||||
width: constraintsEditor.maxWidth,
|
return const SizedBox.shrink();
|
||||||
height: constraintsEditor.maxHeight,
|
}
|
||||||
onLocalFileDropZoneListener: (details) =>
|
}),
|
||||||
controller.onLocalFileDropZoneListener(
|
Obx(() {
|
||||||
context: context,
|
if (controller.mailboxDashBoardController.isLocalFileDraggableAppActive) {
|
||||||
details: details,
|
return Positioned.fill(
|
||||||
maxWidth: constraintsEditor.maxWidth,
|
child: PointerInterceptor(
|
||||||
),
|
child: LocalFileDropZoneWidget(
|
||||||
)
|
imagePaths: controller.imagePaths,
|
||||||
),
|
width: constraintsBody.maxWidth,
|
||||||
);
|
height: constraintsBody.maxHeight,
|
||||||
} else {
|
onLocalFileDropZoneListener: (details) =>
|
||||||
return const SizedBox.shrink();
|
controller.onLocalFileDropZoneListener(
|
||||||
}
|
context: context,
|
||||||
}),
|
details: details,
|
||||||
],
|
maxWidth: constraintsBody.maxWidth,
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
Obx(() => BottomBarComposerWidget(
|
|
||||||
isCodeViewEnabled: controller.richTextWebController!.codeViewEnabled,
|
|
||||||
isFormattingOptionsEnabled: controller.richTextWebController!.isFormattingOptionsEnabled,
|
|
||||||
hasReadReceipt: controller.hasRequestReadReceipt.value,
|
|
||||||
openRichToolbarAction: controller.richTextWebController!.toggleFormattingOptions,
|
|
||||||
attachFileAction: () => controller.openFilePickerByType(context, FileType.any),
|
|
||||||
insertImageAction: () => controller.insertImage(context, constraints.maxWidth),
|
|
||||||
showCodeViewAction: controller.richTextWebController!.toggleCodeView,
|
|
||||||
deleteComposerAction: () => controller.handleClickDeleteComposer(context),
|
|
||||||
saveToDraftAction: () => controller.handleClickSaveAsDraftsButton(context),
|
|
||||||
sendMessageAction: () => controller.handleClickSendButton(context),
|
|
||||||
requestReadReceiptAction: () => controller.toggleRequestReadReceipt(context),
|
|
||||||
)),
|
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import 'package:tmail_ui_user/features/email/domain/state/transform_html_email_c
|
|||||||
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
|
import 'package:tmail_ui_user/features/email/presentation/model/composer_arguments.dart';
|
||||||
import 'package:tmail_ui_user/main/utils/app_utils.dart';
|
import 'package:tmail_ui_user/main/utils/app_utils.dart';
|
||||||
|
|
||||||
|
typedef OnDragEnterListener = Function(List<dynamic>? types);
|
||||||
|
|
||||||
class WebEditorView extends StatelessWidget with EditorViewMixin {
|
class WebEditorView extends StatelessWidget with EditorViewMixin {
|
||||||
|
|
||||||
final HtmlEditorController editorController;
|
final HtmlEditorController editorController;
|
||||||
@@ -29,7 +31,7 @@ class WebEditorView extends StatelessWidget with EditorViewMixin {
|
|||||||
final OnEditorTextSizeChanged? onEditorTextSizeChanged;
|
final OnEditorTextSizeChanged? onEditorTextSizeChanged;
|
||||||
final double? width;
|
final double? width;
|
||||||
final double? height;
|
final double? height;
|
||||||
final VoidCallback? onDragEnter;
|
final OnDragEnterListener? onDragEnter;
|
||||||
|
|
||||||
const WebEditorView({
|
const WebEditorView({
|
||||||
super.key,
|
super.key,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:core/utils/app_logger.dart';
|
|||||||
import 'package:core/utils/html/html_utils.dart';
|
import 'package:core/utils/html/html_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:html_editor_enhanced/html_editor.dart';
|
import 'package:html_editor_enhanced/html_editor.dart';
|
||||||
|
import 'package:tmail_ui_user/features/composer/presentation/view/web/web_editor_view.dart';
|
||||||
import 'package:universal_html/html.dart' hide VoidCallback;
|
import 'package:universal_html/html.dart' hide VoidCallback;
|
||||||
|
|
||||||
typedef OnChangeContentEditorAction = Function(String? text);
|
typedef OnChangeContentEditorAction = Function(String? text);
|
||||||
@@ -27,7 +28,7 @@ class WebEditorWidget extends StatefulWidget {
|
|||||||
final OnEditorTextSizeChanged? onEditorTextSizeChanged;
|
final OnEditorTextSizeChanged? onEditorTextSizeChanged;
|
||||||
final double? width;
|
final double? width;
|
||||||
final double? height;
|
final double? height;
|
||||||
final VoidCallback? onDragEnter;
|
final OnDragEnterListener? onDragEnter;
|
||||||
|
|
||||||
const WebEditorWidget({
|
const WebEditorWidget({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -63,8 +64,6 @@ class _WebEditorState extends State<WebEditorWidget> {
|
|||||||
bool _dropListenerRegistered = false;
|
bool _dropListenerRegistered = false;
|
||||||
Function(Event)? _dropListener;
|
Function(Event)? _dropListener;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@@ -175,7 +174,7 @@ class _WebEditorState extends State<WebEditorWidget> {
|
|||||||
HtmlUtils.lineHeight100Percent.name
|
HtmlUtils.lineHeight100Percent.name
|
||||||
),
|
),
|
||||||
onDragEnter: widget.onDragEnter,
|
onDragEnter: widget.onDragEnter,
|
||||||
onDragLeave: () {},
|
onDragLeave: (_) {},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user