Open jouni opened 7 years ago
@jouni Looks pretty good. Something that may be worth looking into would be having two versions of vaadin-uploader
one with the current ajax method and the other using the HTML5 File API setup.
I can work on a technical document for what I am thinking and how it all works together. I put them together all the time for work. I'm hoping to cover a lot of the feature set that is missing in the existing codebase as well. Let me know if you have any concerns or comments.
@jouni @manolo @platosha PTAL Hopefully this will be a good starting point.
These are my thoughts on the refactor and how I envision it coming together. I am completely open to suggestions and comments.
While thinking about this, I have taken into consideration @jouni's thoughts and the Feature Backlog (#23).
vaadin-upload
: Alias for the current implementation built on top of the new design
vaadin-upload-(behavior|mixin)
: Holds the common properties and functionality
maxFileSize
: The max file size allowed uploadaccept
: The accepted file typesfileSizeBase
: Base that is used to calculate the filesizecapture
: Capture typeclearOnComplete
: Clear file list on completionpreventReload
: Prevents reload during uploadrequired
: Required inputinvalid
: Invalid Statevaadin-multiple-upload
: For selecting files and acceptance criteria
vaadin-upload-behavior
files
: The files queued for uploadmaxFiles
: The max file countmaxFilesReached
: The max files reachedvaadin-single-upload
: For selecting a file and allowing re-upload of a file. Also controls acceptance criteria
vaadin-upload-behavior
file
: The file queued for uploadvaadin-uploader-(behavior|mixin)
: Common functionality for API uploaders
fallback
: Provides a fallback upload strategyfiles
: All filesurl
: The upload targetmethod
: The upload methodparams
: The upload query paramsheaders
: The upload headerstimeout
: The upload timeoutauto
: Auto-uploads queued filesretryOnError
: Auto Retry on errorswithCredentials
: Add the withCredentials
flag to the uploadcancel()
: Cancels the uploadabort()
: Cancels the upload and removes the fileuploadFiles()
: Start queued files for uploadretry()
: Retry a failed uploadvaddin-file-uploader
: Uses the HTML5 File API
vaadin-uploader-behavior
chunkSize
: The size of bytes of each uploaded chunk of dataconcurrentUploads
: Number of concurrent uploadsprioritizeStartAndEnd
: Prioritize the first and last chunks of filetestChunks
: Test each chunk to see it already existspause()
: Pause the uploadresume()
: Resume the uploadvaadin-ajax-uploader
: Uses XHR
vaadin-uploader-behavior
vaadin-localstorage-uploader
: Stores the files uploaded into the localstorage
files
: All filespath
: The path to store images atvaadin-file-list
: Displays a list of file items
files
: All files queued and uploaded to displayvaadin-file-item
: List item for displaying status and controlling the file's upload
file
: File metadata, upload status and progress informationvaadin-file-preview
: Renders a preview of the file that was uploaded or queued for upload
file
: The file to render a preview forvaadin-dropzone
: Handles the drag-n-drop of file(s)
target
: The target upload to handle the drag-n-dropWe could alias this as vaadin-upload
with some minimal customization.
<vaadin-dropzone target="upload">
<vaadin-ajax-uploader files="{{files}}"></vaadin-ajax-uploader>
<vaadin-multiple-upload id="upload" files="{{files}}">
<paper-button>UPLOAD FILES</paper-button>
</vaadin-multiple-upload>
<span>
<iron-icon icon="vaadin:upload"></iron-icon>
Drop Files here...
</span>
<vaadin-file-list files="{{files}}">
<template>
<vaadin-file-item file="{{file}}"></vaadin-file-item>
</template>
</vaadin-file-list>
</vaadin-dropzone>
<vaadin-dropzone target="upload"></vaadin-dropzone>
<vaadin-ajax-uploader files="{{files}}"></vaadin-ajax-uploader>
<vaadin-multiple-upload id="upload" files="{{files}}">
<paper-button>UPLOAD FILES</paper-button>
</vaadin-multiple-upload>
<span>
<iron-icon icon="vaadin:upload"></iron-icon>
Drop Files here...
</span>
<vaadin-file-list files="{{files}}">
<template>
<vaadin-file-item file="{{file}}"></vaadin-file-item>
</template>
</vaadin-file-list>
<vaadin-dropzone target="upload">
<vaadin-file-uploader files="{{files}}" fallback="ajax"></vaadin-file-uploader>
<vaadin-ajax-uploader files="{{files}}" id="ajax"></vaadin-ajax-uploader>
<vaadin-multiple-upload files="{{files}}">
<paper-button>UPLOAD FILES</paper-button>
</vaadin-multiple-upload>
<span>
<iron-icon icon="vaadin:upload"></iron-icon>
Drop Files here...
</span>
<vaadin-file-list files="{{files}}">
<template>
<vaadin-file-item file="{{file}}"></vaadin-file-item>
</template>
</vaadin-file-list>
</vaadin-dropzone>
Kudos, @stramel, for the proposal. I hope the team has some time to go through it asap. Would you be willing to build the first prototype for this, if we agree on the approach?
Yeah, I could probably build out a prototype of it.
I can’t find many things to point at, but here are some:
vaadin-upload-mixin – what is “capture”?
vaadin-upload alias – do we really need that, or should we just make users migrate to vaadin-multiple-upload? Or is there some difference between those?
uploader.cancel/abort/retry – do those target a single file in the list? Do we need “cancel/abort/retry all”?
localstorage-uploader.path mentions “images” – can’t we use localstorage for other file types?
vaadin-dropzone – Can I make it cover the entire viewport without wrapping other elements?
Thanks for taking a look through it @jouni and providing some feedback.
vaadin-upload-mixin – what is “capture”?
capture
is a pass-through to the input's capture attribute. (https://www.w3.org/TR/html-media-capture/#dom-htmlinputelement-capture)
vaadin-upload alias – do we really need that, or should we just make users migrate to vaadin-multiple-upload? Or is there some difference between those?
It isn't necessary. I just figured it would be a nice to have for an easy conversion to the next major change as well as providing an easy to use base interface. The difference between the two is that vaadin-upload
recreates the existing vaadin-upload
using the new components (ie. vaadin-multiple-upload
, vaadin-dropzone
, etc)
uploader.cancel/abort/retry – do those target a single file in the list? Do we need “cancel/abort/retry all”?
I would like to allow these to take a single file or multiple. Covert a single object to an array of 1 and accepting an array as well.
localstorage-uploader.path mentions “images” – can’t we use localstorage for other file types?
Yes, this could be any file type. Images are just the common type that I think of.
vaadin-dropzone – Can I make it cover the entire viewport without wrapping other elements?
Hmmm, that's an interesting thought. I think the only way to do that would be to take in a "drop-target" for handling drag-n-drop events and a "upload-target" for handling the upload of the dropped files. "drop-target" would allow you to specify something like document.body
. "upload-target" would target the uploader.
@jouni Did that answer your questions?
@stramel, yes, seems pretty clear at this point. Let’s see after we have the first working pieces of the prototype, I’ll probably have more then :)
Been a while since I updated this thread. I have a lot of the initial stuff working now. I need to do a few things before submitting for an initial review.
Hoping to make good progress this weekend!
Great to hear!
I did some snooping around, and the prototype is coming along in https://github.com/stramel/vaadin-upload/tree/ms/prototype-refactor, right?
Would you like someone to take a quick look at the work at this point? Just wondering if there are any obvious blockers that would slow things down more later on if not caught early?
@jouni, yeah that's the branch. You can take a look if you would like and any feedback would be great!
I'm still trying to figure out the best way to handle some of the validations and hopefully clean up some aspects of it.
Hoping to have it out in a PR for everyone to review soon.
For anyone who cares to take a preview of what I have, take a look at this PR. https://github.com/stramel/vaadin-upload/pull/1
Once I finish up a handful more things I will submit it over here. Just trying to get some initial feedback and gather my thoughts.
The current implementation has a narrow use case. Splitting it apart as Michael Stramel has done would make it much more useful.
Currently, what does the file-list do? I think it is just display-only, or does removing a file from the file-list remove it from the Receiver (I don't think it does anything).
It would also be nice if
Disclaimer: I’ve not thought this all through properly, but this is my current rough idea
Split the current
vaadin-upload
element into modules. When combined/connected together, they should produce the same feature set as the current element, but offer more customization options and ways to integrate those parts in other use cases.Modules (element names are just initial ideas):
vaadin-file-provider: for selecting files (either dropping on it or opening the OS dialog)
FileList
arrayvaadin-uploader: only handles the data communication, sending data to the server and firing events about the upload progress. Not sure if there should be one element per file (that is my gut feeling), or if one element can handle multiple uploads.
FileList
array, and could be configured to start uploads automatically, or leave them pending for manual start.vaadin-uploader-list: showing the status of files being uploaded, and allowing the end user to start/stop individual uploads (or all uploads at once).