Open edemaine opened 8 years ago
Hi, sure this should be possible with a little customization. The built-in resumable.js instance support is really just a convenience for the most common case.
In your case, I think that you can just setup however many additional resumable.js instances a given page needs, being careful to configure each of them to be compatible with the server-side resumable endpoint: https://github.com/vsivsi/meteor-file-collection/blob/master/src/resumable_client.coffee#L28-L41
Thanks; this worked. This is probably obvious to you, but I had to set resumable: true
in the FileCollection call, even though I'm creating my own Resumable -- because otherwise the server side isn't setup, and the calls fail. Just an extra Resumable hanging around though, so not a big deal.
I'm also wondering whether I could capture the drop target / browse button events myself, mark the files with attributes about where they came from, and send them to a global resumable. I might try that next.
This also worked well, and is perhaps simpler -- it enables global upload limits etc. Some sample CoffeeScript code:
Template.messageAttach.events
'change .attachInput': (e, t) ->
for file in e.target.files
file.parentMessage = t.data.messageId
Files.resumable.addFile file, e
...
Files.resumable.on 'fileAdded', (file) ->
Files.insert
_id: file.uniqueIdentifier ## This is the ID resumable will use.
filename: file.fileName
contentType: file.file.type
metadata: parentMessage: file.file.parentMessage
, (err, _id) ->
if err
console.error "File creation failed:", err
else
Files.resumable.upload()
Speaking of the last few lines (based on your sample code), could you explain why it's OK to call resumable.upload()
after a single file is inserted into Mongo? I'm imagining that, if I select multiple files, several fileAdded
events get triggered, and then these insert
operations get queued, and I'll get the callback for one before possibly the others have finished, so before the Mongo entry is there for resumable to "append" to. But I've never seen this problem actually arise -- it seems like the files get uploaded sequentially even though I set simultaneousUploads
to 10... Well, at least it works!
Hi, I've also never seen a problem with that call to resumable.upload()
. Resumable doesn't seem to have a way to start uploading a single file, and there's no way (that I'm aware of) to get a count of the files that were dropped. So, yeah, seems a little brittle... The worst case is that a chunk or two would fail to upload until the file record was inserted, but resumable should retry those and recover. Something to think about though....
edemaine, I am in a similar situation as you. Let me see if I understand your 2nd solution...
You intercept the attachInput message, and pass a messageId in the parent message of each file and do your own addFile call. I assume you also do the same for drop?
Then in file added you pull the parentMessage and use that to determine your next steps?
@dpatte: Yes, that's exactly what I'm doing. And I do the same for drop. Here's some updated CoffeeScript code, which enables dragging onto an upload button, or clicking the upload button which triggers the browse of the file form input. Id and group fields of the template go into file metadata.
Template.messageAttach.events
"click .uploadButton": (e, t) ->
e.preventDefault()
e.stopPropagation()
t.find(".#{input}").click()
"change .uploadInput": (e, t) ->
attachFiles e.target.files, e, t
e.target.value = ''
"dragenter .uploadButton": (e) ->
e.preventDefault()
e.stopPropagation()
"dragover .uploadButton": (e) ->
e.preventDefault()
e.stopPropagation()
"drop .uploadButton": (e, t) ->
e.preventDefault()
e.stopPropagation()
attachFiles e.originalEvent.dataTransfer.files, e, t
attachFiles = (files, e, t) ->
message = t.data._id
group = t.data.group
for file in files
file.callback = (file2) ->
Meteor.call 'messageNew', group, message, null,
format: 'file'
title: file2.fileName
body: file2.uniqueIdentifier
file.group = group
Files.resumable.addFile file, e
Jade template looks like this: (Let me know if you need HTML.)
template(name="messageAttach")
input.attachInput(type="file", style="display:none", multiple)
button.btn.btn-default.attachButton Attach
In my application, there are multiple posts, and each post (rendered by its own template) should have its own browse button/drop target to attach files to the post.
Is this possible with file-collection? The package looks really great, except possibly for this issue, possibly caused by a limitation of Resumable.js.
assignBrowse
andassignDrop
accept multiple targets, which is annoying because each post is its own template, but workable -- but thenon('fileAdded')
doesn't seem to include in the event which one it came from. Perhaps the "right" answer would be to have multiple Resumable instances -- is this possible with (or easy to add to) file-collection?