TF-2989 Fix drag and drop text within composer is broken

This commit is contained in:
dab246
2024-07-12 17:46:58 +07:00
committed by Dat H. Pham
parent 01561e3167
commit 34cbb155bd
4 changed files with 162 additions and 133 deletions
@@ -385,22 +385,42 @@ class ComposerController extends BaseController with DragDropFileMixin implement
}); });
_subscriptionOnDragEnter = html.window.onDragEnter.listen((event) { _subscriptionOnDragEnter = html.window.onDragEnter.listen((event) {
event.preventDefault();
if (_validateFilesTransfer(event.dataTransfer.types)) {
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.active; mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.active;
}
}); });
_subscriptionOnDragOver = html.window.onDragOver.listen((event) { _subscriptionOnDragOver = html.window.onDragOver.listen((event) {
event.preventDefault();
if (_validateFilesTransfer(event.dataTransfer.types)) {
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.active; mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.active;
}
}); });
_subscriptionOnDragLeave = html.window.onDragLeave.listen((event) { _subscriptionOnDragLeave = html.window.onDragLeave.listen((event) {
event.preventDefault();
if (_validateFilesTransfer(event.dataTransfer.types)) {
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.inActive; mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.inActive;
}
}); });
_subscriptionOnDrop = html.window.onDrop.listen((event) { _subscriptionOnDrop = html.window.onDrop.listen((event) {
event.preventDefault();
if (_validateFilesTransfer(event.dataTransfer.types)) {
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.inActive; 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,9 +2111,11 @@ class ComposerController extends BaseController with DragDropFileMixin implement
} }
} }
void handleOnDragEnterHtmlEditorWeb() { void handleOnDragEnterHtmlEditorWeb(List<dynamic>? types) {
if (_validateFilesTransfer(types)) {
mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.active; mailboxDashBoardController.localFileDraggableAppState.value = DraggableAppState.active;
} }
}
void onLocalFileDropZoneListener({ void onLocalFileDropZoneListener({
required BuildContext context, required BuildContext context,
@@ -653,8 +653,13 @@ class ComposerView extends GetWidget<ComposerController> {
), ),
Expanded( Expanded(
child: LayoutBuilder( child: LayoutBuilder(
builder: (context, constraintsEditor) { builder: (context, constraintsBody) {
return Container( return Stack(
children: [
Column(
children: [
Expanded(
child: Container(
decoration: const BoxDecoration( decoration: const BoxDecoration(
border: Border( border: Border(
bottom: BorderSide( bottom: BorderSide(
@@ -664,9 +669,7 @@ class ComposerView extends GetWidget<ComposerController> {
), ),
color: ComposerStyle.backgroundEditorColor color: ComposerStyle.backgroundEditorColor
), ),
child: Stack( child: Column(
children: [
Column(
children: [ children: [
Expanded( Expanded(
child: Padding( child: Padding(
@@ -716,55 +719,6 @@ class ComposerView extends GetWidget<ComposerController> {
}) })
], ],
), ),
Align(
alignment: AlignmentDirectional.topCenter,
child: Obx(() => InsertImageLoadingBarWidget(
uploadInlineViewState: controller.uploadController.uploadInlineViewState.value,
viewState: controller.viewState.value,
padding: ComposerStyle.insertImageLoadingBarPadding,
)),
),
Obx(() {
if (controller.mailboxDashBoardController.isAttachmentDraggableAppActive) {
return Positioned.fill(
child: PointerInterceptor(
child: AttachmentDropZoneWidget(
imagePaths: controller.imagePaths,
width: constraintsEditor.maxWidth,
height: constraintsEditor.maxHeight,
onAttachmentDropZoneListener: controller.onAttachmentDropZoneListener,
)
),
);
} else {
return const SizedBox.shrink();
}
}),
Obx(() {
if (controller.mailboxDashBoardController.isLocalFileDraggableAppActive) {
return Positioned.fill(
child: PointerInterceptor(
child: LocalFileDropZoneWidget(
imagePaths: controller.imagePaths,
width: constraintsEditor.maxWidth,
height: constraintsEditor.maxHeight,
onLocalFileDropZoneListener: (details) =>
controller.onLocalFileDropZoneListener(
context: context,
details: details,
maxWidth: constraintsEditor.maxWidth,
),
)
),
);
} else {
return const SizedBox.shrink();
}
}),
],
),
);
}
), ),
), ),
Obx(() => BottomBarComposerWidget( Obx(() => BottomBarComposerWidget(
@@ -780,6 +734,58 @@ class ComposerView extends GetWidget<ComposerController> {
sendMessageAction: () => controller.handleClickSendButton(context), sendMessageAction: () => controller.handleClickSendButton(context),
requestReadReceiptAction: () => controller.toggleRequestReadReceipt(context), requestReadReceiptAction: () => controller.toggleRequestReadReceipt(context),
)), )),
],
),
Align(
alignment: AlignmentDirectional.topCenter,
child: Obx(() => InsertImageLoadingBarWidget(
uploadInlineViewState: controller.uploadController.uploadInlineViewState.value,
viewState: controller.viewState.value,
padding: ComposerStyle.insertImageLoadingBarPadding,
)),
),
Obx(() {
if (controller.mailboxDashBoardController.isAttachmentDraggableAppActive) {
return Positioned.fill(
child: PointerInterceptor(
child: AttachmentDropZoneWidget(
imagePaths: controller.imagePaths,
width: constraintsBody.maxWidth,
height: constraintsBody.maxHeight,
onAttachmentDropZoneListener: controller.onAttachmentDropZoneListener,
)
),
);
} else {
return const SizedBox.shrink();
}
}),
Obx(() {
if (controller.mailboxDashBoardController.isLocalFileDraggableAppActive) {
return Positioned.fill(
child: PointerInterceptor(
child: LocalFileDropZoneWidget(
imagePaths: controller.imagePaths,
width: constraintsBody.maxWidth,
height: constraintsBody.maxHeight,
onLocalFileDropZoneListener: (details) =>
controller.onLocalFileDropZoneListener(
context: context,
details: details,
maxWidth: constraintsBody.maxWidth,
),
)
),
);
} else {
return const SizedBox.shrink();
}
}),
],
);
},
),
)
]), ]),
); );
}, },
@@ -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: (_) {},
), ),
); );
} }