Browse Source

transloadit: cancel Assemblies when cancelling uploads

Renée Kooi 6 years ago
parent
commit
428da2bec1
2 changed files with 79 additions and 7 deletions
  1. 22 0
      packages/@uppy/transloadit/src/Client.js
  2. 57 7
      packages/@uppy/transloadit/src/index.js

+ 22 - 0
packages/@uppy/transloadit/src/Client.js

@@ -46,12 +46,24 @@ module.exports = class Client {
     })
   }
 
+  /**
+   * Reserve resources for a file in an Assembly. Then addFile can be used later.
+   *
+   * @param {object} assembly
+   * @param {UppyFile} file
+   */
   reserveFile (assembly, file) {
     const size = encodeURIComponent(file.size)
     return fetch(`${assembly.assembly_ssl_url}/reserve_file?size=${size}`, { method: 'post' })
       .then((response) => response.json())
   }
 
+  /**
+   * Import a remote file to an Assembly.
+   *
+   * @param {object} assembly
+   * @param {UppyFile} file
+   */
   addFile (assembly, file) {
     if (!file.uploadURL) {
       return Promise.reject(new Error('File does not have an `uploadURL`.'))
@@ -66,6 +78,16 @@ module.exports = class Client {
       .then((response) => response.json())
   }
 
+  /**
+   * Cancel a running Assembly.
+   *
+   * @param {object} assembly
+   */
+  cancelAssembly (assembly) {
+    return fetch(assembly.assembly_ssl_url, { method: 'delete' })
+      .then((response) => response.json())
+  }
+
   /**
    * Get the current status for an assembly.
    *

+ 57 - 7
packages/@uppy/transloadit/src/index.js

@@ -64,7 +64,8 @@ module.exports = class Transloadit extends Plugin {
 
     this._prepareUpload = this._prepareUpload.bind(this)
     this._afterUpload = this._afterUpload.bind(this)
-    this._handleError = this._handleError.bind(this)
+    this._onError = this._onError.bind(this)
+    this._onCancelAll = this._onCancelAll.bind(this)
     this._onFileUploadURLAvailable = this._onFileUploadURLAvailable.bind(this)
     this._onRestored = this._onRestored.bind(this)
     this._getPersistentData = this._getPersistentData.bind(this)
@@ -329,6 +330,52 @@ module.exports = class Transloadit extends Plugin {
     })
   }
 
+  _cancelAssembly (assembly) {
+    return this.client.cancelAssembly(assembly).then(() => {
+      // TODO bubble this through AssemblyWatcher so its event handlers can clean up correctly
+      this.uppy.emit('transloadit:assembly-cancelled', assembly)
+    })
+  }
+
+  /**
+   * When a file is removed from Uppy, cancel its corresponding Assembly.
+   */
+  _onFileRemoved (file) {
+    if (!file.transloadit) {
+      // No associated Assembly.
+      return
+    }
+
+    const assemblyID = file.transloadit.assembly
+    const assembly = this.getAssembly(assemblyID)
+
+    const assemblyContainsOtherFiles = this.getAssemblyFiles(assemblyID).length > 0
+    if (assemblyContainsOtherFiles) {
+      return
+    }
+
+    this.client.cancelAssembly(assembly).then(() => {
+      // TODO bubble this through AssemblyWatcher so its event handlers can clean up correctly
+      this.uppy.emit('transloadit:assembly-cancelled', assembly)
+    })
+  }
+
+  /**
+   * When all files are removed, cancel in-progress Assemblies.
+   */
+  _onCancelAll () {
+    const { assemblies } = this.getPluginState()
+
+    const cancelPromises = Object.keys(assemblies).map((assemblyID) => {
+      const assembly = this.getAssembly(assemblyID)
+      return this._cancelAssembly(assembly)
+    })
+
+    Promise.all(cancelPromises).catch((err) => {
+      this.uppy.log(err)
+    })
+  }
+
   /**
    * Custom state serialization for the Golden Retriever plugin.
    * It will pass this back to the `_onRestored` function.
@@ -632,8 +679,8 @@ module.exports = class Transloadit extends Plugin {
     })
   }
 
-  _handleError (err, uploadID) {
-    this.uppy.log(`[Transloadit] _handleError in upload ${uploadID}`)
+  _onError (err, uploadID) {
+    this.uppy.log(`[Transloadit] _onError in upload ${uploadID}`)
     this.uppy.log(err)
     const state = this.getPluginState()
     const assemblyIDs = state.uploadsAssemblies[uploadID]
@@ -650,7 +697,10 @@ module.exports = class Transloadit extends Plugin {
     this.uppy.addPostProcessor(this._afterUpload)
 
     // We may need to close socket.io connections on error.
-    this.uppy.on('error', this._handleError)
+    this.uppy.on('error', this._onError)
+
+    // Handle cancellation.
+    this.uppy.on('cancel-all', this._onCancelAll)
 
     if (this.opts.importFromUploadURLs) {
       // No uploader needed when importing; instead we take the upload URL from an existing uploader.
@@ -686,7 +736,7 @@ module.exports = class Transloadit extends Plugin {
   uninstall () {
     this.uppy.removePreProcessor(this._prepareUpload)
     this.uppy.removePostProcessor(this._afterUpload)
-    this.uppy.off('error', this._handleError)
+    this.uppy.off('error', this._onError)
 
     if (this.opts.importFromUploadURLs) {
       this.uppy.off('upload-success', this._onFileUploadURLAvailable)
@@ -694,8 +744,8 @@ module.exports = class Transloadit extends Plugin {
   }
 
   getAssembly (id) {
-    const state = this.getPluginState()
-    return state.assemblies[id]
+    const { assemblies } = this.getPluginState()
+    return assemblies[id]
   }
 
   getAssemblyFiles (assemblyID) {