Переглянути джерело

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

Ifedapo Olarewaju 7 роки тому
батько
коміт
94ef98ade3

+ 19 - 3
CHANGELOG.md

@@ -114,6 +114,24 @@ What we need to do to release Uppy 1.0
 - [ ] providers: select files only after “select” is pressed, don’t add them right away when they are checked (keep a list of fileIds in state?); better UI + solves issue with autoProceed uploading in background, which is weird; re-read https://github.com/transloadit/uppy/pull/419#issuecomment-345210519 (@arturi, @goto-bus-stop)
 - [ ] tus: add `filename` and `filetype`, so that tus servers knows what headers to set  https://github.com/tus/tus-js-client/commit/ebc5189eac35956c9f975ead26de90c896dbe360
 - [ ] core: look into utilizing https://github.com/que-etc/resize-observer-polyfill for responsive components
+- [ ] docs: improve on React docs https://uppy.io/docs/react/, add small example for each component maybe? Dashboard, DragDrop, ProgressBar? No need to make separate pages for all of them, just headings on the same page. Right now docs are confusing, because they focus on DashboardModal. Also problems with syntax highlight on https://uppy.io/docs/react/dashboard-modal/.
+- [ ] docs: add note in docs or solve the .run() issue, see #756
+
+## 0.24.2
+
+Released: 2018-04-17.
+
+- dashboard: Fix showLinkToFileUploadResult option (@arturi / #763)
+- docs: Consistent shape for the getResponseData (responseText, response) (@arturi / #765)
+
+## 0.24.1
+
+Released: 2018-04-16.
+
+- dashboard: ⚠️ **breaking** `maxWidth`, `maxHeight` --> `width` and `height`; update docs and React props too; regardless of what we call those internally, this makes more sense, I think (@arturi)
+- core: Avoid important for those styles that need to be overriden by inline-styles + microtip (@arturi)
+- tus & xhrupload: Retain uppy-server error messages, fixes #707 (@goto-bus-stop / #759)
+- dragdrop: Link `<label>` and `<input>`, fixes #749 (@goto-bus-stop / #757)
 
 ## 0.24.0
 
@@ -124,7 +142,6 @@ Released: 2018-04-12.
 - statusbar: ⚠️ **breaking** Move progress details to second line and make them optional (#682 / @arturi)
 - core: Add uppy-Root to a DOM el that gets mounted in mount (#682 / @arturi)
 - core: Fix all file state was included in progress accidentally (#682 / @arturi)
-- core: Fix for all file state was included in progress accidentally (#682 / @arturi)
 - dashboard: Options to disable showLinkToFileUploadResult and meta editing if metaFields is not provided (#682 / @arturi)
 - dashboard: Remove dashed file icon for now (#682 / @arturi)
 - dashboard: Add optional whitelabel “powered by uppy.io” (@nqst, @arturi)
@@ -133,7 +150,6 @@ Released: 2018-04-12.
 - docs: Talk about success_action_status for POST uploads (#728 / @goto-bus-stop)
 - docs: Add custom provider example (#743 / @ifedapoolarewaju)
 - docs: Addmore useful events, i18n strings, typos, fixes and improvements following Tim’s feedback (#704 / @arturi)
-- form: Fix `get-form-data` being undefined when built with Rollup (#698 / @goto-bus-stop)
 - goldenretriever: Regenerate thumbnails after restore (#723 / @goto-bus-stop)
 - goldenretriever: Warn, not error, when files cannot be saved by goldenretriever (#641 / @goto-bus-stop)
 - instagram: Use date&time as file name for instagram files (#682 / @arturi)
@@ -141,7 +157,7 @@ Released: 2018-04-12.
 - providers: Refactor Provider views: Filter, add showFilter and showBreadcrumbs (#682 / @arturi)
 - react: Allow overriding `<DashboardModal />` `target` prop (#740, @goto-bus-stop)
 - s3: Support fake XHR from remote uploads (#711, @goto-bus-stop)
-- s3: Document Google Cloud Storage too? See #460
+- s3: Document Digital Ocean Spaces
 - s3: Fix xhr response handlers (#625, @goto-bus-stop)
 - statusbar: Cancel button for any kind of uploads (@arturi, @goto-bus-stop)
 - url: Add checks for protocols, assume `http` when no protocol is used (#682 / @arturi)

+ 4 - 4
README.md

@@ -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/).
 
-Add CSS [uppy.min.css](https://transloadit.edgly.net/releases/uppy/v0.24.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.24.2/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.
 
@@ -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>`:
 
 ``` html
-<script src="https://transloadit.edgly.net/releases/uppy/v0.24.0/dist/uppy.min.js"></script>
+<script src="https://transloadit.edgly.net/releases/uppy/v0.24.2/dist/uppy.min.js"></script>
 ```
 
 2\. Add CSS to `<head>`:
 ``` html
-<link href="https://transloadit.edgly.net/releases/uppy/v0.24.0/dist/uppy.min.css" rel="stylesheet">
+<link href="https://transloadit.edgly.net/releases/uppy/v0.24.2/dist/uppy.min.css" rel="stylesheet">
 ```
 
 3\. Initialize:
@@ -99,7 +99,7 @@ Alternatively, you can also use a pre-built bundle from Transloadit's CDN: Edgly
 - [Plugins](https://uppy.io/docs/plugins/) — list of Uppy plugins and their options.
 - [Server](https://uppy.io/docs/server/) — setting up and running an Uppy Server instance, which adds support for Instagram, Dropbox, Google Drive and other remote sources.
 - [React](https://uppy.io/docs/react/) — components to integrate Uppy UI plugins with React apps.
-- Architecture & Making a Plugin — how to write a plugin for Uppy [documentation in progress].
+- [Architecture & Making a Plugin](https://uppy.io/docs/writing-plugins/) — how to write a plugin for Uppy [documentation in progress].
 
 ## Plugins
 

+ 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)
 #  - 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)
-#  - Runs npm pack, and stores files to e.g. https://transloadit.edgly.net/releases/uppy/v0.24.0/dist/uppy.css
+#  - Runs npm pack, and stores files to e.g. https://transloadit.edgly.net/releases/uppy/v0.24.2/dist/uppy.css
 #  - Uses local package by default, if [version] argument was specified, takes package from npm
 #
 # Run as:

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

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

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

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

+ 1 - 1
package-lock.json

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

+ 3 - 2
package.json

@@ -1,6 +1,6 @@
 {
   "name": "uppy",
-  "version": "0.24.0",
+  "version": "0.24.2",
   "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",
   "jsnext:main": "src/index.js",
@@ -135,7 +135,8 @@
     "release:minor": "env SEMANTIC=minor npm run release",
     "release:patch": "env SEMANTIC=patch npm run release",
     "replace:versions": "replace-x -r 'uppy/v\\d+\\.\\d+\\.\\d+/dist' \"uppy/v$npm_package_version/dist\" ./examples/ README.md bin/upload-to-cdn.sh website/src/examples/ website/src/docs/ website/themes/uppy/layout/ --exclude=node_modules",
-    "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",
+    "replace:versions:commit": "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/",
+    "release": "npm version ${SEMANTIC:-patch} -m \"Release %s\" && npm run replace:versions && npm run replace:versions:commit && git push && git push --tags && npm publish",
     "start:server": "node bin/start-server",
     "start": "npm-run-all --parallel watch start:server web:preview",
     "test:acceptance": "./bin/endtoend-build && wdio test/endtoend/wdio.remote.conf.js",

+ 1 - 1
src/core/Core.js

@@ -33,7 +33,7 @@ class Uppy {
         uppyServerError: 'Connection with Uppy Server failed',
         failedToUpload: 'Failed to upload',
         noInternetConnection: 'No Internet connection',
-        connectedToInternet: 'Connected to the Intenet!'
+        connectedToInternet: 'Connected to the Internet'
       }
     }
 

+ 2 - 2
src/plugins/Dashboard/Dashboard.js

@@ -49,8 +49,8 @@ module.exports = function Dashboard (props) {
         aria-modal={!props.inline && 'true'}
         role={!props.inline && 'dialog'}
         style={{
-          maxWidth: props.inline && props.maxWidth ? props.maxWidth : '',
-          maxHeight: props.inline && props.maxHeight ? props.maxHeight : ''
+          width: props.inline && props.width ? props.width : '',
+          height: props.inline && props.height ? props.height : ''
         }}>
         <button class="uppy-Dashboard-close"
           type="button"

+ 4 - 3
src/plugins/Dashboard/FileItem.js

@@ -91,7 +91,7 @@ module.exports = function fileItem (props) {
     </div>
     <div class="uppy-DashboardItem-info">
       <h4 class="uppy-DashboardItem-name" title={fileName}>
-        {file.uploadURL
+        {props.showLinkToFileUploadResult && file.uploadURL
           ? <a href={file.uploadURL} target="_blank">
             {file.extension ? truncatedFileName + '.' + file.extension : truncatedFileName}
           </a>
@@ -121,8 +121,8 @@ module.exports = function fileItem (props) {
         </button>
         : null
       }
-      {file.uploadURL &&
-        <button class="uppy-DashboardItem-copyLink"
+      {props.showLinkToFileUploadResult && file.uploadURL
+        ? <button class="uppy-DashboardItem-copyLink"
           type="button"
           aria-label={props.i18n('copyLink')}
           title={props.i18n('copyLink')}
@@ -134,6 +134,7 @@ module.exports = function fileItem (props) {
               })
               .catch(props.log)
           }}>{iconCopy()}</button>
+        : ''
       }
     </div>
     <div class="uppy-DashboardItem-action">

+ 4 - 3
src/plugins/Dashboard/index.js

@@ -44,7 +44,7 @@ module.exports = class Dashboard extends Plugin {
         importFrom: 'Import from',
         dashboardWindowTitle: 'Uppy Dashboard Window (Press escape to close)',
         dashboardTitle: 'Uppy Dashboard',
-        copyLinkToClipboardSuccess: 'Link copied to clipboard.',
+        copyLinkToClipboardSuccess: 'Link copied to clipboard',
         copyLinkToClipboardFallback: 'Copy the URL below',
         copyLink: 'Copy link',
         fileSource: 'File source',
@@ -362,6 +362,7 @@ module.exports = class Dashboard extends Plugin {
 
   handleDrop (files) {
     this.uppy.log('[Dashboard] Files were dropped')
+    console.log(files)
 
     files.forEach((file) => {
       this.uppy.addFile({
@@ -479,8 +480,8 @@ module.exports = class Dashboard extends Plugin {
       toggleFileCard: this.toggleFileCard,
       saveFileCard: saveFileCard,
       updateDashboardElWidth: this.updateDashboardElWidth,
-      maxWidth: this.opts.maxWidth,
-      maxHeight: this.opts.maxHeight,
+      width: this.opts.width,
+      height: this.opts.height,
       showLinkToFileUploadResult: this.opts.showLinkToFileUploadResult,
       proudlyDisplayPoweredByUppy: this.opts.proudlyDisplayPoweredByUppy,
       currentWidth: pluginState.containerWidth,

+ 9 - 15
src/plugins/DragDrop/index.js

@@ -46,7 +46,6 @@ module.exports = class DragDrop extends Plugin {
 
     // Bind `this` to class methods
     this.handleDrop = this.handleDrop.bind(this)
-    this.handleBrowseClick = this.handleBrowseClick.bind(this)
     this.handleInputChange = this.handleInputChange.bind(this)
     this.checkDragDropSupport = this.checkDragDropSupport.bind(this)
     this.render = this.render.bind(this)
@@ -102,11 +101,6 @@ module.exports = class DragDrop extends Plugin {
     })
   }
 
-  handleBrowseClick (ev) {
-    ev.stopPropagation()
-    this.input.click()
-  }
-
   render (state) {
     const DragDropClass = `uppy uppy-DragDrop-container ${this.isDragDropSupported ? 'is-dragdrop-supported' : ''}`
     const DragDropStyle = {
@@ -119,15 +113,15 @@ module.exports = class DragDrop extends Plugin {
           <svg aria-hidden="true" class="UppyIcon uppy-DragDrop-arrow" width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
             <path d="M11 10V0H5v10H2l6 6 6-6h-3zm0 0" fill-rule="evenodd" />
           </svg>
-          <input class="uppy-DragDrop-input"
-            type="file"
-            name="files[]"
-            multiple="true"
-            ref={(input) => {
-              this.input = input
-            }}
-            onchange={this.handleInputChange} />
-          <label class="uppy-DragDrop-label" onclick={this.handleBrowseClick}>
+          <label class="uppy-DragDrop-label">
+            <input class="uppy-DragDrop-input"
+              type="file"
+              name="files[]"
+              multiple="true"
+              ref={(input) => {
+                this.input = input
+              }}
+              onchange={this.handleInputChange} />
             {this.i18n('dropHereOr')} <span class="uppy-DragDrop-dragText">{this.i18n('browse')}</span>
           </label>
           <span class="uppy-DragDrop-note">{this.opts.note}</span>

+ 4 - 2
src/plugins/Tus.js

@@ -302,8 +302,10 @@ module.exports = class Tus extends Plugin {
       socket.on('progress', (progressData) => emitSocketProgress(this, progressData, file))
 
       socket.on('error', (errData) => {
-        this.uppy.emit('upload-error', file, new Error(errData.error))
-        reject(new Error(errData.error))
+        const { message } = errData.error
+        const error = Object.assign(new Error(message), { cause: errData.error })
+        this.uppy.emit('upload-error', file, error)
+        reject(error)
       })
 
       socket.on('success', (data) => {

+ 1 - 3
src/plugins/Webcam/index.js

@@ -238,9 +238,7 @@ module.exports = class Webcam extends Plugin {
       this.captureInProgress = false
       const dashboard = this.uppy.getPlugin('Dashboard')
       if (dashboard) dashboard.hideAllPanels()
-      return this.uppy.addFile(tagFile).catch(() => {
-        // Ignore
-      })
+      return this.uppy.addFile(tagFile)
     }, (error) => {
       this.captureInProgress = false
       throw error

+ 13 - 11
src/plugins/XHRUpload.js

@@ -55,25 +55,25 @@ module.exports = class XHRUpload extends Plugin {
        * @property {string} statusText
        * @property {Object.<string, string>} headers
        *
-       * @param {string} responseContent the response body
-       * @param {XMLHttpRequest | respObj} responseObject the response object
+       * @param {string} responseText the response body string
+       * @param {XMLHttpRequest | respObj} response the response object (XHR or similar)
        */
-      getResponseData (responseContent, responseObject) {
-        let response = {}
+      getResponseData (responseText, response) {
+        let parsedResponse = {}
         try {
-          response = JSON.parse(responseContent)
+          parsedResponse = JSON.parse(responseText)
         } catch (err) {
           console.log(err)
         }
 
-        return response
+        return parsedResponse
       },
       /**
        *
-       * @param {string} responseContent the response body
-       * @param {XMLHttpRequest | respObj} responseObject the response object
+       * @param {string} responseText the response body string
+       * @param {XMLHttpRequest | respObj} response the response object (XHR or similar)
        */
-      getResponseError (responseContent, responseObject) {
+      getResponseError (responseText, response) {
         return new Error('Upload error')
       }
     }
@@ -338,9 +338,11 @@ module.exports = class XHRUpload extends Plugin {
 
           socket.on('error', (errData) => {
             const resp = errData.response
-            const error = resp ? opts.getResponseError(resp.responseText, resp) : new Error(errData.error)
+            const error = resp
+              ? opts.getResponseError(resp.responseText, resp)
+              : Object.assign(new Error(errData.error.message), { cause: errData.error })
             this.uppy.emit('upload-error', file, error)
-            reject(new Error(errData.error))
+            reject(error)
           })
         })
       })

+ 2 - 2
src/react/Dashboard.js

@@ -43,8 +43,8 @@ Dashboard.propTypes = {
   uppy: PropTypes.instanceOf(UppyCore).isRequired,
   plugins: PropTypes.arrayOf(PropTypes.string),
   inline: PropTypes.bool,
-  maxWidth: PropTypes.number,
-  maxHeight: PropTypes.number,
+  width: PropTypes.number,
+  height: PropTypes.number,
   semiTransparent: PropTypes.bool,
   showProgressDetails: PropTypes.bool,
   hideUploadButton: PropTypes.bool,

+ 2 - 2
src/react/DashboardModal.js

@@ -64,8 +64,8 @@ DashboardModal.propTypes = {
   open: PropTypes.bool,
   onRequestClose: PropTypes.func,
   plugins: PropTypes.arrayOf(PropTypes.string),
-  maxWidth: PropTypes.number,
-  maxHeight: PropTypes.number,
+  width: PropTypes.number,
+  height: PropTypes.number,
   showProgressDetails: PropTypes.bool,
   hideUploadButton: PropTypes.bool,
   note: PropTypes.string,

+ 3 - 3
src/scss/_common.scss

@@ -188,7 +188,7 @@
   .uppy-c-textInput:focus {
     border-color: $color-cornflower-blue;
     outline: none;
-    box-shadow: 0 0 1px 1px rgba($color-cornflower-blue, 0.3);
+    box-shadow: 0 0 1px 1px rgba($color-cornflower-blue, 0.5);
   }
 
 // Buttons
@@ -230,7 +230,7 @@
 
   .uppy-c-btn-primary:focus {
     outline: none;
-    box-shadow: 0 0 3px 1px rgba($color-cornflower-blue, 0.7);
+    box-shadow: 0 0 0 3px rgba($color-cornflower-blue, 0.5);
   }
 
 .uppy-c-btn-link {
@@ -254,7 +254,7 @@
 
   .uppy-c-btn-link:focus {
     outline: none;
-    box-shadow: 0 0 3px 1px rgba($color-cornflower-blue, 0.7);
+    box-shadow: 0 0 0 0.2rem rgba($color-cornflower-blue, 0.5);
   }
 
 .uppy-c-btn--small {

+ 6 - 9
src/scss/_dashboard.scss

@@ -30,12 +30,10 @@
 .uppy-Dashboard-inner {
   position: relative;
   background-color: darken($color-white, 2%);
-  // background-color: $color-white;
-  max-width: 100%;
-  max-height: 100%;
-  width: 100%;
-  height: 100%;
-  // overflow: hidden;
+  max-width: 100%; /* no !important */
+  max-height: 100%; /* no !important */
+  width: 100%; /* no !important */
+  height: 100%; /* no !important */
   outline: none;
   border: 1px solid rgba($color-gray, 0.2);
 
@@ -44,8 +42,8 @@
   }
 
   @media #{$screen-medium} {
-    width: 750px;
-    height: 550px;
+    width: 750px; /* no !important */
+    height: 550px; /* no !important */
     border-radius: 5px;
   }
 }
@@ -55,7 +53,6 @@
   right: 4px;
   bottom: -23px;
   font-size: 11px;
-  // font-weight: 300;
   color: rgba($color-gray, 0.8);
   text-align: right;
   text-decoration: none;

+ 1 - 1
src/scss/_informer.scss

@@ -9,7 +9,7 @@
   padding: 0 15px;
   height: 35px;
   line-height: 35px;
-  background-color: $color-black;
+  background-color: $color-black; /* no !important */
   color: $color-white;
   opacity: 1;
   transform: none;

+ 80 - 44
src/scss/_microtip.scss

@@ -18,12 +18,14 @@
   [1] Base Styles
 -------------------------------------------------*/
 
-.Uppy-root [aria-label][role~="tooltip"] {
+.uppy-Root [aria-label][role~="tooltip"] {
+  /* no important */
   position: relative;
 }
 
-.Uppy-root [aria-label][role~="tooltip"]::before,
-.Uppy-root [aria-label][role~="tooltip"]::after {
+.uppy-Root [aria-label][role~="tooltip"]::before,
+.uppy-Root [aria-label][role~="tooltip"]::after {
+  /* no important */
   transform: translate3d(0, 0, 0);
   -webkit-backface-visibility: hidden;
   backface-visibility: hidden;
@@ -37,12 +39,14 @@
   transform-origin: top;
 }
 
-.Uppy-root [aria-label][role~="tooltip"]::before {
+.uppy-Root [aria-label][role~="tooltip"]::before {
+  /* no important */
   background-size: 100% auto !important;
   content: "";
 }
 
-.Uppy-root [aria-label][role~="tooltip"]::after {
+.uppy-Root [aria-label][role~="tooltip"]::after {
+  /* no important */
   background: rgba(17, 17, 17, .9);
   border-radius: 4px;
   color: #ffffff;
@@ -55,10 +59,11 @@
   box-sizing: content-box;
 }
 
-.Uppy-root [aria-label][role~="tooltip"]:hover::before,
-.Uppy-root [aria-label][role~="tooltip"]:hover::after,
-.Uppy-root [aria-label][role~="tooltip"]:focus::before,
-.Uppy-root [aria-label][role~="tooltip"]:focus::after {
+.uppy-Root [aria-label][role~="tooltip"]:hover::before,
+.uppy-Root [aria-label][role~="tooltip"]:hover::after,
+.uppy-Root [aria-label][role~="tooltip"]:focus::before,
+.uppy-Root [aria-label][role~="tooltip"]:focus::after {
+  /* no important */
   opacity: 1;
   pointer-events: auto;
 }
@@ -69,46 +74,54 @@
   [2] Position Modifiers
 -------------------------------------------------*/
 
-.Uppy-root [role~="tooltip"][data-microtip-position|="top"]::before {
+.uppy-Root [role~="tooltip"][data-microtip-position|="top"]::before {
+  /* no important */
   background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
   height: 6px;
   width: 18px;
   margin-bottom: 5px;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position|="top"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-position|="top"]::after {
+  /* no important */
   margin-bottom: 11px;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position|="top"]::before {
+.uppy-Root [role~="tooltip"][data-microtip-position|="top"]::before {
+  /* no important */
   transform: translate3d(-50%, 0, 0);
   bottom: 100%;
   left: 50%;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position|="top"]:hover::before {
+.uppy-Root [role~="tooltip"][data-microtip-position|="top"]:hover::before {
+  /* no important */
   transform: translate3d(-50%, -5px, 0);
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position|="top"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-position|="top"]::after {
+  /* no important */
   transform: translate3d(-50%, 0, 0);
   bottom: 100%;
   left: 50%;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position="top"]:hover::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="top"]:hover::after {
+  /* no important */
   transform: translate3d(-50%, -5px, 0);
 }
 
 /* ------------------------------------------------
   [2.1] Top Left
 -------------------------------------------------*/
-.Uppy-root [role~="tooltip"][data-microtip-position="top-left"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="top-left"]::after {
+  /* no important */
   transform: translate3d(calc(-100% + 16px), 0, 0);
   bottom: 100%;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position="top-left"]:hover::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="top-left"]:hover::after {
+  /* no important */
   transform: translate3d(calc(-100% + 16px), -5px, 0);
 }
 
@@ -116,12 +129,14 @@
 /* ------------------------------------------------
   [2.2] Top Right
 -------------------------------------------------*/
-.Uppy-root [role~="tooltip"][data-microtip-position="top-right"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="top-right"]::after {
+  /* no important */
   transform: translate3d(calc(0% + -16px), 0, 0);
   bottom: 100%;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position="top-right"]:hover::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="top-right"]:hover::after {
+  /* no important */
   transform: translate3d(calc(0% + -16px), -5px, 0);
 }
 
@@ -129,7 +144,8 @@
 /* ------------------------------------------------
   [2.3] Bottom
 -------------------------------------------------*/
-.Uppy-root [role~="tooltip"][data-microtip-position|="bottom"]::before {
+.uppy-Root [role~="tooltip"][data-microtip-position|="bottom"]::before {
+  /* no important */
   background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
   height: 6px;
   width: 18px;
@@ -137,28 +153,33 @@
   margin-bottom: 0;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position|="bottom"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-position|="bottom"]::after {
+  /* no important */
   margin-top: 11px;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position|="bottom"]::before {
+.uppy-Root [role~="tooltip"][data-microtip-position|="bottom"]::before {
+  /* no important */
   transform: translate3d(-50%, -10px, 0);
   bottom: auto;
   left: 50%;
   top: 100%;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position|="bottom"]:hover::before {
+.uppy-Root [role~="tooltip"][data-microtip-position|="bottom"]:hover::before {
+  /* no important */
   transform: translate3d(-50%, 0, 0);
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position|="bottom"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-position|="bottom"]::after {
+  /* no important */
   transform: translate3d(-50%, -10px, 0);
   top: 100%;
   left: 50%;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position="bottom"]:hover::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="bottom"]:hover::after {
+  /* no important */
   transform: translate3d(-50%, 0, 0);
 }
 
@@ -166,12 +187,14 @@
 /* ------------------------------------------------
   [2.4] Bottom Left
 -------------------------------------------------*/
-.Uppy-root [role~="tooltip"][data-microtip-position="bottom-left"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="bottom-left"]::after {
+  /* no important */
   transform: translate3d(calc(-100% + 16px), -10px, 0);
   top: 100%;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position="bottom-left"]:hover::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="bottom-left"]:hover::after {
+  /* no important */
   transform: translate3d(calc(-100% + 16px), 0, 0);
 }
 
@@ -179,12 +202,14 @@
 /* ------------------------------------------------
   [2.5] Bottom Right
 -------------------------------------------------*/
-.Uppy-root [role~="tooltip"][data-microtip-position="bottom-right"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="bottom-right"]::after {
+  /* no important */
   transform: translate3d(calc(0% + -16px), -10px, 0);
   top: 100%;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position="bottom-right"]:hover::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="bottom-right"]:hover::after {
+  /* no important */
   transform: translate3d(calc(0% + -16px), 0, 0);
 }
 
@@ -192,8 +217,9 @@
 /* ------------------------------------------------
   [2.6] Left
 -------------------------------------------------*/
-.Uppy-root [role~="tooltip"][data-microtip-position="left"]::before,
-.Uppy-root [role~="tooltip"][data-microtip-position="left"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="left"]::before,
+.uppy-Root [role~="tooltip"][data-microtip-position="left"]::after {
+  /* no important */
   bottom: auto;
   left: auto;
   right: 100%;
@@ -201,7 +227,8 @@
   transform: translate3d(10px, -50%, 0);
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position="left"]::before {
+.uppy-Root [role~="tooltip"][data-microtip-position="left"]::before {
+  /* no important */
   background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
   height: 18px;
   width: 6px;
@@ -209,12 +236,14 @@
   margin-bottom: 0;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position="left"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="left"]::after {
+  /* no important */
   margin-right: 11px;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position="left"]:hover::before,
-.Uppy-root [role~="tooltip"][data-microtip-position="left"]:hover::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="left"]:hover::before,
+.uppy-Root [role~="tooltip"][data-microtip-position="left"]:hover::after {
+  /* no important */
   transform: translate3d(0, -50%, 0);
 }
 
@@ -222,15 +251,17 @@
 /* ------------------------------------------------
   [2.7] Right
 -------------------------------------------------*/
-.Uppy-root [role~="tooltip"][data-microtip-position="right"]::before,
-.Uppy-root [role~="tooltip"][data-microtip-position="right"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="right"]::before,
+.uppy-Root [role~="tooltip"][data-microtip-position="right"]::after {
+  /* no important */
   bottom: auto;
   left: 100%;
   top: 50%;
   transform: translate3d(-10px, -50%, 0);
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position="right"]::before {
+.uppy-Root [role~="tooltip"][data-microtip-position="right"]::before {
+  /* no important */
   background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
   height: 18px;
   width: 6px;
@@ -238,29 +269,34 @@
   margin-left: 5px;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position="right"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="right"]::after {
+  /* no important */
   margin-left: 11px;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-position="right"]:hover::before,
-.Uppy-root [role~="tooltip"][data-microtip-position="right"]:hover::after {
+.uppy-Root [role~="tooltip"][data-microtip-position="right"]:hover::before,
+.uppy-Root [role~="tooltip"][data-microtip-position="right"]:hover::after {
+  /* no important */
   transform: translate3d(0, -50%, 0);
 }
 
 /* ------------------------------------------------
   [3] Size
 -------------------------------------------------*/
-.Uppy-root [role~="tooltip"][data-microtip-size="small"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-size="small"]::after {
+  /* no important */
   white-space: initial;
   width: 80px;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-size="medium"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-size="medium"]::after {
+  /* no important */
   white-space: initial;
   width: 150px;
 }
 
-.Uppy-root [role~="tooltip"][data-microtip-size="large"]::after {
+.uppy-Root [role~="tooltip"][data-microtip-size="large"]::after {
+  /* no important */
   white-space: initial;
   width: 260px;
 }

+ 4 - 9
src/scss/_progressbar.scss

@@ -1,9 +1,5 @@
-// @import '_variables.scss';
-// @import '_utils.scss';
-// @import '_animation.scss';
-// @import '_common.scss';
-
 .uppy-ProgressBar {
+  /* no important */
   position: absolute;
   top: 0;
   left: 0;
@@ -14,10 +10,12 @@
 }
 
 .uppy-ProgressBar[aria-hidden=true] {
+  /* no important */
   height: 0;
 }
 
 .uppy-ProgressBar-inner {
+  /* no important */
   background-color: $color-cornflower-blue;
   box-shadow: 0 0 10px rgba($color-cornflower-blue, 0.7);
   height: 100%;
@@ -26,6 +24,7 @@
 }
 
 .uppy-ProgressBar-percentage {
+  /* no important */
   display: none;
   text-align: center;
   position: absolute;
@@ -33,8 +32,4 @@
   left: 50%;
   transform: translate(-50%, -50%);
   color: $color-white;
-
-  // &:after {
-  //   content: ' %';
-  // }
 }

+ 5 - 0
src/scss/_webcam.scss

@@ -63,6 +63,11 @@
     background-color: darken($color-red, 10%);
   }
 
+  .uppy-Webcam-button:focus {
+    outline: none;
+    box-shadow: 0 0 0 0.2rem rgba($color-cornflower-blue, 0.5);
+  }
+
   .uppy-Webcam-button .UppyIcon {
     width: 30px;
     height: 30px;

+ 2 - 0
website/src/_posts/2018-02-0.23.md

@@ -180,3 +180,5 @@ Here is the full list of changes for version `0.23.0` (and patches `0.22.1`—`0
 - docs: fix reference to incorrect width/height options (#475 / @xhocquet)
 - docs: Documentation fixes and improvements (#463 / @janko-m)
 - docs: Fixed several typos in docs/server and docs/uppy (#484 / @martiuslim)
+
+The Uppy Team

+ 74 - 24
website/src/_posts/2018-02-0.24.md

@@ -1,11 +1,12 @@
 ---
-title: "Uppy 0.24: Refreshed UI, Simplified StatusBar"
-date: 2018-04-16
+title: "Uppy 0.24: Refreshed Dashboard, StatusBar and Provider UI, revamped XHR Response Handling"
+date: 2018-04-17
 author: arturi
-published: false
+image: "https://uppy.io/images/blog/0.24/uppy-screenshot.jpg"
+published: true
 ---
 
-Uppy `0.24.0` brings a refreshed UI in Dashboard and StatusBar, synchronous `addFile()`, cancel button, style protections, documentation on writing your own Uppy plugins, revamped XHR response handling and tons of fixes.
+Uppy 0.24.2 brings a refreshed UI in the Dashboard and StatusBar plugins, a synchronous `addFile()` method, a cancel button, style protections, documentation on writing your own Uppy plugin, revamped XHR response handling and tons of bugfixes.
 
 <!--more-->
 
@@ -13,6 +14,8 @@ Uppy `0.24.0` brings a refreshed UI in Dashboard and StatusBar, synchronous `add
 
 As always, we are trying to simplify and improve the UI of Uppy plugins. In this release, Dashboard’s design has been refreshed, check this out:
 
+<img class="border" src="/images/blog/0.24/uppy-screenshot.jpg">
+
 <img class="border" src="/images/blog/0.24/dashboard-main.jpg">
 
 Meta editing screen:
@@ -27,13 +30,15 @@ Import from URL (Link):
 
 <img class="border" src="/images/blog/0.24/import-from-url.jpg">
 
-## Better StatusBar
+And more, check out the [Dashboard example page](https://uppy.io/examples/dashboard/).
+
+## A Better StatusBar
 
-StatusBar used to always show a lot of (unnecessary) progress details. This has been improved, by default it will now only show percentage:
+The StatusBar plugin used to always show a lot of (unnecessary) progress details. This has been improved, by default it will now only show a percentage:
 
 <img src="/images/blog/0.24/statusbar-2.jpg">
 
-But there’s an option `showProgressDetails: true` for the StatusBar and Dashboard (which passes it to StatusBar included in the Dashboard), that will show two lines of easy to understand progress:
+But there’s an option `showProgressDetails: true` for the StatusBar and Dashboard (which passes it to StatusBar included in the Dashboard) to bring back this detailed information, spread over two lines:
 
 <img src="/images/blog/0.24/statusbar-1.jpg">
 
@@ -45,37 +50,82 @@ uppy.use(StatusBar, { ..., showProgressDetails: true })
 uppy.use(Dashboard, { ..., showProgressDetails: true })
 ```
 
-We’ve also added a handy “cancel” button, which should cancel everything in progress regardless of the type of the upload.
+We’ve also added a handy “cancel” button, which will cancel everything in progress regardless of the type of the upload (wether uppy-server or local powered, and wether tus-resumable or old school XHR/form uploads).
 
 ## XHR Response Handling
 
+When the upload completes (regardless of whether it succeeded), a `response` key gets added to the file. `file.response` contains a `status` and `data` properties. `data` is the result of the `getResponseData()` option. The `getResponseData()` function's signature is now:
+
+```js
+getResponseData (responseText, response) { }
+```
+
+This is what the default JSON parsing implementation looks like in the `XHRUpload` plugin, but you can override it with your own:
+
+```js
+getResponseData (responseText, response) {
+  let parsedResponse = {}
+  try {
+    parsedResponse = JSON.parse(responseText)
+  } catch (err) {
+    console.log(err)
+  }
+
+  return parsedResponse
+}
+```
+
+The `responseText` is the XHR endpoint response as a string. For uploads from the user's device, `response` is the [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) object.
 
+When uploading files from remote providers such as Dropbox or Instagram, Uppy Server sends upload response data to the client. This is made available in the `getResponseData()` option as well. The `response` object from Uppy Server contains some properties named after their [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) counterparts:
+
+ - `response.responseText` - the XHR endpoint response as a string;
+ - `response.status` - the HTTP status code;
+ - `response.statusText` - the HTTP status text;
+ - `response.headers` - an object mapping lowercase header names to their values.
 
 ## Powered by Uppy
 
-Uppy is provided for the world for free by the [Transloadit](https://transloadit.com) team. In return, we ask that you consider keeping a tiny tasteful Uppy logo at the bottom of the Dashboard, so that more people can discover and use Uppy.
+Uppy is provided to the world for free. In return, we ask that you consider keeping a tiny tasteful Uppy logo at the bottom of the Dashboard, so that more people can discover and enjoy Uppy. This really helps to grow the community which will directly result in more issues reported, more features requested, more PRs merged, and a better Uppy for you to use tomorrow, for free.
 
 This is entirely optional of course, just set `proudlyDisplayPoweredByUppy: false` option if you do not wish to display Uppy logo.
 
-## Misc Good Stuff
+<img src="/images/blog/0.24/powered-by-1.png">
+
+## Other Fixes & Improvements
 
-- ⚠️ **breaking** `addFile()`, `onBeforeFileAdded()` and `onBeforeUpload()` are now synchronous, please see check out the update docs: [onBeforeFileAdded()](https://uppy.io/docs/uppy/#onBeforeFileAdded) and [onBeforeUpload()](https://uppy.io/docs/uppy/#onBeforeUpload).
-- ⚠️ **breaking** most event now emit the whole file object instead of a fileId.
-- ⚠️ **breaking** We’ve added `postcss-safe-important` to out style build step, so now 90% of rules got `!important` declaration added to them. This is done to prevent page styles (especially global like Bootstrap) from leaking into the Uppy widget. There are other solutions we are looking into, like iFrames and WebComponents, this is an experiment. Keep in mind that to override Uppy styles, you now have to also use `!important`.
-- There’s now an option `showLinkToFileUploadResult: true` to disable linking to the upload result in Dashboard UI.
-- We are now using the image time and date as a file name in Instagram.
-- URL plugin checks for http(s) protocol, and add http by default if no protocol is present.
-— It’s now possible to overrid `<DashboardModal />` React component’s target prop. 
-- Provider views now have `showFilter` and `showBreadcrumbs` options, those are off for Instagram plugin, for example.
-- Uppy Server to Client communication has been refactored into `Provider` and `Request` modules. Request can be used when a simple request needs to be made to Uppy Server, like in URL plugin, for example. Provider is used for more complex implementations shared between Google Drive and Instagram, for example.
-- We’ve added Transloadit example to the website, [check it out](https://uppy.io/examples/transloadit/).
+- ⚠️ **breaking** `addFile()`, `onBeforeFileAdded()` and `onBeforeUpload()` are now synchronous and have to return nothing or file objects to proceed, or false to abort; please check out the update docs for details: [onBeforeFileAdded()](https://uppy.io/docs/uppy/#onBeforeFileAdded) and [onBeforeUpload()](https://uppy.io/docs/uppy/#onBeforeUpload).
+- ⚠️ **breaking** Most events now emit the whole `file` object instead of a `fileId`. So you can access `file.name` right away, for example, so you no longer have to fish for the file using its id.
+- ⚠️ **breaking** We’ve added `postcss-safe-important` to our style build step, so now 90% of rules got `!important` declaration added to them. This is done to prevent page styles (especially global ones like from Bootstrap) from leaking into the Uppy widget. There are other solutions we are looking into, like iFrames and WebComponents, this is an experiment. Keep in mind that to override Uppy styles, you now have to also use `!important`.
+- dashboard: ⚠️ **breaking** `maxWidth`, `maxHeight` options have been converted to `width` and `height`, because this makes more sense, `maxWidth` and `maxHeight` are actually `100%`.
+- There is now an option `showLinkToFileUploadResult: false` to disable linking to the upload result in Dashboard UI.
+- We are now using the image time and date as a file name in Instagram, instead of a generic file id.
+- The URL plugin now checks for HTTP(S) protocol, and adds HTTP by default if no protocol is present.
+- It’s now possible to override `<DashboardModal />` React component’s target prop.
+- Provider views now have `showFilter` and `showBreadcrumbs` options, those are `false` for the Instagram plugin, for example.
+- Uppy Server to Client communication has been refactored into `Provider` and `Request` modules. `Request` can be used when a simple request needs to be made to Uppy Server, like in the URL plugin. `Provider` is used for more complex implementations shared between Google Drive and Instagram, for example.
+- We’ve added a Transloadit example to the website, [check it out](https://uppy.io/examples/transloadit/).
 
 ## Docs
 
-- Uppy Server docs now point to a detailed write-up on how to run Uppy Server in Kubernetes (#706 / @kiloreux)
-- Uppy Server custom provider example has been added, so now it’s easier create your own custom providers.
-- More useful events, i18n strings, typos, fixes and improvements.
+- Uppy Server docs now point to a detailed write-up on how to run Uppy Server on Kubernetes (#706 / @kiloreux)
+- An Uppy Server custom provider example has been added, so now it’s easier create your own custom providers.
+- Added more useful events, i18n strings, fixed typos, and other polish.
 
 ## Server News
 
-?
+On the Server side we tackled a number of security issues:
+
+- Fixed security vulnerability in transient dependency [#70](https://github.com/transloadit/uppy-server/issues/70)
+- Auto-generate tmp download file name to avoid Path traversal
+- Namespace redis key storage/lookup to avoid collisions
+- Validate callback redirect url after completing OAuth
+- Reduce the permission level required by Google Drive
+
+Other non-security improvements are:
+
+- Auto-generate Server secret if none is provided on startup
+- We implemented a more standard logger for Uppy Server
+- Added an example project to run Uppy Server on Serverless, [see](https://github.com/transloadit/uppy-server/tree/master/examples/serverless).
+
+The Uppy Team

+ 4 - 4
website/src/docs/dashboard.md

@@ -112,13 +112,13 @@ uppy.use(Dashboard, {
 
 Of course, you can also use the `target` option in the Webcam plugin to achieve this. However, that does not work with the React components. The `target` option may be changed in the future to only accept DOM elements, so it is recommended to use this `plugins` array instead.
 
-### `maxWidth: 750`
+### `width: 750`
 
-Maximum width of the Dashboard in pixels. Used when `inline: true`.
+Width of the Dashboard in pixels. Used when `inline: true`.
 
-### `maxHeight: 550`
+### `height: 550`
 
-Maximum height of the Dashboard in pixels. Used when `inline: true`.
+Height of the Dashboard in pixels. Used when `inline: true`.
 
 ### `showProgressDetails: false`
 

+ 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>`:
 
 ``` html
-<script src="https://transloadit.edgly.net/releases/uppy/v0.24.0/dist/uppy.min.js"></script>
+<script src="https://transloadit.edgly.net/releases/uppy/v0.24.2/dist/uppy.min.js"></script>
 ```
 
 2\. Add CSS to `<head>`:
 ``` html
-<link href="https://transloadit.edgly.net/releases/uppy/v0.24.0/dist/uppy.min.css" rel="stylesheet">
+<link href="https://transloadit.edgly.net/releases/uppy/v0.24.2/dist/uppy.min.css" rel="stylesheet">
 ```
 
 3\. Initialize:

+ 17 - 8
website/src/docs/xhrupload.md

@@ -72,7 +72,7 @@ uppy.setFileState(otherFileID, {
 })
 ```
 
-### `getResponseData(xhr.responseText, xhr)`
+### `getResponseData(responseText, response)`
 
 When an upload has completed, Uppy will extract response data from the upload endpoint. This response data will be available on the file's `.response` property, and be emitted in the `upload-success` event:
 
@@ -96,29 +96,38 @@ By default, Uppy assumes the endpoint will return JSON. So, if `POST /upload` re
 }
 ```
 
-That object will be emitted in the `upload-success` event. Not all endpoints respond with JSON. Providing a `getResponseData` function overrides this behavior. The `xhr` parameter is the `XMLHttpRequest` instance used to upload the file.
+That object will be emitted in the `upload-success` event. Not all endpoints respond with JSON. Providing a `getResponseData` function overrides this behavior. The `response` parameter is the `XMLHttpRequest` instance used to upload the file.
 
 For example, an endpoint that responds with an XML document:
 
 ```js
-getResponseData (xhr.responseText, xhr) {
+getResponseData (responseText, response) {
   return {
-    url: xhr.responseXML.querySelector('Location').textContent
+    url: responseText.match(/<Location>(.*?)<\/Location>/)[1]
   }
 }
 ```
 
-### `getResponseError(xhr.responseText, xhr)`
+The `responseText` is the XHR endpoint response as a string. For uploads from the user's device, `response` is the [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) object.
+
+When uploading files from remote providers such as Dropbox or Instagram, Uppy Server sends upload response data to the client. This is made available in the `getResponseData()` function as well. The `response` object from Uppy Server contains some properties named after their [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) counterparts:
+
+ - `response.responseText` - the XHR endpoint response as a string;
+ - `response.status` - the HTTP status code;
+ - `response.statusText` - the HTTP status text;
+ - `response.headers` - an object mapping lowercase header names to their values.
+
+### `getResponseError(responseText, response)`
+
+If the upload endpoint responds with a non-2xx status code, the upload is assumed to have failed. The endpoint might have responded with some information about the error, though.
 
-If the upload endpoint responds with a non-2xx status code, the upload is assumed to have failed.
-The endpoint might have responded with some information about the error, though.
 Pass in a `getResponseError` function to extract error data from the `XMLHttpRequest` instance used for the upload.
 
 For example, if the endpoint responds with a JSON object containing a `{ message }` property, this would show that message to the user:
 
 ```js
 getResponseError (responseText, xhr) {
-  return new Error(JSON.parse(xhr.response).message)
+  return new Error(JSON.parse(responseText).message)
 }
 ```
 

+ 4 - 3
website/src/examples/dashboard/app.es6

@@ -40,10 +40,11 @@ function uppyInit () {
     target: opts.DashboardInline ? '.DashboardContainer' : 'body',
     replaceTargetContent: opts.DashboardInline,
     note: opts.restrictions ? 'Images and video only, 2–3 files, up to 1 MB' : '',
-    maxHeight: 450,
+    height: 470,
+    showProgressDetails: true,
     metaFields: [
-      { id: 'license', name: 'License', placeholder: 'specify license' },
-      { id: 'caption', name: 'Caption', placeholder: 'describe what the image is about' }
+      { id: 'name', name: 'Name', placeholder: 'file name' },
+      { id: 'caption', name: 'Caption', placeholder: 'add description' }
     ]
   })
 

+ 3 - 2
website/src/examples/dashboard/index.ejs

@@ -42,10 +42,11 @@ const uppy = Uppy({
   inline: true,
   target: '.DashboardContainer',
   replaceTargetContent: true,
+  showProgressDetails: true,
   note: 'Images and video only, 2–3 files, up to 1 MB',
-  maxHeight: 450,
+  height: 470,
   metaFields: [
-    { id: 'license', name: 'License', placeholder: 'specify license' },
+    { id: 'name', name: 'Name', placeholder: 'file name' },
     { id: 'caption', name: 'Caption', placeholder: 'describe what the image is about' }
   ]
 })

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

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

BIN
website/src/images/blog/0.24/powered-by-1.png


BIN
website/src/images/blog/0.24/uppy-screenshot.jpg


+ 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>
 </footer>
 
-<link href="https://transloadit.edgly.net/releases/uppy/v0.24.0/dist/uppy.min.css" rel="stylesheet">
-<script src="https://transloadit.edgly.net/releases/uppy/v0.24.0/dist/uppy.min.js"></script>
+<link href="https://transloadit.edgly.net/releases/uppy/v0.24.2/dist/uppy.min.css" rel="stylesheet">
+<script src="https://transloadit.edgly.net/releases/uppy/v0.24.2/dist/uppy.min.js"></script>
 
 <script>
   var PROTOCOL = location.protocol === 'https:' ? 'https' : 'http'