Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[desktop_drop] Drag and drop folder on web now returns the folder's content #288

Merged
merged 2 commits into from Dec 26, 2023

Conversation

LucazzP
Copy link
Contributor

@LucazzP LucazzP commented Sep 19, 2023

My issue:
I'm developing an application that uses the drag and drop on the desktop and web. On desktop it works perfectly well, when I drop a folder, for example, I can use the Directory object from the dart:io and iterates from all the folder's content.
But on the web we don't have the dart:io library, so how could I do this folder content getting?
I searched for many ways to do that, using the blob URL that is generated, using the FileReader and some other ways, nothing worked. The only way possible to do that was getting the folder content when I drop the folder, using the DataTransferItem from the DataTransferItemList.

The solution
Using the DataTransferItem I can determine if the item is a File or a Directory, so I added a check if it is a Directory and iterated from the folder's content using the FileSystemDirectoryEntry with the .createReader() function that returns a FileSystemDirectoryReader with a .readEntries() that returns the content listing.

With each content, I run the function recursively until I find all the files from the dragged folder (I tested with the biggest nested folder that I have, and it lagged nothing, so I don't think we need to limit that, but we could add a parameter to make this recursively optional), mapping all into WebDropItem, as it was.

For that change, I was needed to change the List<XFile> files from the DropDoneEvent to List<DropItem> files, that will not be a breaking change, since the DropItemFile is a class that extends XFile, so it will keep working as it was in all other projects that were using the XFile.
I created three new classes, DropItem that extends from XFile, DropItemFile that extends from DropItem and finally the DropItemDirectory that extends from DropItem and adds a new property called children, that is a List of DropItem.
So with that, we can return all the folders and contents that we want, without breaking changes and any issues 馃専

Challenges
I got some troubles until I got the solution working, so it could be evident on the _entryToWebDropItem method of the desktop_drop_web file.
For some reason, if I try to use the objects that dart provides me from the HTML package, it simply fails when I try to cast from the Entry object to the DirectoryEntry. So what I made was use the JS directly, using dynamic types and making my own implementation. It could look a little messy for maintenance, but it works really well and didn't fail, so if someone has other better solution for that, I'd appreciate it!

Changes

  • Improved the print files from the example
  • Updated index.html of the example
  • Created DropItem, DropItemFile and DropItemDirectory to be used instead of XFile (no breaking change)
  • DropDoneDetails now uses DropItem instead of XFile

Copy link
Contributor

@boyan01 boyan01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for later.

Thanks for you contribution. 馃挋

@boyan01 boyan01 merged commit 40bf8cf into MixinNetwork:main Dec 26, 2023
@jackie099
Copy link
Contributor

jackie099 commented Mar 21, 2024

Thanks for the work.. It's working on debug mode, but not on release. I'm getting the following error:

desktop_drop_web: NoSuchMethodError: method not found: 'file'
js_primitives.dart:42 Receiver: Instance of 'minified:eu'
js_primitives.dart:42 Arguments: [Closure 'minified:Yo', Closure 'minified:Yp'] NoSuchMethodError: method not found: 'file'
js_primitives.dart:42 Receiver: Instance of 'minified:eu'
js_primitives.dart:42 Arguments: [Closure 'minified:Yo', Closure 'minified:Yp']
js_primitives.dart:42 at Object.c (http://localhost:61500/main.dart.js:4145:19)
js_primitives.dart:42 at d.E (http://localhost:61500/main.dart.js:34748:16)
js_primitives.dart:42 at d.x7 (http://localhost:61500/main.dart.js:39137:23)
js_primitives.dart:42 at http://localhost:61500/main.dart.js:41800:4
js_primitives.dart:42 at aj1.a (http://localhost:61500/main.dart.js:5496:63)
js_primitives.dart:42 at aj1.$2 (http://localhost:61500/main.dart.js:36294:14)
js_primitives.dart:42 at Object.U (http://localhost:61500/main.dart.js:5482:10)
js_primitives.dart:42 at FM.kU (http://localhost:61500/main.dart.js:41815:10)
js_primitives.dart:42 at Yr.$1 (http://localhost:61500/main.dart.js:41866:15)
js_primitives.dart:42 at Object.aAm (http://localhost:61500/main.dart.js:6423:24)

I'm seeing this for debug mode:
Attempting to install properties from non-Object type 'FileEntry' onto the native JS Object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants