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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple browse/drop targets with different callbacks? #71

Open
edemaine opened this issue Dec 4, 2015 · 6 comments
Open

Multiple browse/drop targets with different callbacks? #71

edemaine opened this issue Dec 4, 2015 · 6 comments
Labels

Comments

@edemaine
Copy link
Contributor

edemaine commented Dec 4, 2015

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 and assignDrop accept multiple targets, which is annoying because each post is its own template, but workable -- but then on('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?

@vsivsi
Copy link
Owner

vsivsi commented Dec 4, 2015

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

@vsivsi vsivsi added the question label Dec 4, 2015
@edemaine
Copy link
Contributor Author

edemaine commented Dec 6, 2015

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.

@edemaine
Copy link
Contributor Author

edemaine commented Dec 6, 2015

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!

@vsivsi
Copy link
Owner

vsivsi commented Dec 8, 2015

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....

@dpatte
Copy link

dpatte commented Jan 16, 2016

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?

@edemaine
Copy link
Contributor Author

@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

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

No branches or pull requests

3 participants