Browse Source

Merge branch 'master' of https://github.com/transloadit/uppy

Artur Paikin 8 years ago
parent
commit
d349c31cc8

+ 31 - 0
src/core/Core.js

@@ -466,6 +466,37 @@ class Uppy {
     })
   }
 
+  /**
+   * Uninstall and remove a plugin.
+   *
+   * @param {Plugin} instance The plugin instance to remove.
+   */
+  removePlugin (instance) {
+    const list = this.plugins[instance.type]
+
+    if (instance.uninstall) {
+      instance.uninstall()
+    }
+
+    const index = list.indexOf(instance)
+    if (index !== -1) {
+      list.splice(index, 1)
+    }
+  }
+
+  /**
+   * Uninstall all plugins and close down this Uppy instance.
+   */
+  close () {
+    this.iteratePlugins((plugin) => {
+      plugin.uninstall()
+    })
+
+    if (this.socket) {
+      this.socket.close()
+    }
+  }
+
 /**
  * Logs stuff to console, only if `debug` is set to true. Silent in production.
  *

+ 48 - 20
src/plugins/Dashboard/index.js

@@ -69,6 +69,8 @@ module.exports = class DashboardUI extends Plugin {
     this.hideAllPanels = this.hideAllPanels.bind(this)
     this.showPanel = this.showPanel.bind(this)
     this.initEvents = this.initEvents.bind(this)
+    this.handleEscapeKeyPress = this.handleEscapeKeyPress.bind(this)
+    this.handleFileCard = this.handleFileCard.bind(this)
     this.handleDrop = this.handleDrop.bind(this)
     this.pauseAll = this.pauseAll.bind(this)
     this.resumeAll = this.resumeAll.bind(this)
@@ -166,6 +168,13 @@ module.exports = class DashboardUI extends Plugin {
     setTimeout(this.updateDashboardElWidth, 300)
   }
 
+  // Close the Modal on esc key press
+  handleEscapeKeyPress (event) {
+    if (event.keyCode === 27) {
+      this.hideModal()
+    }
+  }
+
   initEvents () {
     // const dashboardEl = this.target.querySelector(`${this.opts.target} .UppyDashboard`)
 
@@ -177,35 +186,29 @@ module.exports = class DashboardUI extends Plugin {
       this.core.log('Modal trigger wasn’t found')
     }
 
-    // Close the Modal on esc key press
-    document.body.addEventListener('keyup', (event) => {
-      if (event.keyCode === 27) {
-        this.hideModal()
-      }
-    })
+    document.body.addEventListener('keyup', this.handleEscapeKeyPress)
 
     // Drag Drop
-    dragDrop(this.el, (files) => {
+    this.removeDragDropListener = dragDrop(this.el, (files) => {
       this.handleDrop(files)
     })
   }
 
-  actions () {
-    const bus = this.core.bus
+  removeEvents () {
+    const showModalTrigger = findDOMElement(this.opts.trigger)
+    if (!this.opts.inline && showModalTrigger) {
+      showModalTrigger.removeEventListener('click', this.showModal)
+    }
 
-    bus.on('core:file-add', () => {
-      this.hideAllPanels()
-    })
+    this.removeDragDropListener()
+    document.body.removeEventListener('keyup', this.handleEscapeKeyPress)
+  }
 
-    bus.on('dashboard:file-card', (fileId) => {
-      const modal = this.core.getState().modal
+  actions () {
+    const bus = this.core.bus
 
-      this.core.setState({
-        modal: Object.assign({}, modal, {
-          fileCardFor: fileId || false
-        })
-      })
-    })
+    bus.on('core:file-add', this.hideAllPanels)
+    bus.on('dashboard:file-card', this.handleFileCard)
 
     window.addEventListener('resize', this.updateDashboardElWidth)
 
@@ -219,6 +222,15 @@ module.exports = class DashboardUI extends Plugin {
     // })
   }
 
+  removeActions () {
+    const bus = this.core.bus
+
+    window.removeEventListener('resize', this.updateDashboardElWidth)
+
+    bus.off('core:file-add', this.hideAllPanels)
+    bus.off('dashboard:file-card', this.handleFileCard)
+  }
+
   updateDashboardElWidth () {
     const dashboardEl = this.target.querySelector('.UppyDashboard-inner')
     const containerWidth = dashboardEl.offsetWidth
@@ -232,6 +244,16 @@ module.exports = class DashboardUI extends Plugin {
     })
   }
 
+  handleFileCard (fileId) {
+    const modal = this.core.getState().modal
+
+    this.core.setState({
+      modal: Object.assign({}, modal, {
+        fileCardFor: fileId || false
+      })
+    })
+  }
+
   handleDrop (files) {
     this.core.log('All right, someone dropped something...')
 
@@ -432,4 +454,10 @@ module.exports = class DashboardUI extends Plugin {
     this.initEvents()
     this.actions()
   }
+
+  uninstall () {
+    this.unmount()
+    this.removeActions()
+    this.removeEvents()
+  }
 }

+ 7 - 1
src/plugins/DragDrop/index.js

@@ -165,9 +165,15 @@ module.exports = class DragDrop extends Plugin {
     const plugin = this
     this.target = this.mount(target, plugin)
 
-    dragDrop(this.target.querySelector('.UppyDragDrop-container'), (files) => {
+    const dndContainer = this.target.querySelector('.UppyDragDrop-container')
+    this.removeDragDropListener = dragDrop(dndContainer, (files) => {
       this.handleDrop(files)
       this.core.log(files)
     })
   }
+
+  uninstall () {
+    this.removeDragDropListener()
+    this.unmount()
+  }
 }

+ 4 - 0
src/plugins/Dropbox/index.js

@@ -66,6 +66,10 @@ module.exports = class Dropbox extends Plugin {
     return
   }
 
+  uninstall () {
+    this.unmount()
+  }
+
   onAuth (authenticated) {
     this.view.updateState({authenticated})
     if (authenticated) {

+ 4 - 0
src/plugins/FileInput.js

@@ -80,4 +80,8 @@ module.exports = class FileInput extends Plugin {
     const plugin = this
     this.target = this.mount(target, plugin)
   }
+
+  uninstall () {
+    this.unmount()
+  }
 }

+ 4 - 0
src/plugins/GoogleDrive/index.js

@@ -64,6 +64,10 @@ module.exports = class Google extends Plugin {
     return
   }
 
+  uninstall () {
+    this.unmount()
+  }
+
   onAuth (authenticated) {
     this.view.updateState({authenticated})
     if (authenticated) {

+ 4 - 0
src/plugins/Informer.js

@@ -113,4 +113,8 @@ module.exports = class Informer extends Plugin {
     const plugin = this
     this.target = this.mount(target, plugin)
   }
+
+  uninstall () {
+    this.unmount()
+  }
 }

+ 15 - 7
src/plugins/MagicLog.js

@@ -19,16 +19,24 @@ module.exports = class MagicLog extends Plugin {
 
     // merge default options with the ones set by user
     this.opts = Object.assign({}, defaultOptions, opts)
+
+    this.handleStateUpdate = this.handleStateUpdate.bind(this)
+  }
+
+  handleStateUpdate (prev, state, patch) {
+    console.group('State')
+    console.log('Prev', prev)
+    console.log('Next', state)
+    console.log('Patch', patch)
+    console.groupEnd()
   }
 
   install () {
     const uppy = this.core.emitter
-    uppy.on('state-update', (prev, state, patch) => {
-      console.group('State')
-      console.log('Prev', prev)
-      console.log('Next', state)
-      console.log('Patch', patch)
-      console.groupEnd()
-    })
+    uppy.on('state-update', this.handleStateUpdate)
+  }
+
+  uninstall () {
+    this.core.emitter.off('state-update', this.handleStateUpdate)
   }
 }

+ 17 - 7
src/plugins/MetaData.js

@@ -17,6 +17,18 @@ module.exports = class MetaData extends Plugin {
 
     // merge default options with the ones set by user
     this.opts = Object.assign({}, defaultOptions, opts)
+
+    this.handleFileAdded = this.handleFileAdded.bind(this)
+  }
+
+  handleFileAdded (fileID) {
+    const metaFields = this.opts.fields
+
+    metaFields.forEach((item) => {
+      const obj = {}
+      obj[item.id] = item.value
+      this.core.updateMeta(obj, fileID)
+    })
   }
 
   addInitialMeta () {
@@ -26,16 +38,14 @@ module.exports = class MetaData extends Plugin {
       metaFields: metaFields
     })
 
-    this.core.emitter.on('file-added', (fileID) => {
-      metaFields.forEach((item) => {
-        const obj = {}
-        obj[item.id] = item.value
-        this.core.updateMeta(obj, fileID)
-      })
-    })
+    this.core.emitter.on('file-added', this.handleFileAdded)
   }
 
   install () {
     this.addInitialMeta()
   }
+
+  uninstall () {
+    this.core.emitter.off('file-added', this.handleFileAdded)
+  }
 }

+ 11 - 0
src/plugins/Plugin.js

@@ -25,6 +25,7 @@ module.exports = class Plugin {
     this.mount = this.mount.bind(this)
     this.focus = this.focus.bind(this)
     this.install = this.install.bind(this)
+    this.uninstall = this.uninstall.bind(this)
 
     // this.frame = null
   }
@@ -98,6 +99,12 @@ module.exports = class Plugin {
     }
   }
 
+  unmount () {
+    if (this.el && this.el.parentNode) {
+      this.el.parentNode.removeChild(this.el)
+    }
+  }
+
   focus () {
     return
   }
@@ -105,4 +112,8 @@ module.exports = class Plugin {
   install () {
     return
   }
+
+  uninstall () {
+    return
+  }
 }

+ 4 - 0
src/plugins/ProgressBar.js

@@ -38,4 +38,8 @@ module.exports = class ProgressBar extends Plugin {
     const plugin = this
     this.target = this.mount(target, plugin)
   }
+
+  uninstall () {
+    this.unmount()
+  }
 }

+ 4 - 0
src/plugins/Transloadit/Socket.js

@@ -37,6 +37,10 @@ module.exports = class TransloaditSocket {
       this.close()
     })
 
+    this.socket.on('assembly_upload_finished', (file) => {
+      this.emit('upload', file)
+    })
+
     this.socket.on('assembly_upload_meta_data_extracted', () => {
       this.emit('metadata')
     })

+ 46 - 3
src/plugins/Transloadit/index.js

@@ -113,16 +113,53 @@ module.exports = class Transloadit extends Plugin {
     return this.opts.waitForEncoding || this.opts.waitForMetadata
   }
 
+  // TODO if/when the transloadit API returns tus upload metadata in the
+  // file objects in the assembly status, change this to use a unique ID
+  // instead of checking the file name and size.
+  findFile ({ name, size }) {
+    const files = this.core.state.files
+    for (const id in files) {
+      if (!files.hasOwnProperty(id)) {
+        continue
+      }
+      if (files[id].name === name && files[id].size === size) {
+        return files[id]
+      }
+    }
+  }
+
+  onFileUploadComplete (uploadedFile) {
+    const file = this.findFile(uploadedFile)
+    this.updateState({
+      files: Object.assign({}, this.state.files, {
+        [uploadedFile.id]: {
+          id: file.id,
+          uploadedFile
+        }
+      })
+    })
+    this.core.bus.emit('transloadit:upload', uploadedFile)
+  }
+
+  onResult (stepName, result) {
+    const file = this.state.files[result.original_id]
+    result.localId = file.id
+    this.updateState({
+      results: this.state.results.concat(result)
+    })
+    this.core.bus.emit('transloadit:result', stepName, result)
+  }
+
   connectSocket () {
     this.socket = new StatusSocket(
       this.state.assembly.websocket_url,
       this.state.assembly
     )
 
+    this.socket.on('upload', this.onFileUploadComplete.bind(this))
+
     if (this.opts.waitForEncoding) {
-      this.socket.on('result', (stepName, result) => {
-        this.core.bus.emit('transloadit:result', stepName, result)
-      })
+      this.socket.on('result', this.onResult.bind(this))
     }
 
     this.assemblyReady = new Promise((resolve, reject) => {
@@ -179,6 +216,12 @@ module.exports = class Transloadit extends Plugin {
   install () {
     this.core.addPreProcessor(this.prepareUpload)
     this.core.addPostProcessor(this.afterUpload)
+
+    this.updateState({
+      assembly: null,
+      files: {},
+      results: []
+    })
   }
 
   uninstall () {

+ 5 - 0
src/plugins/Webcam/index.js

@@ -216,6 +216,11 @@ module.exports = class Webcam extends Plugin {
     this.target = this.mount(target, plugin)
   }
 
+  uninstall () {
+    this.webcam.reset()
+    this.unmount()
+  }
+
   /**
    * Little shorthand to update the state with my new state
    */