diff --git a/contact/pubspec.lock b/contact/pubspec.lock index 76a072a66d..382ce6ae6f 100644 --- a/contact/pubspec.lock +++ b/contact/pubspec.lock @@ -252,10 +252,10 @@ packages: dependency: transitive description: name: device_info_plus - sha256: "499c61743e13909c13374a8c209075385858c614b9c0f2487b5f9995eeaf7369" + sha256: "2c35b6d1682b028e42d07b3aee4b98fa62996c10bc12cb651ec856a80d6a761b" url: "https://pub.dev" source: hosted - version: "9.0.1" + version: "9.0.2" device_info_plus_platform_interface: dependency: transitive description: @@ -664,6 +664,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + irondash_engine_context: + dependency: transitive + description: + name: irondash_engine_context + sha256: "0e803321935ca7af1a88f1391be9edfdb940df800353670bfc694934c7643ff3" + url: "https://pub.dev" + source: hosted + version: "0.4.1" + irondash_message_channel: + dependency: transitive + description: + name: irondash_message_channel + sha256: "500daa1fbe679f7d28a5258df3ff47dab6de352e680dc93c1ca9eae1555d8db5" + url: "https://pub.dev" + source: hosted + version: "0.3.1" jmap_dart_client: dependency: "direct main" description: @@ -904,6 +920,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.1" + pixel_snap: + dependency: transitive + description: + name: pixel_snap + sha256: "677410ea37b07cd37ecb6d5e6c0d8d7615a7cf3bd92ba406fd1ac57e937d1fb0" + url: "https://pub.dev" + source: hosted + version: "0.1.5" platform: dependency: transitive description: @@ -1070,6 +1094,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.0" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" stack_trace: dependency: transitive description: @@ -1102,6 +1134,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + super_clipboard: + dependency: transitive + description: + name: super_clipboard + sha256: "1031873af66c796177eff073d1453c9f19a75e6f9b308ca0b950928d0a20aedd" + url: "https://pub.dev" + source: hosted + version: "0.7.3" + super_drag_and_drop: + dependency: transitive + description: + name: super_drag_and_drop + sha256: cb884e24f75127ddfba7908808ac265249075511c72584148345b259ca99788c + url: "https://pub.dev" + source: hosted + version: "0.7.0" + super_native_extensions: + dependency: transitive + description: + name: super_native_extensions + sha256: fd658e096e99ed7555c0727a8201dbe3b8afc0059742ac14bdcff115e08f589c + url: "https://pub.dev" + source: hosted + version: "0.7.3" term_glyph: dependency: transitive description: @@ -1222,6 +1278,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.0" + uuid: + dependency: transitive + description: + name: uuid + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + url: "https://pub.dev" + source: hosted + version: "4.5.1" vector_graphics: dependency: transitive description: diff --git a/core/lib/presentation/views/text/text_drop_zone_web.dart b/core/lib/presentation/views/text/text_drop_zone_web.dart new file mode 100644 index 0000000000..667c9893a6 --- /dev/null +++ b/core/lib/presentation/views/text/text_drop_zone_web.dart @@ -0,0 +1,109 @@ +import 'dart:async'; + +import 'package:collection/collection.dart'; +import 'package:core/presentation/extensions/list_nullable_extensions.dart'; +import 'package:core/utils/app_logger.dart'; +import 'package:flutter/material.dart'; +import 'package:super_drag_and_drop/super_drag_and_drop.dart'; +import 'package:universal_html/html.dart' hide VoidCallback; + +typedef OnSuperTextDrop = void Function(String value); + +class TextDropZoneWeb extends StatefulWidget { + const TextDropZoneWeb({ + super.key, + required this.child, + this.onHover, + this.onLeave, + this.onDrop, + }); + + final Widget child; + final VoidCallback? onHover; + final VoidCallback? onLeave; + final OnSuperTextDrop? onDrop; + + @override + State createState() => _TextDropZoneWebState(); +} + +class _TextDropZoneWebState extends State { + bool _textIsDragging = false; + StreamSubscription? _dragEnterSubscription; + StreamSubscription? _dragOverSubscription; + StreamSubscription? _dropSubscription; + StreamSubscription? _dragLeaveSubscription; + + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((_) { + _dragEnterSubscription = window.onDragEnter.listen((event) { + setState(() { + _textIsDragging = event.dataTransfer.types?.validateFilesTransfer != true; + }); + }); + _dragOverSubscription = window.onDragOver.listen((event) { + setState(() { + _textIsDragging = event.dataTransfer.types?.validateFilesTransfer != true; + }); + }); + _dropSubscription = window.onDrop.listen((event) { + setState(() { + _textIsDragging = false; + }); + }); + _dragLeaveSubscription = window.onDragLeave.listen((event) { + setState(() { + _textIsDragging = false; + }); + }); + }); + } + + @override + void dispose() { + _dragEnterSubscription?.cancel(); + _dragOverSubscription?.cancel(); + _dropSubscription?.cancel(); + _dragLeaveSubscription?.cancel(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (!_textIsDragging) return widget.child; + + return DropRegion( + formats: const [Formats.plainText], + onDropOver: (dropOverEvent) { + final dragItem = dropOverEvent.session.items.firstOrNull; + if (dragItem == null || !dragItem.canProvide(Formats.plainText)) { + return DropOperation.none; + } + + widget.onHover?.call(); + + return DropOperation.copy; + }, + onDropLeave: (_) => widget.onLeave?.call(), + onPerformDrop: (performDropEvent) async { + final item = performDropEvent.session.items.firstOrNull; + if (item == null) return; + + item.dataReader?.getValue( + Formats.plainText, + (value) { + log('TextDropZoneWeb::onPerformDrop:value = $value'); + if (value == null) return; + widget.onDrop?.call(value); + }, + onError: (error) { + logError('TextDropZoneWeb::onPerformDrop:error: $error'); + } + ); + }, + child: widget.child, + ); + } +} \ No newline at end of file diff --git a/core/lib/presentation/views/text/text_field_builder.dart b/core/lib/presentation/views/text/text_field_builder.dart index 4934594ff9..b8295403f6 100644 --- a/core/lib/presentation/views/text/text_field_builder.dart +++ b/core/lib/presentation/views/text/text_field_builder.dart @@ -1,5 +1,6 @@ import 'package:core/presentation/extensions/color_extension.dart'; import 'package:core/presentation/views/semantics/text_field_semantics.dart'; +import 'package:core/presentation/views/text/text_drop_zone_web.dart'; import 'package:core/utils/direction_utils.dart'; import 'package:flutter/material.dart'; @@ -27,6 +28,7 @@ class TextFieldBuilder extends StatefulWidget { final bool readOnly; final MouseCursor? mouseCursor; final String? semanticLabel; + final bool dropTextEnabled; const TextFieldBuilder({ super.key, @@ -52,6 +54,7 @@ class TextFieldBuilder extends StatefulWidget { this.onTapOutside, this.onTextChange, this.onTextSubmitted, + this.dropTextEnabled = false, }); @override @@ -79,7 +82,7 @@ class _TextFieldBuilderState extends State { @override Widget build(BuildContext context) { - final textField = TextField( + Widget textField = TextField( key: widget.key, controller: _controller, cursorColor: widget.cursorColor, @@ -103,6 +106,17 @@ class _TextFieldBuilderState extends State { onTapOutside: widget.onTapOutside, ); + if (widget.dropTextEnabled) { + textField = TextDropZoneWeb( + child: textField, + onDrop: (value) { + _controller?.text += value; + widget.focusNode?.requestFocus(); + _onTextChanged(value); + }, + ); + } + if (widget.semanticLabel != null) { return TextFieldSemantics( label: widget.semanticLabel!, diff --git a/core/pubspec.lock b/core/pubspec.lock index fd2dc5f7f4..f77071c129 100644 --- a/core/pubspec.lock +++ b/core/pubspec.lock @@ -245,10 +245,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: "499c61743e13909c13374a8c209075385858c614b9c0f2487b5f9995eeaf7369" + sha256: "2c35b6d1682b028e42d07b3aee4b98fa62996c10bc12cb651ec856a80d6a761b" url: "https://pub.dev" source: hosted - version: "9.0.1" + version: "9.0.2" device_info_plus_platform_interface: dependency: transitive description: @@ -649,6 +649,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + irondash_engine_context: + dependency: transitive + description: + name: irondash_engine_context + sha256: "0e803321935ca7af1a88f1391be9edfdb940df800353670bfc694934c7643ff3" + url: "https://pub.dev" + source: hosted + version: "0.4.1" + irondash_message_channel: + dependency: transitive + description: + name: irondash_message_channel + sha256: "500daa1fbe679f7d28a5258df3ff47dab6de352e680dc93c1ca9eae1555d8db5" + url: "https://pub.dev" + source: hosted + version: "0.3.1" js: dependency: transitive description: @@ -865,6 +881,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.1" + pixel_snap: + dependency: transitive + description: + name: pixel_snap + sha256: "677410ea37b07cd37ecb6d5e6c0d8d7615a7cf3bd92ba406fd1ac57e937d1fb0" + url: "https://pub.dev" + source: hosted + version: "0.1.5" platform: dependency: transitive description: @@ -1015,6 +1039,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.0" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" stack_trace: dependency: transitive description: @@ -1047,6 +1079,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + super_clipboard: + dependency: transitive + description: + name: super_clipboard + sha256: "1031873af66c796177eff073d1453c9f19a75e6f9b308ca0b950928d0a20aedd" + url: "https://pub.dev" + source: hosted + version: "0.7.3" + super_drag_and_drop: + dependency: "direct main" + description: + name: super_drag_and_drop + sha256: cb884e24f75127ddfba7908808ac265249075511c72584148345b259ca99788c + url: "https://pub.dev" + source: hosted + version: "0.7.0" + super_native_extensions: + dependency: transitive + description: + name: super_native_extensions + sha256: fd658e096e99ed7555c0727a8201dbe3b8afc0059742ac14bdcff115e08f589c + url: "https://pub.dev" + source: hosted + version: "0.7.3" term_glyph: dependency: transitive description: @@ -1159,6 +1215,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.0" + uuid: + dependency: transitive + description: + name: uuid + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + url: "https://pub.dev" + source: hosted + version: "4.5.1" vector_graphics: dependency: transitive description: diff --git a/core/pubspec.yaml b/core/pubspec.yaml index 83db4a792e..ca5e3e4ba7 100644 --- a/core/pubspec.yaml +++ b/core/pubspec.yaml @@ -53,7 +53,7 @@ dependencies: get: 4.6.6 - device_info_plus: 9.0.1 + device_info_plus: 9.0.2 flutter_inappwebview: 6.1.0 @@ -105,6 +105,8 @@ dependencies: pull_to_refresh: 2.0.0 html_unescape: 2.0.0 + + super_drag_and_drop: 0.7.0 dev_dependencies: flutter_test: diff --git a/lib/features/composer/presentation/composer_controller.dart b/lib/features/composer/presentation/composer_controller.dart index 5b5277bf26..3f84350d72 100644 --- a/lib/features/composer/presentation/composer_controller.dart +++ b/lib/features/composer/presentation/composer_controller.dart @@ -5,7 +5,6 @@ import 'dart:math'; import 'package:core/core.dart'; import 'package:custom_pop_up_menu/custom_pop_up_menu.dart'; import 'package:dartz/dartz.dart'; -import 'package:desktop_drop/desktop_drop.dart'; import 'package:dio/dio.dart'; import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:file_picker/file_picker.dart'; @@ -1969,15 +1968,13 @@ class ComposerController extends BaseController } } - void onLocalFileDropZoneListener({ + Future onSuperDropListener({ required BuildContext context, - required DropDoneDetails details, + required List listFileInfo, required double maxWidth }) async { _setUpMaxWidthInlineImage(context: context, maxWidth: maxWidth); - final listFileInfo = await onDragDone(context: context, details: details); - if (listFileInfo.isEmpty && context.mounted) { appToast.showToastErrorMessage( context, diff --git a/lib/features/composer/presentation/composer_view_web.dart b/lib/features/composer/presentation/composer_view_web.dart index 74e47a7f78..7efcd2db5d 100644 --- a/lib/features/composer/presentation/composer_view_web.dart +++ b/lib/features/composer/presentation/composer_view_web.dart @@ -205,6 +205,7 @@ class ComposerView extends GetWidget { onTextChange: controller.setSubjectEmail, padding: ComposerStyle.mobileSubjectPadding, margin: ComposerStyle.mobileSubjectMargin, + dropTextEnabled: true, ), Expanded( child: LayoutBuilder( @@ -305,10 +306,10 @@ class ComposerView extends GetWidget { imagePaths: controller.imagePaths, width: constraintsEditor.maxWidth, height: constraintsEditor.maxHeight, - onLocalFileDropZoneListener: (details) => - controller.onLocalFileDropZoneListener( + onSuperDrop: (listFileInfo) => + controller.onSuperDropListener( context: context, - details: details, + listFileInfo: listFileInfo, maxWidth: constraintsEditor.maxWidth, ), ) @@ -474,6 +475,7 @@ class ComposerView extends GetWidget { onTextChange: controller.setSubjectEmail, padding: ComposerStyle.desktopSubjectPadding, margin: ComposerStyle.desktopSubjectMargin, + dropTextEnabled: true, ), Expanded( child: LayoutBuilder( @@ -613,10 +615,10 @@ class ComposerView extends GetWidget { imagePaths: controller.imagePaths, width: constraintsEditor.maxWidth, height: constraintsEditor.maxHeight, - onLocalFileDropZoneListener: (details) => - controller.onLocalFileDropZoneListener( + onSuperDrop: (listFileInfo) => + controller.onSuperDropListener( context: context, - details: details, + listFileInfo: listFileInfo, maxWidth: constraintsEditor.maxWidth, ), ) @@ -786,6 +788,7 @@ class ComposerView extends GetWidget { onTextChange: controller.setSubjectEmail, padding: ComposerStyle.tabletSubjectPadding, margin: ComposerStyle.tabletSubjectMargin, + dropTextEnabled: true, ), Expanded( child: LayoutBuilder( @@ -923,10 +926,10 @@ class ComposerView extends GetWidget { imagePaths: controller.imagePaths, width: constraintsBody.maxWidth, height: constraintsBody.maxHeight, - onLocalFileDropZoneListener: (details) => - controller.onLocalFileDropZoneListener( + onSuperDrop: (listFileInfo) => + controller.onSuperDropListener( context: context, - details: details, + listFileInfo: listFileInfo, maxWidth: constraintsBody.maxWidth, ), ) diff --git a/lib/features/composer/presentation/mixin/drag_drog_file_mixin.dart b/lib/features/composer/presentation/mixin/drag_drog_file_mixin.dart index 1d27758307..ab0e5abb6c 100644 --- a/lib/features/composer/presentation/mixin/drag_drog_file_mixin.dart +++ b/lib/features/composer/presentation/mixin/drag_drog_file_mixin.dart @@ -1,10 +1,7 @@ import 'dart:async' as async; import 'package:async/async.dart'; -import 'package:core/data/constants/constant.dart'; -import 'package:desktop_drop/desktop_drop.dart'; import 'package:flutter/material.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; -import 'package:model/upload/file_info.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; mixin DragDropFileMixin { @@ -19,34 +16,4 @@ mixin DragDropFileMixin { future: future, ); } - - async.Future> onDragDone({ - required BuildContext context, - required DropDoneDetails details - }) async { - final bytesList = await showFutureLoadingDialogFullScreen( - context: context, - future: () => async.Future.wait( - details.files.map( - (xFile) => xFile.readAsBytes(), - ), - ), - ); - - if (bytesList.error != null) return []; - - final listFileInfo = []; - for (var i = 0; i < bytesList.result!.length; i++) { - listFileInfo.add( - FileInfo( - bytes: bytesList.result![i], - fileName: details.files[i].name, - type: details.files[i].mimeType, - fileSize: bytesList.result![i].length, - isInline: details.files[i].mimeType?.startsWith(Constant.imageType) == true - ), - ); - } - return listFileInfo; - } } diff --git a/lib/features/composer/presentation/widgets/recipient_composer_widget.dart b/lib/features/composer/presentation/widgets/recipient_composer_widget.dart index 500fbfc227..0a62fe98ca 100644 --- a/lib/features/composer/presentation/widgets/recipient_composer_widget.dart +++ b/lib/features/composer/presentation/widgets/recipient_composer_widget.dart @@ -17,6 +17,7 @@ import 'package:model/email/prefix_email_address.dart'; import 'package:model/extensions/email_address_extension.dart'; import 'package:model/mailbox/expand_mode.dart'; import 'package:super_tag_editor/tag_editor.dart'; +import 'package:core/presentation/views/text/text_drop_zone_web.dart'; import 'package:tmail_ui_user/features/composer/presentation/extensions/prefix_email_address_extension.dart'; import 'package:tmail_ui_user/features/composer/presentation/extensions/mail_address_extension.dart'; import 'package:tmail_ui_user/features/composer/presentation/model/draggable_email_address.dart'; @@ -162,7 +163,7 @@ class _RecipientComposerWidgetState extends State { if (PlatformInfo.isWeb || widget.isTestingForWeb) { return DragTarget( builder: (context, candidateData, rejectedData) { - return TagEditor( + final child = TagEditor( key: widget.keyTagEditor, length: _collapsedListEmailAddress.length, controller: widget.controller, @@ -244,6 +245,27 @@ class _RecipientComposerWidgetState extends State { ); }, ); + + return TextDropZoneWeb( + onHover: () { + if (!_isDragging) { + stateSetter(() => _isDragging = true); + } + }, + onLeave: () { + if (_isDragging) { + stateSetter(() => _isDragging = false); + } + }, + onDrop: (value) { + if (_isDragging) { + stateSetter(() => _isDragging = false); + } + widget.controller?.text += value; + widget.focusNode?.requestFocus(); + }, + child: child, + ); }, onAcceptWithDetails: (draggableEmailAddress) => _handleAcceptDraggableEmailAddressAction(draggableEmailAddress.data, stateSetter), onLeave: (draggableEmailAddress) { diff --git a/lib/features/composer/presentation/widgets/subject_composer_widget.dart b/lib/features/composer/presentation/widgets/subject_composer_widget.dart index f7aa1ac1e1..1d90102abd 100644 --- a/lib/features/composer/presentation/widgets/subject_composer_widget.dart +++ b/lib/features/composer/presentation/widgets/subject_composer_widget.dart @@ -11,6 +11,7 @@ class SubjectComposerWidget extends StatelessWidget { final ValueChanged? onTextChange; final EdgeInsetsGeometry? margin; final EdgeInsetsGeometry? padding; + final bool dropTextEnabled; const SubjectComposerWidget({ super.key, @@ -19,6 +20,7 @@ class SubjectComposerWidget extends StatelessWidget { required this.onTextChange, this.margin, this.padding, + this.dropTextEnabled = false, }); @override @@ -51,6 +53,7 @@ class SubjectComposerWidget extends StatelessWidget { textDirection: DirectionUtils.getDirectionByLanguage(context), textStyle: SubjectComposerWidgetStyle.inputTextStyle, controller: textController, + dropTextEnabled: dropTextEnabled, ) ) ] diff --git a/lib/features/composer/presentation/widgets/web/local_file_drop_zone_widget.dart b/lib/features/composer/presentation/widgets/web/local_file_drop_zone_widget.dart index dc5111a195..32e990e596 100644 --- a/lib/features/composer/presentation/widgets/web/local_file_drop_zone_widget.dart +++ b/lib/features/composer/presentation/widgets/web/local_file_drop_zone_widget.dart @@ -1,21 +1,28 @@ +import 'dart:async'; + +import 'package:collection/collection.dart'; +import 'package:core/data/constants/constant.dart'; import 'package:core/presentation/resources/image_paths.dart'; import 'package:dotted_border/dotted_border.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:model/upload/file_info.dart'; +import 'package:super_clipboard/super_clipboard.dart'; +import 'package:super_drag_and_drop/super_drag_and_drop.dart'; +import 'package:tmail_ui_user/features/composer/presentation/mixin/drag_drog_file_mixin.dart'; import 'package:tmail_ui_user/features/composer/presentation/styles/web/drop_zone_widget_style.dart'; import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; -import 'package:desktop_drop/desktop_drop.dart'; -typedef OnLocalFileDropZoneListener = Function(DropDoneDetails details); +typedef OnSuperFileDrop = void Function(List fileInfos); -class LocalFileDropZoneWidget extends StatelessWidget { +class LocalFileDropZoneWidget extends StatelessWidget with DragDropFileMixin { final ImagePaths imagePaths; final double? width; final double? height; final EdgeInsetsGeometry margin; - final OnLocalFileDropZoneListener? onLocalFileDropZoneListener; + final OnSuperFileDrop? onSuperDrop; const LocalFileDropZoneWidget({ super.key, @@ -23,13 +30,23 @@ class LocalFileDropZoneWidget extends StatelessWidget { this.width, this.height, this.margin = DropZoneWidgetStyle.margin, - this.onLocalFileDropZoneListener + this.onSuperDrop, }); + static final allowedFormats = Formats.standardFormats.where((format) { + return format != Formats.plainText + && format != Formats.htmlText + && format != Formats.uri + && format != Formats.fileUri; + }).cast().toList(); + @override Widget build(BuildContext context) { - return DropTarget( - onDragDone: onLocalFileDropZoneListener, + return DropRegion( + formats: allowedFormats, + onDropOver: (_) => DropOperation.copy, + onPerformDrop: (performDropEvent) => _onFileDrop(context, performDropEvent), + hitTestBehavior: HitTestBehavior.opaque, child: SizedBox( width: width, height: height, @@ -68,4 +85,45 @@ class LocalFileDropZoneWidget extends StatelessWidget { ), ); } + + Future _onFileDrop(BuildContext context, PerformDropEvent performDropEvent) async { + await showFutureLoadingDialogFullScreen( + context: context, + future: () async { + final items = performDropEvent.session.items; + final listFileInfo = await Future.wait(items.map( + (item) async { + final dataReaderFile = await item.dataReader?.getFileFuture( + SimpleFileFormat(mimeTypes: item.platformFormats) + ); + final bytes = await dataReaderFile?.readAll(); + return FileInfo( + fileName: dataReaderFile?.fileName ?? await item.dataReader?.getSuggestedName() ?? '', + fileSize: bytes?.length ?? 0, + bytes: bytes, + isInline: item.platformFormats.firstOrNull?.startsWith(Constant.imageType), + type: item.platformFormats.firstOrNull ?? Constant.octetStreamMimeType, + ); + }, + )); + + onSuperDrop?.call(listFileInfo); + }, + ); + } } + +extension _DataReaderExtension on DataReader { + Future getFileFuture(FileFormat format) { + final c = Completer(); + final progress = getFile( + format, + (file) => c.complete(file), + onError: (e) => c.completeError(e), + ); + if (progress == null) { + c.complete(null); + } + return c.future; + } +} \ No newline at end of file diff --git a/lib/features/identity_creator/presentation/identity_creator_controller.dart b/lib/features/identity_creator/presentation/identity_creator_controller.dart index f2028a2cb1..b418aa2d21 100644 --- a/lib/features/identity_creator/presentation/identity_creator_controller.dart +++ b/lib/features/identity_creator/presentation/identity_creator_controller.dart @@ -12,7 +12,6 @@ import 'package:core/presentation/utils/keyboard_utils.dart'; import 'package:core/utils/app_logger.dart'; import 'package:core/utils/file_utils.dart'; import 'package:core/utils/platform_info.dart'; -import 'package:desktop_drop/desktop_drop.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/scheduler.dart'; @@ -896,14 +895,13 @@ class IdentityCreatorController extends BaseController with DragDropFileMixin im AppLocalizations.of(context).thisImageCannotBePastedIntoTheEditor); } - void onLocalFileDropZoneListener({ + Future onSuperDropListener({ required BuildContext context, - required DropDoneDetails details, + required List listFileInfo, required double maxWidth }) async { clearFocusEditor(context); - final listFileInfo = await onDragDone(context: context, details: details); if (!context.mounted) return; await _uploadMultipleFilesToPublicAsset( context, diff --git a/lib/features/identity_creator/presentation/identity_creator_view.dart b/lib/features/identity_creator/presentation/identity_creator_view.dart index a41cc06232..e7f22ce8ec 100644 --- a/lib/features/identity_creator/presentation/identity_creator_view.dart +++ b/lib/features/identity_creator/presentation/identity_creator_view.dart @@ -137,10 +137,10 @@ class IdentityCreatorView extends GetWidget width: constraintsEditor.maxWidth, height: constraintsEditor.maxHeight, margin: EdgeInsets.zero, - onLocalFileDropZoneListener: (details) => - controller.onLocalFileDropZoneListener( + onSuperDrop: (listFileInfo) => + controller.onSuperDropListener( context: context, - details: details, + listFileInfo: listFileInfo, maxWidth: constraintsEditor.maxWidth, ), ) diff --git a/model/pubspec.lock b/model/pubspec.lock index 1203072449..5bf221d51f 100644 --- a/model/pubspec.lock +++ b/model/pubspec.lock @@ -252,10 +252,10 @@ packages: dependency: transitive description: name: device_info_plus - sha256: "499c61743e13909c13374a8c209075385858c614b9c0f2487b5f9995eeaf7369" + sha256: "2c35b6d1682b028e42d07b3aee4b98fa62996c10bc12cb651ec856a80d6a761b" url: "https://pub.dev" source: hosted - version: "9.0.1" + version: "9.0.2" device_info_plus_platform_interface: dependency: transitive description: @@ -656,6 +656,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + irondash_engine_context: + dependency: transitive + description: + name: irondash_engine_context + sha256: "0e803321935ca7af1a88f1391be9edfdb940df800353670bfc694934c7643ff3" + url: "https://pub.dev" + source: hosted + version: "0.4.1" + irondash_message_channel: + dependency: transitive + description: + name: irondash_message_channel + sha256: "500daa1fbe679f7d28a5258df3ff47dab6de352e680dc93c1ca9eae1555d8db5" + url: "https://pub.dev" + source: hosted + version: "0.3.1" jmap_dart_client: dependency: "direct main" description: @@ -881,6 +897,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.1" + pixel_snap: + dependency: transitive + description: + name: pixel_snap + sha256: "677410ea37b07cd37ecb6d5e6c0d8d7615a7cf3bd92ba406fd1ac57e937d1fb0" + url: "https://pub.dev" + source: hosted + version: "0.1.5" platform: dependency: transitive description: @@ -1047,6 +1071,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.0" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" stack_trace: dependency: transitive description: @@ -1079,6 +1111,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + super_clipboard: + dependency: transitive + description: + name: super_clipboard + sha256: "1031873af66c796177eff073d1453c9f19a75e6f9b308ca0b950928d0a20aedd" + url: "https://pub.dev" + source: hosted + version: "0.7.3" + super_drag_and_drop: + dependency: transitive + description: + name: super_drag_and_drop + sha256: cb884e24f75127ddfba7908808ac265249075511c72584148345b259ca99788c + url: "https://pub.dev" + source: hosted + version: "0.7.0" + super_native_extensions: + dependency: transitive + description: + name: super_native_extensions + sha256: fd658e096e99ed7555c0727a8201dbe3b8afc0059742ac14bdcff115e08f589c + url: "https://pub.dev" + source: hosted + version: "0.7.3" term_glyph: dependency: transitive description: @@ -1199,6 +1255,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.0" + uuid: + dependency: transitive + description: + name: uuid + sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + url: "https://pub.dev" + source: hosted + version: "4.5.1" vector_graphics: dependency: transitive description: diff --git a/pubspec.lock b/pubspec.lock index 0069276685..300e30d2e4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -408,22 +408,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" - desktop_drop: - dependency: "direct main" - description: - name: desktop_drop - sha256: d55a010fe46c8e8fcff4ea4b451a9ff84a162217bdb3b2a0aa1479776205e15d - url: "https://pub.dev" - source: hosted - version: "0.4.4" device_info_plus: dependency: "direct main" description: name: device_info_plus - sha256: "499c61743e13909c13374a8c209075385858c614b9c0f2487b5f9995eeaf7369" + sha256: "2c35b6d1682b028e42d07b3aee4b98fa62996c10bc12cb651ec856a80d6a761b" url: "https://pub.dev" source: hosted - version: "9.0.1" + version: "9.0.2" device_info_plus_platform_interface: dependency: transitive description: @@ -1337,6 +1329,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + irondash_engine_context: + dependency: transitive + description: + name: irondash_engine_context + sha256: "0e803321935ca7af1a88f1391be9edfdb940df800353670bfc694934c7643ff3" + url: "https://pub.dev" + source: hosted + version: "0.4.1" + irondash_message_channel: + dependency: transitive + description: + name: irondash_message_channel + sha256: "500daa1fbe679f7d28a5258df3ff47dab6de352e680dc93c1ca9eae1555d8db5" + url: "https://pub.dev" + source: hosted + version: "0.3.1" jmap_dart_client: dependency: "direct main" description: @@ -1714,6 +1722,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + pixel_snap: + dependency: transitive + description: + name: pixel_snap + sha256: "677410ea37b07cd37ecb6d5e6c0d8d7615a7cf3bd92ba406fd1ac57e937d1fb0" + url: "https://pub.dev" + source: hosted + version: "0.1.5" platform: dependency: transitive description: @@ -2040,6 +2056,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + super_clipboard: + dependency: transitive + description: + name: super_clipboard + sha256: "10774204b35b68f8dc5884ab620f83220d2c12620a8dcf4e6f39c94666f3549f" + url: "https://pub.dev" + source: hosted + version: "0.7.0" + super_drag_and_drop: + dependency: "direct main" + description: + name: super_drag_and_drop + sha256: cb884e24f75127ddfba7908808ac265249075511c72584148345b259ca99788c + url: "https://pub.dev" + source: hosted + version: "0.7.0" + super_native_extensions: + dependency: transitive + description: + name: super_native_extensions + sha256: b2fb454a90308f4f25e8ab928272490883d87a28d362307678c76989287cae43 + url: "https://pub.dev" + source: hosted + version: "0.7.0" super_tag_editor: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 1b2146bc6b..81c6020d89 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -145,7 +145,7 @@ dependencies: path_provider: 2.1.5 - device_info_plus: 9.0.1 + device_info_plus: 9.0.2 permission_handler: 10.2.0 @@ -235,8 +235,6 @@ dependencies: mime: 1.0.4 - desktop_drop: 0.4.4 - future_loading_dialog: 0.3.0 file_picker: 8.0.5 @@ -262,6 +260,8 @@ dependencies: url: https://github.com/linagora/twake-previewer-flutter.git ref: main + super_drag_and_drop: 0.7.0 + dev_dependencies: flutter_test: sdk: flutter