Browse Source

Event-based plugin communication, upload progress for each file

Artur Paikin 9 years ago
parent
commit
5675c515bb

+ 9 - 7
src/plugins/DragDrop.js

@@ -141,14 +141,16 @@ export default class DragDrop extends Plugin {
 
     const newFiles = Array.from(e.dataTransfer.files)
 
-    this.core.emitter.emit('file-selection', {
+    this.core.emitter.emit('file-add', {
       plugin: this,
-      filesSelected: newFiles
+      acquiredFiles: newFiles
     })
 
-    newFiles.forEach((newFile) => {
-      this.files.push(newFile)
-    })
+    this.core.emitter.emit('new-next')
+    //
+    // newFiles.forEach((newFile) => {
+    //   this.files.push(newFile)
+    // })
 
     // return this.result(files)
   }
@@ -158,9 +160,9 @@ export default class DragDrop extends Plugin {
 
     const newFiles = Array.from(this.input.files)
 
-    this.core.emitter.emit('file-selection', {
+    this.core.emitter.emit('file-add', {
       plugin: this,
-      filesSelected: newFiles
+      acquiredFiles: newFiles
     })
 
     newFiles.forEach((newFile) => {

+ 4 - 4
src/plugins/Modal.js

@@ -149,10 +149,10 @@ export default class Modal extends Plugin {
     // Listen for allDone event to close all tabs
     this.core.emitter.on('allDone', () => this.allDone())
 
-    this.core.emitter.on('fileSelection', (data) => {
+    this.core.emitter.on('file-add', (data) => {
       this.nextButton.classList.add('is-active')
 
-      const files = data.filesSelected
+      const files = Object.keys(data.acquiredFiles)
       const selectedCount = files.length
 
         // How many files have been selected totally
@@ -160,8 +160,8 @@ export default class Modal extends Plugin {
 
       this.nextButton.innerHTML = this.core.i18n('uploadFiles', {'smart_count': this.core.totalFilesSelectedCount})
 
-      Object.keys(files).forEach((file) => {
-        this.core.log(`These file has been selected: ${files[file]}`)
+      files.forEach((file) => {
+        this.core.log(`These files have been selected: ${data.acquiredFiles[file]}`)
       })
     })
 

+ 4 - 4
src/plugins/ProgressBar.js

@@ -38,13 +38,13 @@ export default class ProgressBar extends Plugin {
 
   events () {
     // When there is some progress (uploading), emit this event to adjust progressbar
-    this.core.emitter.on('progress', (data) => {
+    this.core.emitter.on('upload-progress', (data) => {
       const percentage = data.percentage
-      const plugin = data.plugin
+      const uploader = data.uploader
       this.core.log(
-        `progress is: ${percentage}, set by ${plugin.constructor.name}`
+        `progress is: ${percentage}, set by ${uploader.constructor.name}`
       )
-      this.setProgress(percentage)
+      // this.setProgress(percentage)
     })
 
     this.core.emitter.on('reset', (data) => {

+ 59 - 21
src/plugins/ProgressDrawer.js

@@ -30,41 +30,74 @@ export default class ProgressDrawer extends Plugin {
   }
 
   render (state) {
+    const selectedFiles = state.files
+
+    const drawerItem = (fileID) => {
+      const remove = (ev) => {
+        this.core.emitter.emit('file-remove', fileID)
+      }
+
+      const checkIcon = () => {
+        return yo`<svg class="UppyProgressDrawer-itemCheck" width="16" height="16" viewBox="0 0 32 32" enable-background="new 0 0 32 32">
+          <polygon points="2.836,14.708 5.665,11.878 13.415,19.628 26.334,6.712 29.164,9.54 13.415,25.288 "></polygon>
+        </svg>`
+      }
+
+      const isUploaded = selectedFiles[fileID].progress === 100
+
+      return yo`<li class="UppyProgressDrawer-item ${isUploaded ? 'is-uploaded' : ''}">
+        <div class="UppyProgressDrawer-itemBar">
+          <span class="UppyProgressDrawer-itemProgress"
+                style="width: ${selectedFiles[fileID].progress}%"></span>
+          <h4 class="UppyProgressDrawer-itemName">
+            ${selectedFiles[fileID].name} (${selectedFiles[fileID].progress})</h4>
+          ${checkIcon()}
+        </div>
+        <button class="UppyProgressDrawer-itemRemove" onclick=${remove}>×</button>
+      </li>`
+    }
+
     return yo`<div class="UppyProgressDrawer">
-      <ul>
-        ${state.files.map((file, index) => {
-          const remove = (ev) => {
-            this.core.emitter.emit('remove-item', index)
-          }
-          return yo`<li>${file.name} <button onclick=${remove}>x</button></li>`
+      <ul class="UppyProgressDrawer-list">
+        ${Object.keys(selectedFiles).map((fileID) => {
+          return drawerItem(fileID)
         })}
       </ul>
     </div>`
   }
 
-  // all actions should be in core, I guess
+  // TODO all actions should be in core, I guess
   events () {
-    // this.core.emitter.on('progress', (data) => {
-    //   this.update({ progress: data })
-    // })
-
-    this.core.emitter.on('remove-item', (index) => {
-      const fileList = this.state.files.slice()
-      fileList.splice(index, 1)
-      this.update({files: fileList})
+    this.core.emitter.on('upload-progress', (progressData) => {
+      this.core.selectedFiles[progressData.id].progress = progressData.percentage
+      this.update({files: this.core.selectedFiles})
     })
 
-    this.core.emitter.on('file-selection', (files) => {
-      const fileList = this.state.files.slice()
-      files.filesSelected.forEach((file) => {
-        fileList.push(file)
+    this.core.emitter.on('file-remove', (fileID) => {
+      delete this.core.selectedFiles[fileID]
+      this.update({files: this.core.selectedFiles})
+    })
+
+    this.core.emitter.on('file-add', (data) => {
+      data.acquiredFiles.forEach((file) => {
+        const fileName = file.name
+        const fileID = this.generateFileID(fileName)
+
+        this.core.selectedFiles[fileID] = {
+          acquiredBy: data.plugin,
+          id: fileID,
+          name: fileName,
+          data: file,
+          progress: 0
+        }
       })
-      this.update({files: fileList})
+
+      this.update({files: this.core.selectedFiles})
     })
   }
 
   init () {
-    this.state = {files: []}
+    this.state = {files: {}}
     this.el = this.render(this.state)
     document.querySelector('.UppyModal').appendChild(this.el)
   }
@@ -72,6 +105,11 @@ export default class ProgressDrawer extends Plugin {
   install () {
     this.init()
     this.events()
+
+    // setTimeout(() => {
+    //   this.core.emitter.emit('new-next')
+    // }, 8000)
+
     return
   }
 }

+ 1 - 1
src/plugins/Spinner.js

@@ -31,7 +31,7 @@ export default class Spinner extends Plugin {
   }
 
   initEvents () {
-    this.core.emitter.on('progress', (data) => {
+    this.core.emitter.on('upload-progress', (data) => {
       const percentage = data.percentage
       const plugin = data.plugin
       this.core.log(

+ 28 - 10
src/plugins/Tus10.js

@@ -27,16 +27,11 @@ export default class Tus10 extends Plugin {
  */
   upload (file, current, total) {
     this.core.log(`uploading ${current} of ${total}`)
-
-    // Dispatch progress 0 on start
-    this.core.emitter.emit('progress', {
-      plugin: this,
-      percentage: 0
-    })
+    // console.log(file)
 
     // Create a new tus upload
     return new Promise((resolve, reject) => {
-      const upload = new tus.Upload(file, {
+      const upload = new tus.Upload(file.data, {
         endpoint: this.opts.endpoint,
         onError: (error) => {
           reject('Failed because: ' + error)
@@ -46,10 +41,13 @@ export default class Tus10 extends Plugin {
           percentage = Math.round(percentage)
 
           // Dispatch progress event
-          this.core.emitter.emit('progress', {
-            plugin: this,
-            percentage: percentage
+          this.core.emitter.emit('upload-progress', {
+            uploader: this,
+            id: file.id,
+            percentage: percentage,
+            done: false
           })
+          this.core.log(file)
         },
         onSuccess: () => {
           this.core.log(`Download ${upload.file.name} from ${upload.url}`)
@@ -60,6 +58,26 @@ export default class Tus10 extends Plugin {
     })
   }
 
+  install () {
+    this.core.emitter.on('new-next', () => {
+      console.log('began uploading!!..')
+      const selectedFiles = this.core.selectedFiles
+      window.selectedFiles = selectedFiles
+      const uploaders = []
+
+      Object.keys(selectedFiles).forEach((fileID, i) => {
+        const file = selectedFiles[fileID]
+        const current = parseInt(i, 10) + 1
+        const total = Object.keys(selectedFiles).length
+        uploaders.push(this.upload(file, current, total))
+      })
+
+      Promise.all(uploaders).then((result) => {
+        console.log('all uploaded!')
+      })
+    })
+  }
+
 /**
  * Add files to an array of `upload()` calles, passing the current and total file count numbers
  *