Przeglądaj źródła

Merge branch 'master' into chore/fileID-to-file

Artur Paikin 7 lat temu
rodzic
commit
e80b9a75e3

+ 15 - 1
CHANGELOG.md

@@ -103,7 +103,7 @@ To be released: 2018-03-01.
 - [ ] goldenretriever: add “ghost” files (@arturi)
 - [ ] goldenretriever: add “ghost” files (@arturi)
 - [ ] core: i18n all strings + document them
 - [ ] core: i18n all strings + document them
 - [ ] core: update file-type
 - [ ] core: update file-type
-- [ ] goldenretriever: warn, not error, when files cannot be saved by goldenretriever (@goto-bus-stop)
+- [x] goldenretriever: warn, not error, when files cannot be saved by goldenretriever (#641 / @goto-bus-stop)
 - [ ] docs: quick start guide: https://community.transloadit.com/t/quick-start-guide-would-be-really-helpful/14605 (@arturi)
 - [ ] docs: quick start guide: https://community.transloadit.com/t/quick-start-guide-would-be-really-helpful/14605 (@arturi)
 - [ ] docs: on writing plugins (@goto-bus-stop)
 - [ ] docs: on writing plugins (@goto-bus-stop)
 - [ ] docs: all useful events (@arturi)
 - [ ] docs: all useful events (@arturi)
@@ -115,6 +115,20 @@ To be released: 2018-03-01.
 - [ ] xhrupload: emit a final `upload-progress` event in the XHRUpload plugin just before firing `upload-complete` (tus-js-client already handles this internally) (@arturi)
 - [ ] xhrupload: emit a final `upload-progress` event in the XHRUpload plugin just before firing `upload-complete` (tus-js-client already handles this internally) (@arturi)
 - [x] s3: fix xhr response handlers (#625, @goto-bus-stop)
 - [x] s3: fix xhr response handlers (#625, @goto-bus-stop)
 - [ ] test: add typescript with JSDoc (@arturi)
 - [ ] test: add typescript with JSDoc (@arturi)
+- [ ] dragdrop: allow customizing arrow icon https://github.com/transloadit/uppy/pull/374#issuecomment-334116208 (@arturi)
+
+## 0.23.1
+
+- xhrupload: ⚠️ **breaking** Revamped XHR response handling: This adds a response key to files when the upload completed (regardless of whether it succeeded). file.response contains a status and a data property. data is the result of getResponseData. One change here is that getResponseData is also called if there was an error, not sure if that's a good idea; Also changed events to emit file objects instead of IDs here because it touches many of the same places. (#612 / @goto-bus-stop)
+- transloadit: ⚠️ **breaking** Embeded tus plugin: When importFromUploadURLs is not set, add the Tus plugin with the right configuration. (#614 / @goto-bus-stop)
+- transloadit: Allow easy passing of form fields (#593 / @goto-bus-stop)
+- s3: Updated XHR response handling, fixes (#624 / @goto-bus-stop)
+- core: Revamped `addFile()` rejections (#604 / @goto-bus-stop)
+- core: Added wrapper function for emitter.on, so you can chain uppy.on().run()... (#597 / @arturi)
+- core: Fix progress events causing errors for removed files (#638 / @arturi)
+- statusbar: Use translations for Uploading / Paused text, fixes #629 (#640 / goto-bus-stop)
+- thumbnailgenerator: Upsizing image if smaller than thumbnail size, fix infinite loop (#637 / @phitranphitranphitran)
+- website: Added Transloadit example to website (#603 / @arturi)
 
 
 ## 0.23.0
 ## 0.23.0
 
 

+ 5 - 5
README.md

@@ -5,9 +5,9 @@
 <a href="https://www.npmjs.com/package/uppy"><img src="https://img.shields.io/npm/v/uppy.svg?style=flat-square"></a>
 <a href="https://www.npmjs.com/package/uppy"><img src="https://img.shields.io/npm/v/uppy.svg?style=flat-square"></a>
 <a href="https://travis-ci.org/transloadit/uppy"><img src="https://img.shields.io/travis/transloadit/uppy/master.svg?style=flat-square" alt="Build Status"></a>
 <a href="https://travis-ci.org/transloadit/uppy"><img src="https://img.shields.io/travis/transloadit/uppy/master.svg?style=flat-square" alt="Build Status"></a>
 
 
-Uppy is a sleek, modular file uploader that integrates seamlessly with any application. It’s fast, easy to use and lets you worry about more important problems than building a file uploader.
+Uppy is a sleek, modular JavaScript file uploader that integrates seamlessly with any application. It’s fast, easy to use and lets you worry about more important problems than building a file uploader.
 
 
-- **Fetch** files from local disk, Google Drive, Dropbox, Instagram, or snap and record selfies with a camera;
+- **Fetch** files from local disk, remote urls, Google Drive, Dropbox, Instagram, or snap and record selfies with a camera;
 - **Preview** and edit metadata with a nice interface;
 - **Preview** and edit metadata with a nice interface;
 - **Upload** to the final destination, optionally process/encode
 - **Upload** to the final destination, optionally process/encode
 
 
@@ -64,7 +64,7 @@ $ npm install uppy --save
 
 
 We recommend installing from npm and then using a module bundler such as [Webpack](http://webpack.github.io/), [Browserify](http://browserify.org/) or [Rollup.js](http://rollupjs.org/).
 We recommend installing from npm and then using a module bundler such as [Webpack](http://webpack.github.io/), [Browserify](http://browserify.org/) or [Rollup.js](http://rollupjs.org/).
 
 
-Add CSS [uppy.min.css](https://transloadit.edgly.net/releases/uppy/v0.23.0/dist/uppy.min.css), either to `<head>` of your HTML page or include in JS, if your bundler of choice supports it — transforms and plugins are available for Browserify and Webpack.
+Add CSS [uppy.min.css](https://transloadit.edgly.net/releases/uppy/v0.23.1/dist/uppy.min.css), either to `<head>` of your HTML page or include in JS, if your bundler of choice supports it — transforms and plugins are available for Browserify and Webpack.
 
 
 Alternatively, you can also use a pre-built bundle from Transloadit's CDN: Edgly. In that case `Uppy` will attach itself to the global `window.Uppy` object.
 Alternatively, you can also use a pre-built bundle from Transloadit's CDN: Edgly. In that case `Uppy` will attach itself to the global `window.Uppy` object.
 
 
@@ -73,12 +73,12 @@ Alternatively, you can also use a pre-built bundle from Transloadit's CDN: Edgly
 1\. Add a script to the bottom of `<body>`:
 1\. Add a script to the bottom of `<body>`:
 
 
 ``` html
 ``` html
-<script src="https://transloadit.edgly.net/releases/uppy/v0.23.0/dist/uppy.min.js"></script>
+<script src="https://transloadit.edgly.net/releases/uppy/v0.23.1/dist/uppy.min.js"></script>
 ```
 ```
 
 
 2\. Add CSS to `<head>`:
 2\. Add CSS to `<head>`:
 ``` html
 ``` html
-<link href="https://transloadit.edgly.net/releases/uppy/v0.23.0/dist/uppy.min.css" rel="stylesheet">
+<link href="https://transloadit.edgly.net/releases/uppy/v0.23.1/dist/uppy.min.css" rel="stylesheet">
 ```
 ```
 
 
 3\. Initialize:
 3\. Initialize:

+ 1 - 1
bin/upload-to-cdn.sh

@@ -8,7 +8,7 @@
 #  - Checks if a tag is being built (on Travis - otherwise opts to continue execution regardless)
 #  - Checks if a tag is being built (on Travis - otherwise opts to continue execution regardless)
 #  - Installs AWS CLI if needed
 #  - Installs AWS CLI if needed
 #  - Assumed a fully built uppy is in root dir (unless a specific tag was specified, then it's fetched from npm)
 #  - Assumed a fully built uppy is in root dir (unless a specific tag was specified, then it's fetched from npm)
-#  - Runs npm pack, and stores files to e.g. https://transloadit.edgly.net/releases/uppy/v0.23.0/dist/uppy.css
+#  - Runs npm pack, and stores files to e.g. https://transloadit.edgly.net/releases/uppy/v0.23.1/dist/uppy.css
 #  - Uses local package by default, if [version] argument was specified, takes package from npm
 #  - Uses local package by default, if [version] argument was specified, takes package from npm
 #
 #
 # Run as:
 # Run as:

+ 2 - 2
examples/cdn-example/index.html

@@ -4,11 +4,11 @@
     <title></title>
     <title></title>
     <meta charset="UTF-8">
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <meta name="viewport" content="width=device-width, initial-scale=1">
-    <link href="https://transloadit.edgly.net/releases/uppy/v0.23.0/dist/uppy.min.css" rel="stylesheet">
+    <link href="https://transloadit.edgly.net/releases/uppy/v0.23.1/dist/uppy.min.css" rel="stylesheet">
   </head>
   </head>
   <body>
   <body>
     <button id="uppyModalOpener">Open Modal</button>
     <button id="uppyModalOpener">Open Modal</button>
-    <script src="https://transloadit.edgly.net/releases/uppy/v0.23.0/dist/uppy.min.js"></script>
+    <script src="https://transloadit.edgly.net/releases/uppy/v0.23.1/dist/uppy.min.js"></script>
     <script>
     <script>
       const uppy = Uppy.Core({debug: true, autoProceed: false})
       const uppy = Uppy.Core({debug: true, autoProceed: false})
         .use(Uppy.Dashboard, { trigger: '#uppyModalOpener' })
         .use(Uppy.Dashboard, { trigger: '#uppyModalOpener' })

+ 2 - 2
examples/uppy-with-server/client/index.html

@@ -4,11 +4,11 @@
     <title></title>
     <title></title>
     <meta charset="UTF-8">
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <meta name="viewport" content="width=device-width, initial-scale=1">
-    <link href="https://transloadit.edgly.net/releases/uppy/v0.23.0/dist/uppy.min.css" rel="stylesheet">
+    <link href="https://transloadit.edgly.net/releases/uppy/v0.23.1/dist/uppy.min.css" rel="stylesheet">
   </head>
   </head>
   <body>
   <body>
     <button id="uppyModalOpener">Open Modal</button>
     <button id="uppyModalOpener">Open Modal</button>
-    <script src="https://transloadit.edgly.net/releases/uppy/v0.23.0/dist/uppy.min.js"></script>
+    <script src="https://transloadit.edgly.net/releases/uppy/v0.23.1/dist/uppy.min.js"></script>
     <script>
     <script>
       const uppy = Uppy.Core({debug: true, autoProceed: false})
       const uppy = Uppy.Core({debug: true, autoProceed: false})
         .use(Uppy.Dashboard, { trigger: '#uppyModalOpener' })
         .use(Uppy.Dashboard, { trigger: '#uppyModalOpener' })

+ 1 - 1
package-lock.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "uppy",
   "name": "uppy",
-  "version": "0.23.0",
+  "version": "0.23.1",
   "lockfileVersion": 1,
   "lockfileVersion": 1,
   "requires": true,
   "requires": true,
   "dependencies": {
   "dependencies": {

+ 3 - 6
package.json

@@ -1,7 +1,7 @@
 {
 {
   "name": "uppy",
   "name": "uppy",
-  "version": "0.23.0",
-  "description": "Extensible file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Dropbox and Google Drive, S3 and more :dog:",
+  "version": "0.23.1",
+  "description": "Extensible JavaScript file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Instagram, Dropbox, Google Drive, S3 and more :dog:",
   "main": "lib/index.js",
   "main": "lib/index.js",
   "jsnext:main": "src/index.js",
   "jsnext:main": "src/index.js",
   "unpkg": "dist/uppy.min.js",
   "unpkg": "dist/uppy.min.js",
@@ -38,7 +38,7 @@
   "bugs": {
   "bugs": {
     "url": "https://github.com/transloadit/uppy/issues"
     "url": "https://github.com/transloadit/uppy/issues"
   },
   },
-  "homepage": "https://github.com/transloadit/uppy#readme",
+  "homepage": "https://uppy.io",
   "jest": {
   "jest": {
     "testPathIgnorePatterns": [
     "testPathIgnorePatterns": [
       "lib"
       "lib"
@@ -136,14 +136,11 @@
     "release": "npm version ${SEMANTIC:-patch} -m \"Release %s\" && npm run replace:versions && git commit -m \"Change Uppy version references to v$npm_package_version\" ./examples/ README.md bin/upload-to-cdn.sh website/src/examples/ website/src/docs/ website/themes/uppy/layout/ && git push && git push --tags && npm publish",
     "release": "npm version ${SEMANTIC:-patch} -m \"Release %s\" && npm run replace:versions && git commit -m \"Change Uppy version references to v$npm_package_version\" ./examples/ README.md bin/upload-to-cdn.sh website/src/examples/ website/src/docs/ website/themes/uppy/layout/ && git push && git push --tags && npm publish",
     "start:server": "node bin/start-server",
     "start:server": "node bin/start-server",
     "start": "npm-run-all --parallel watch start:server web:preview",
     "start": "npm-run-all --parallel watch start:server web:preview",
-    "test:acceptance:handleservers": "bin/bootandkill-servers node test/acceptance/index.js",
     "test:acceptance": "./bin/endtoend-build && wdio test/endtoend/wdio.remote.conf.js",
     "test:acceptance": "./bin/endtoend-build && wdio test/endtoend/wdio.remote.conf.js",
     "test:acceptance:local": "./bin/endtoend-build && wdio test/endtoend/wdio.local.conf.js",
     "test:acceptance:local": "./bin/endtoend-build && wdio test/endtoend/wdio.local.conf.js",
     "test:unit": "jest --testPathPattern=./src --coverage",
     "test:unit": "jest --testPathPattern=./src --coverage",
     "test": "npm run lint && npm run test:unit",
     "test": "npm run lint && npm run test:unit",
     "test:watch": "jest --watch --testPathPattern=src",
     "test:watch": "jest --watch --testPathPattern=src",
-    "test:serve": "npm-run-all web:build --parallel start:server web:serve",
-    "test:next-update": "next-update",
     "travis:deletecache": "travis cache --delete",
     "travis:deletecache": "travis cache --delete",
     "watch:css": "onchange 'src/scss/**/*.scss' --initial --verbose -- npm run build:css",
     "watch:css": "onchange 'src/scss/**/*.scss' --initial --verbose -- npm run build:css",
     "watch:js": "onchange 'src/**/*.js' --initial --verbose -- npm run build:bundle",
     "watch:js": "onchange 'src/**/*.js' --initial --verbose -- npm run build:bundle",

+ 54 - 0
src/locales/es_ES.js

@@ -0,0 +1,54 @@
+/* eslint camelcase: 0 */
+
+const es_ES = {}
+
+es_ES.strings = {
+  chooseFile: 'Selecciona un fichero',
+  youHaveChosen: 'Has seleccionado: %{fileName}',
+  orDragDrop: 'o arrástralo aquí',
+  filesChosen: {
+    0: '%{smart_count} fichero seleccionado',
+    1: '%{smart_count} ficheros seleccionados'
+  },
+  filesUploaded: {
+    0: '%{smart_count} fichero subido',
+    1: '%{smart_count} ficheros subidos'
+  },
+  files: {
+    0: '%{smart_count} fichero',
+    1: '%{smart_count} ficheros'
+  },
+  uploadFiles: {
+    0: 'Subir %{smart_count} fichero',
+    1: 'Subir %{smart_count} ficheros'
+  },
+  selectToUpload: 'Selecciona los ficheros a subir',
+  closeModal: 'Cerrar modal',
+  upload: 'Subir',
+  importFrom: 'Importar ficheros desde',
+  dashboardWindowTitle: 'Panel de Uppy (Pulsa escape para cerrar)',
+  dashboardTitle: 'Panel de Uppy',
+  copyLinkToClipboardSuccess: 'Enlace copiado al portapapeles.',
+  copyLinkToClipboardFallback: 'Copiar la siguiente URL',
+  done: 'Hecho',
+  localDisk: 'Disco local',
+  dropPasteImport: 'Arrasta ficheros aquí, pega, importa de alguno de los servicios de arriba o',
+  dropPaste: 'Arrastra ficheros aquí, pega o',
+  browse: 'navegar',
+  fileProgress: 'Progreso: velocidad de subida y tiempo estimado',
+  numberOfSelectedFiles: 'Número de ficheros seleccionados',
+  uploadAllNewFiles: 'Subir todos los nuevos ficheros'
+}
+
+es_ES.pluralize = function (n) {
+  if (n === 1) {
+    return 0
+  }
+  return 1
+}
+
+if (typeof window !== 'undefined' && typeof window.Uppy !== 'undefined') {
+  window.Uppy.locales.es_ES = es_ES
+}
+
+module.exports = es_ES

+ 29 - 10
src/plugins/GoldenRetriever/index.js

@@ -126,11 +126,13 @@ module.exports = class GoldenRetriever extends Plugin {
       if (numberOfFilesRecovered === numberOfFilesTryingToRecover) {
       if (numberOfFilesRecovered === numberOfFilesTryingToRecover) {
         this.uppy.log(`[GoldenRetriever] Successfully recovered ${numberOfFilesRecovered} blobs from Service Worker!`)
         this.uppy.log(`[GoldenRetriever] Successfully recovered ${numberOfFilesRecovered} blobs from Service Worker!`)
         this.uppy.info(`Successfully recovered ${numberOfFilesRecovered} files`, 'success', 3000)
         this.uppy.info(`Successfully recovered ${numberOfFilesRecovered} files`, 'success', 3000)
-        this.onBlobsLoaded(blobs)
-      } else {
-        this.uppy.log('[GoldenRetriever] Failed to recover blobs from Service Worker, trying IndexedDB now...')
-        this.loadFileBlobsFromIndexedDB()
+        return this.onBlobsLoaded(blobs)
       }
       }
+      this.uppy.log('[GoldenRetriever] No blobs found in Service Worker, trying IndexedDB now...')
+      return this.loadFileBlobsFromIndexedDB()
+    }).catch((err) => {
+      this.uppy.log('[GoldenRetriever] Failed to recover blobs from Service Worker', 'warning')
+      this.uppy.log(err)
     })
     })
   }
   }
 
 
@@ -139,11 +141,14 @@ module.exports = class GoldenRetriever extends Plugin {
       const numberOfFilesRecovered = Object.keys(blobs).length
       const numberOfFilesRecovered = Object.keys(blobs).length
 
 
       if (numberOfFilesRecovered > 0) {
       if (numberOfFilesRecovered > 0) {
-        this.uppy.log(`[GoldenRetriever] Successfully recovered ${numberOfFilesRecovered} blobs from Indexed DB!`)
+        this.uppy.log(`[GoldenRetriever] Successfully recovered ${numberOfFilesRecovered} blobs from IndexedDB!`)
         this.uppy.info(`Successfully recovered ${numberOfFilesRecovered} files`, 'success', 3000)
         this.uppy.info(`Successfully recovered ${numberOfFilesRecovered} files`, 'success', 3000)
         return this.onBlobsLoaded(blobs)
         return this.onBlobsLoaded(blobs)
       }
       }
-      this.uppy.log('[GoldenRetriever] Couldn’t recover anything from IndexedDB :(')
+      this.uppy.log('[GoldenRetriever] No blobs found in IndexedDB')
+    }).catch((err) => {
+      this.uppy.log('[GoldenRetriever] Failed to recover blobs from IndexedDB', 'warning')
+      this.uppy.log(err)
     })
     })
   }
   }
 
 
@@ -178,6 +183,9 @@ module.exports = class GoldenRetriever extends Plugin {
     if (obsoleteBlobs.length) {
     if (obsoleteBlobs.length) {
       this.deleteBlobs(obsoleteBlobs).then(() => {
       this.deleteBlobs(obsoleteBlobs).then(() => {
         this.uppy.log(`[GoldenRetriever] Cleaned up ${obsoleteBlobs.length} old files`)
         this.uppy.log(`[GoldenRetriever] Cleaned up ${obsoleteBlobs.length} old files`)
+      }).catch((err) => {
+        this.uppy.log(`[GoldenRetriever] Could not clean up ${obsoleteBlobs.length} old files`, 'warning')
+        this.uppy.log(err)
       })
       })
     }
     }
   }
   }
@@ -216,26 +224,37 @@ module.exports = class GoldenRetriever extends Plugin {
 
 
       if (this.ServiceWorkerStore) {
       if (this.ServiceWorkerStore) {
         this.ServiceWorkerStore.put(file).catch((err) => {
         this.ServiceWorkerStore.put(file).catch((err) => {
-          this.uppy.log('[GoldenRetriever] Could not store file', 'error')
+          this.uppy.log('[GoldenRetriever] Could not store file', 'warning')
           this.uppy.log(err)
           this.uppy.log(err)
         })
         })
       }
       }
 
 
       this.IndexedDBStore.put(file).catch((err) => {
       this.IndexedDBStore.put(file).catch((err) => {
-        this.uppy.log('[GoldenRetriever] Could not store file', 'error')
+        this.uppy.log('[GoldenRetriever] Could not store file', 'warning')
         this.uppy.log(err)
         this.uppy.log(err)
       })
       })
     })
     })
 
 
     this.uppy.on('file-removed', (file) => {
     this.uppy.on('file-removed', (file) => {
-      if (this.ServiceWorkerStore) this.ServiceWorkerStore.delete(file.id)
-      this.IndexedDBStore.delete(file.id)
+      if (this.ServiceWorkerStore) {
+        this.ServiceWorkerStore.delete(file.id).catch((err) => {
+          this.uppy.log('[GoldenRetriever] Failed to remove file', 'warning')
+          this.uppy.log(err)
+        })
+      }
+      this.IndexedDBStore.delete(file.id).catch((err) => {
+        this.uppy.log('[GoldenRetriever] Failed to remove file', 'warning')
+        this.uppy.log(err)
+      })
     })
     })
 
 
     this.uppy.on('complete', ({ successful }) => {
     this.uppy.on('complete', ({ successful }) => {
       const fileIDs = successful.map((file) => file.id)
       const fileIDs = successful.map((file) => file.id)
       this.deleteBlobs(fileIDs).then(() => {
       this.deleteBlobs(fileIDs).then(() => {
         this.uppy.log(`[GoldenRetriever] Removed ${successful.length} files that finished uploading`)
         this.uppy.log(`[GoldenRetriever] Removed ${successful.length} files that finished uploading`)
+      }).catch((err) => {
+        this.uppy.log(`[GoldenRetriever] Could not remove ${successful.length} files that finished uploading`, 'warning')
+        this.uppy.log(err)
       })
       })
     })
     })
 
 

+ 9 - 6
src/plugins/Tus.js

@@ -202,6 +202,13 @@ module.exports = class Tus extends Plugin {
   uploadRemote (file, current, total) {
   uploadRemote (file, current, total) {
     this.resetUploaderReferences(file.id)
     this.resetUploaderReferences(file.id)
 
 
+    const opts = Object.assign(
+      {},
+      this.opts,
+      // Install file-specific upload overrides.
+      file.tus || {}
+    )
+
     return new Promise((resolve, reject) => {
     return new Promise((resolve, reject) => {
       this.uppy.log(file.remote.url)
       this.uppy.log(file.remote.url)
       if (file.serverToken) {
       if (file.serverToken) {
@@ -210,11 +217,6 @@ module.exports = class Tus extends Plugin {
           .catch(reject)
           .catch(reject)
       }
       }
 
 
-      let endpoint = this.opts.endpoint
-      if (file.tus && file.tus.endpoint) {
-        endpoint = file.tus.endpoint
-      }
-
       this.uppy.emit('upload-started', file)
       this.uppy.emit('upload-started', file)
 
 
       fetch(file.remote.url, {
       fetch(file.remote.url, {
@@ -225,7 +227,8 @@ module.exports = class Tus extends Plugin {
           'Content-Type': 'application/json'
           'Content-Type': 'application/json'
         },
         },
         body: JSON.stringify(Object.assign({}, file.remote.body, {
         body: JSON.stringify(Object.assign({}, file.remote.body, {
-          endpoint,
+          endpoint: opts.endpoint,
+          uploadUrl: opts.uploadUrl,
           protocol: 'tus',
           protocol: 'tus',
           size: file.data.size,
           size: file.data.size,
           metadata: file.meta
           metadata: file.meta

+ 2 - 2
src/plugins/Url/index.js

@@ -83,7 +83,7 @@ module.exports = class Url extends Plugin {
   }
   }
 
 
   addFile (url) {
   addFile (url) {
-    this.getMeta(url).then((meta) => {
+    return this.getMeta(url).then((meta) => {
       const tagFile = {
       const tagFile = {
         source: this.id,
         source: this.id,
         name: this.getFileNameFromUrl(url),
         name: this.getFileNameFromUrl(url),
@@ -106,7 +106,7 @@ module.exports = class Url extends Plugin {
       }
       }
 
 
       this.uppy.log('[Url] Adding remote file')
       this.uppy.log('[Url] Adding remote file')
-      this.uppy.addFile(tagFile)
+      return this.uppy.addFile(tagFile)
         .then(() => {
         .then(() => {
           const dashboard = this.uppy.getPlugin('Dashboard')
           const dashboard = this.uppy.getPlugin('Dashboard')
           if (dashboard) dashboard.hideAllPanels()
           if (dashboard) dashboard.hideAllPanels()

+ 1 - 1
src/plugins/XHRUpload.js

@@ -234,7 +234,7 @@ module.exports = class XHRUpload extends Plugin {
 
 
           return resolve(file)
           return resolve(file)
         } else {
         } else {
-          const body = opts.getResponseData(xhr)
+          const body = opts.getResponseData(xhr.responseText, xhr)
           const error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr))
           const error = buildResponseError(xhr, opts.getResponseError(xhr.responseText, xhr))
 
 
           const response = {
           const response = {

+ 35 - 33
website/src/_posts/2018-02-0.23.md

@@ -2,17 +2,17 @@
 title: "Uppy 0.23: Import from Url, refactored thumbnail generation, XHR bundle"
 title: "Uppy 0.23: Import from Url, refactored thumbnail generation, XHR bundle"
 date: 2018-02-12
 date: 2018-02-12
 author: arturi
 author: arturi
-published: false
+published: true
 ---
 ---
 
 
 Hi all! We are back from holidays with a shiny new `0.23.0` release for you! It’s packed with a new `Url` plugin (imports files from urls), refactored `ThumbnailGenerator`, `Webcam` improvements and more.
 Hi all! We are back from holidays with a shiny new `0.23.0` release for you! It’s packed with a new `Url` plugin (imports files from urls), refactored `ThumbnailGenerator`, `Webcam` improvements and more.
 
 
 ## Import from Url
 ## Import from Url
 
 
-Meet our new “Provider” plugin, `Url`. It’s simple, but powerful: paste a link to any file on the web, and Uppy with Uppy Server will upload it wherever you need.
+Meet our new “Provider” plugin, `Url`. It’s simple, yet powerful: paste a link to any file on the web, and Uppy with Uppy Server will upload it wherever you need.
 
 
 ```js
 ```js
-uppy.use(Url, { host: YOUR_UPPY_SERVER_URL })
+uppy.use(Url, { target: Dashboard, host: YOUR_UPPY_SERVER_URL })
 ```
 ```
 
 
 <figure class="wide"><video alt="Demo video showing Uppy with Url plugin that imports files from urls" controls autoplay><source src="/images/blog/0.23/uppy-url-demo.mp4" type="video/mp4">Your browser does not support the video tag, you can <a href="/images/blog/0.23/uppy-url-demo.mp4">download the video</a> to watch it.</video></figure>
 <figure class="wide"><video alt="Demo video showing Uppy with Url plugin that imports files from urls" controls autoplay><source src="/images/blog/0.23/uppy-url-demo.mp4" type="video/mp4">Your browser does not support the video tag, you can <a href="/images/blog/0.23/uppy-url-demo.mp4">download the video</a> to watch it.</video></figure>
@@ -21,13 +21,15 @@ uppy.use(Url, { host: YOUR_UPPY_SERVER_URL })
 
 
 ## ThumbnailGenerator
 ## ThumbnailGenerator
 
 
-Thumbnail generation has been refactored to a separate `ThumbnailGenerator` plugin, thanks to a PR from [@richardwillars](https://github.com/richardwillars). So Uppy Core is now more lightweight for when you don’t need previews. 
+Thumbnail generation has been refactored to a separate `ThumbnailGenerator` plugin, thanks to the PR from [@richardwillars](https://github.com/richardwillars). So Uppy Core is now more lightweight, if you don’t need previews.
 
 
-`ThumbnailGenerator` is still bundled with our most feature complete Dashboard plugin, so you don’t have to change anything if you were using that.
+`ThumbnailGenerator` is still bundled with our most feature complete `Dashboard` plugin though, so you don’t have to change anything if you were using that.
+
+We’ve also fixed previews in Safari and tweaked the code slightly after reading the excellent [Image resize in browsers is broken](https://blog.uploadcare.com/image-resize-in-browsers-is-broken-e38eed08df01) post by Uploadcare 👌.
 
 
 ## Processing results
 ## Processing results
 
 
-Processing results, from encoding plugins like Transloadit, are now added to `complete` event:
+Processing results from encoding plugins like [`Transloadit`](https://uppy.io/docs/transloadit/), are now added to `complete` event:
 
 
 ```js
 ```js
 uppy.on('complete', (result) => {
 uppy.on('complete', (result) => {
@@ -41,7 +43,7 @@ uppy.on('complete', (result) => {
 })
 })
 ```
 ```
 
 
-And to upload promise too:
+And to `uppy.upload()` promise result too:
 
 
 ```js
 ```js
 uppy.upload().then((result) => {
 uppy.upload().then((result) => {
@@ -49,7 +51,7 @@ uppy.upload().then((result) => {
 })
 })
 ```
 ```
 
 
-You can still use events like `transloadit:result`, its just easier when things are in the same place. Plugins can use new `uppy.addResultData()` API to add data to the `result`, like so:
+You can still use events like [`transloadit:result`](https://uppy.io/docs/transloadit/#transloadit-result), its just easier when things are in the same place. Plugins can use the new `uppy.addResultData()` API to add data to the `result`, like so:
 
 
 ```js
 ```js
 uppy.addResultData(uploadID, { transloadit: assemblies })
 uppy.addResultData(uploadID, { transloadit: assemblies })
@@ -57,44 +59,40 @@ uppy.addResultData(uploadID, { transloadit: assemblies })
 
 
 ## Webcam
 ## Webcam
 
 
-Webcam plugin now mirrors image previews by default, so that when you are making a selfie and wave with your right hand, you see that right hand of yours in the Webcam preview, just like in the mirror. This option can be disabled via `.use(Webcam, { mirror: false }`. Note that the resulting image will not be mirrored, so your hand will actually be waving on the left. This mimics the behaviour of smarphone selfie cameras.
+The Webcam plugin now mirrors image previews by default, so when you are making a selfie and wave with your right hand, you see that right hand in the Webcam preview, just like in the mirror. This option can be disabled via `uppy.use(Webcam, { mirror: false }`. Note that the resulting image will not be mirrored, so your hand will actually be waving on the left. This mimics the behaviour of smarphone selfie cameras.
 
 
-We’ve also added an option to select which camera will be used to capture pictures or video: [facingMode](https://uppy.io/docs/webcam/#facingMode-39-user-39) set to `user` (front camera) by default.
+We’ve also added an option to select which camera will be used to capture pictures or video: [facingMode](https://uppy.io/docs/webcam/#facingMode-39-user-39), set to `user` (front camera) by default.
 
 
 ## Server
 ## Server
 
 
-- You can now specify a config path when starting the standalone Uppy Server like so `uppy-server --config /path/to/uppyconf.json`. The config file is expected to be a json file with the same schema as the [uppy-server options](https://uppy.io/docs/server/#Options).
-- A periodic cleanup job has been added to Uppy Server, to delete stale upload files from the specified `filePath`. Even though we'd rarely expect uploaded files to go undeleted immediately, there could be cases where an error occurs during an upload, and so uppy-server leaves the file undeleted to give room for upload retries. With the cleanup job in place, we can ensure that this file would eventually be deleted after the file upload is done.
-- Responses from Multipart uploads are now relayed to Uppy Client as they are received from the upload server. With this in place, you can now handle responses from local and remote XHRUpload in nearly the same way.
+- You can now specify a config path when starting the standalone Uppy Server like so `uppy-server --config /path/to/uppyconf.json`. The config file is expected to be a JSON file with the same schema as the [Uppy Server options](https://uppy.io/docs/server/#Options).
+- A periodic cleanup job has been added to Uppy Server, to delete stale upload files from the specified `filePath`. Even though we'd rarely expect uploaded files to go undeleted immediately, there could be cases where an error occurs during an upload, and so Uppy Server leaves the file undeleted to give room for upload retries. With the cleanup job in place, we can ensure that this file would eventually be deleted after the file upload is done.
+- Responses from Multipart uploads are now relayed to Uppy Client as they are received from the target server. With this in place, you can now handle responses from local and remote XHRUpload in nearly the same way.
 
 
-## Improvements
+## Other Improvements and Additions
 
 
-- New option to hide ProgressBar and StatusBar after upload finish (#485 / @wilkoklak)
-- Chaining API has been improved, you can now use `.on` and `.off` anywhere: `uppy.use(Dashboard).use(Tus).on('complete', handleComplete).run()`.
-- We now pass response from uppy-server upload’s endpoint.
-- Transloadit plugin now has a new `transloadit:assembly-executing` event and assembly results to to the `complete` callback (#547, #527 / @goto-bus-stop).
-- We’ve added `bundle` option to `XHRUpload` plugin send multiple files in one request (#442 / @goto-bus-stop)
+- Added new option to hide ProgressBar and StatusBar after upload finish (#485 / @wilkoklak)
+- Chaining API has been improved, you can now use `.on` and `.off` anywhere: `uppy.use(Dashboard).use(Tus).on('complete', handleComplete).run()`
+- The Transloadit plugin now has a new `transloadit:assembly-executing` event and passes Assembly results to the `complete` callback (#547, #527 / @goto-bus-stop)
+- We’ve added a `bundle` option to the `XHRUpload` plugin to send multiple files in one request (#442 / @goto-bus-stop)
+- Uppy releases are now hosted on Edgly CDN by Transloadit
+- A Third-party extension for integrating the Ngrx Angular state management library with Uppy has been released, [uppy-store-ngrx](https://github.com/rimlin/uppy-store-ngrx/) by @rimlin
 
 
-## Fixes
+## Other Fixes
 
 
-- Fixed blank preview thumbnails for images in Safari; use slightly different stap scaling (#458, #584 / @arturi)
+- Fixed blank preview thumbnails for images in Safari; use slightly different step scaling (#458, #584 / @arturi)
 - We now log in console and show an Informer message, not error in console, when file cannot be added due to restrictions (#604, #492 / @goto-bus-stop).
 - We now log in console and show an Informer message, not error in console, when file cannot be added due to restrictions (#604, #492 / @goto-bus-stop).
-- Unused files have been removed from published package (#586 / @goto-bus-stop)
+- Unused files have been removed from published package, saving many many precious megabytes :) (#586 / @goto-bus-stop)
 - Use empty input value so same file can be selected multiple times (@arturi / #534)
 - Use empty input value so same file can be selected multiple times (@arturi / #534)
 - Fix modal and page scroll (#564 / @arturi)
 - Fix modal and page scroll (#564 / @arturi)
 - Refactor provider views (#554 / @arturi)
 - Refactor provider views (#554 / @arturi)
-- Lots of documentation fixes, thanks to all our contributers!
-
-## Misc
-
-- Third-party extension for integrating Ngrx Angular state management library with Uppy has been released, [uppy-store-ngrx](https://github.com/rimlin/uppy-store-ngrx/) by @rimlin.
-- Uppy releases are now hosted on Edgly CDN by Transloadit.
+- Lots of documentation fixes, thanks to all our contributors!
 
 
 ## Press
 ## Press
 
 
 Uppy has made some appearances on the internet recently.
 Uppy has made some appearances on the internet recently.
 
 
-**[Better File Uploads with Shrine: Direct Uploads](https://twin.github.io/better-file-uploads-with-shrine-direct-uploads)**
+1\. **[Better File Uploads with Shrine: Direct Uploads](https://twin.github.io/better-file-uploads-with-shrine-direct-uploads)**:
 
 
 On how to set up Uppy with [Shrine](http://shrinerb.com/), a file attachment toolkit for Ruby applications. It starts off with an example of a plain `<form>` upload and builds up to a more advanced experience:
 On how to set up Uppy with [Shrine](http://shrinerb.com/), a file attachment toolkit for Ruby applications. It starts off with an example of a plain `<form>` upload and builds up to a more advanced experience:
 
 
@@ -106,18 +104,22 @@ On how to set up Uppy with [Shrine](http://shrinerb.com/), a file attachment too
 >
 >
 > There are many popular JavaScript file upload libraries out there – jQuery-File-Upload, Dropzone.js, FineUploader etc. – but the one you should use with Shrine is definitely Uppy 🐶. Uppy is a modular library that knows how to upload files to a custom endpoint on your app, to Amazon S3, or even to a resumable endpoint, providing progress bars, drag & drop functionality, image previews, file validations etc, all while making as few assumptions as possible.
 > There are many popular JavaScript file upload libraries out there – jQuery-File-Upload, Dropzone.js, FineUploader etc. – but the one you should use with Shrine is definitely Uppy 🐶. Uppy is a modular library that knows how to upload files to a custom endpoint on your app, to Amazon S3, or even to a resumable endpoint, providing progress bars, drag & drop functionality, image previews, file validations etc, all while making as few assumptions as possible.
 
 
-**Featured [in Javascript Daily](https://twitter.com/JavaScriptDaily/status/950348390268919809)**
+2\. **Featured [in Javascript Daily](https://twitter.com/JavaScriptDaily/status/950348390268919809)**:
+> Uppy: A Powerful, Modular JavaScript File Uploader
+<cite>— JavaScript Daily</cite>
 
 
-**[Trending on GitHub](https://twitter.com/uppy_io/status/946485101541683201) accross all languages**
+3\. **[#1 Trending on GitHub](https://twitter.com/uppy_io/status/946485101541683201) accross all languages**:
+> Today our open source efforts are outpacing those of MSFT GOOG FB combined :D
+<cite>— kvz, transloadit</cite>
 
 
-**[#2 Product of the Week](https://www.producthunt.com/posts/uppy-io) on ProductHunt**
+4\. **[#2 Product of the Week](https://www.producthunt.com/posts/uppy-io) on ProductHunt**:
 > You literally solved my biggest problem, thank you for developing such a great project. 
 > You literally solved my biggest problem, thank you for developing such a great project. 
 <cite>— Chetan Menaria</cite>
 <cite>— Chetan Menaria</cite>
 
 
 > Writing file upload functionality is always a pain in the arse. I’ll be checking this out today and integrating into SongBox if it’s good.
 > Writing file upload functionality is always a pain in the arse. I’ll be checking this out today and integrating into SongBox if it’s good.
 <cite>— Mick</cite>
 <cite>— Mick</cite>
 
 
-**[#2 New Tool of The Year](https://stackshare.io/posts/top-developer-tools-2017) on Stackshare**
+5\. **[#2 New Tool of The Year](https://stackshare.io/posts/top-developer-tools-2017) on Stackshare**:
 > Uppy closed out the year as the #1 trending GitHub JavaScript project, so we think it’s only getting started.
 > Uppy closed out the year as the #1 trending GitHub JavaScript project, so we think it’s only getting started.
 
 
 ## Full Changelog
 ## Full Changelog

+ 2 - 2
website/src/docs/index.md

@@ -48,12 +48,12 @@ Alternatively, you can also use a pre-built bundle from Transloadit's CDN: Edgly
 1\. Add a script to the bottom of `<body>`:
 1\. Add a script to the bottom of `<body>`:
 
 
 ``` html
 ``` html
-<script src="https://transloadit.edgly.net/releases/uppy/v0.23.0/dist/uppy.min.js"></script>
+<script src="https://transloadit.edgly.net/releases/uppy/v0.23.1/dist/uppy.min.js"></script>
 ```
 ```
 
 
 2\. Add CSS to `<head>`:
 2\. Add CSS to `<head>`:
 ``` html
 ``` html
-<link href="https://transloadit.edgly.net/releases/uppy/v0.23.0/dist/uppy.min.css" rel="stylesheet">
+<link href="https://transloadit.edgly.net/releases/uppy/v0.23.1/dist/uppy.min.css" rel="stylesheet">
 ```
 ```
 
 
 3\. Initialize:
 3\. Initialize:

+ 2 - 2
website/src/examples/i18n/app.html

@@ -1,11 +1,11 @@
 <!-- Basic Uppy styles. You can use Transloadit's CDN, Edgly: 
 <!-- Basic Uppy styles. You can use Transloadit's CDN, Edgly: 
-https://transloadit.edgly.net/releases/uppy/v0.23.0/dist/uppy.min.css -->
+https://transloadit.edgly.net/releases/uppy/v0.23.1/dist/uppy.min.css -->
 <link rel="stylesheet" href="/uppy/uppy.min.css">
 <link rel="stylesheet" href="/uppy/uppy.min.css">
 
 
 <div class="UppyDragDrop"></div>
 <div class="UppyDragDrop"></div>
 
 
 <!-- Load Uppy pre-built bundled version. You can use Transloadit's CDN, Edgly: 
 <!-- Load Uppy pre-built bundled version. You can use Transloadit's CDN, Edgly: 
-https://transloadit.edgly.net/releases/uppy/v0.23.0/dist/uppy.min.js -->
+https://transloadit.edgly.net/releases/uppy/v0.23.1/dist/uppy.min.js -->
 <script src="/uppy/uppy.min.js"></script>
 <script src="/uppy/uppy.min.js"></script>
 <script>
 <script>
   var uppy = Uppy.Core({ debug: true });
   var uppy = Uppy.Core({ debug: true });

+ 2 - 2
website/themes/uppy/layout/index.ejs

@@ -79,8 +79,8 @@
   <p>© <%- date(Date.now(), 'YYYY') %> <a href="https://transloadit.com" target="_blank">Transloadit</a></p>
   <p>© <%- date(Date.now(), 'YYYY') %> <a href="https://transloadit.com" target="_blank">Transloadit</a></p>
 </footer>
 </footer>
 
 
-<link href="https://transloadit.edgly.net/releases/uppy/v0.23.0/dist/uppy.min.css" rel="stylesheet">
-<script src="https://transloadit.edgly.net/releases/uppy/v0.23.0/dist/uppy.min.js"></script>
+<link href="https://transloadit.edgly.net/releases/uppy/v0.23.1/dist/uppy.min.css" rel="stylesheet">
+<script src="https://transloadit.edgly.net/releases/uppy/v0.23.1/dist/uppy.min.js"></script>
 
 
 <script>
 <script>
   var PROTOCOL = location.protocol === 'https:' ? 'https' : 'http'
   var PROTOCOL = location.protocol === 'https:' ? 'https' : 'http'