Преглед изворни кода

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

Kevin van Zonneveld пре 6 година
родитељ
комит
f877010d5b
75 измењених фајлова са 1149 додато и 412 уклоњено
  1. 5 5
      .browsersync.js
  2. 59 10
      CHANGELOG.md
  3. 31 31
      README.md
  4. 0 0
      assets/uppy-screenshot.jpg
  5. 30 1
      bin/build-lib.js
  6. 1 1
      bin/release
  7. 10 0
      bin/to-gif-hd.sh
  8. 1 1
      bin/upload-to-cdn.sh
  9. 2 2
      examples/cdn-example/index.html
  10. 2 4
      examples/react-example/App.js
  11. 2 2
      examples/uppy-with-companion/client/index.html
  12. 472 93
      package-lock.json
  13. 4 3
      package.json
  14. 4 5
      packages/@uppy/aws-s3-multipart/package.json
  15. 10 2
      packages/@uppy/aws-s3-multipart/src/index.js
  16. 5 6
      packages/@uppy/aws-s3/package.json
  17. 2 2
      packages/@uppy/aws-s3/src/index.js
  18. 1 2
      packages/@uppy/companion-client/package.json
  19. 19 19
      packages/@uppy/companion/package.json
  20. 1 1
      packages/@uppy/companion/src/uppy.js
  21. 3 4
      packages/@uppy/core/package.json
  22. 9 4
      packages/@uppy/core/src/index.js
  23. 9 9
      packages/@uppy/dashboard/package.json
  24. 14 4
      packages/@uppy/dashboard/src/index.js
  25. 3 4
      packages/@uppy/drag-drop/package.json
  26. 5 6
      packages/@uppy/dropbox/package.json
  27. 3 4
      packages/@uppy/file-input/package.json
  28. 3 4
      packages/@uppy/form/package.json
  29. 3 4
      packages/@uppy/golden-retriever/package.json
  30. 5 6
      packages/@uppy/google-drive/package.json
  31. 3 4
      packages/@uppy/informer/package.json
  32. 5 6
      packages/@uppy/instagram/package.json
  33. 3 4
      packages/@uppy/progress-bar/package.json
  34. 3 4
      packages/@uppy/provider-views/package.json
  35. 2 2
      packages/@uppy/provider-views/src/index.js
  36. 7 7
      packages/@uppy/react/package.json
  37. 17 2
      packages/@uppy/react/src/Dashboard.js
  38. 1 1
      packages/@uppy/react/src/DashboardModal.d.ts
  39. 17 2
      packages/@uppy/react/src/DashboardModal.js
  40. 17 2
      packages/@uppy/react/src/DragDrop.js
  41. 17 2
      packages/@uppy/react/src/ProgressBar.js
  42. 17 2
      packages/@uppy/react/src/StatusBar.js
  43. 17 2
      packages/@uppy/react/src/Wrapper.js
  44. 2 3
      packages/@uppy/redux-dev-tools/package.json
  45. 3 4
      packages/@uppy/status-bar/package.json
  46. 14 8
      packages/@uppy/status-bar/src/StatusBar.js
  47. 23 16
      packages/@uppy/status-bar/src/style.scss
  48. 1 2
      packages/@uppy/store-default/package.json
  49. 1 2
      packages/@uppy/store-redux/package.json
  50. 3 4
      packages/@uppy/thumbnail-generator/package.json
  51. 6 7
      packages/@uppy/transloadit/package.json
  52. 5 6
      packages/@uppy/tus/package.json
  53. 10 2
      packages/@uppy/tus/src/index.js
  54. 4 5
      packages/@uppy/url/package.json
  55. 1 2
      packages/@uppy/utils/package.json
  56. 3 4
      packages/@uppy/webcam/package.json
  57. 4 5
      packages/@uppy/xhr-upload/package.json
  58. 19 12
      packages/@uppy/xhr-upload/src/index.js
  59. 26 26
      packages/uppy/package.json
  60. 1 1
      test/endtoend/url-plugin/test.js
  61. 2 1
      test/endtoend/wdio.base.conf.js
  62. 2 2
      website/src/_posts/2017-10-0.20.md
  63. 1 1
      website/src/docs/form.md
  64. 6 6
      website/src/docs/index.md
  65. 26 0
      website/src/docs/react-dashboard-modal.md
  66. 26 0
      website/src/docs/react-dashboard.md
  67. 26 0
      website/src/docs/react-dragdrop.md
  68. 26 0
      website/src/docs/react-progressbar.md
  69. 26 0
      website/src/docs/react-statusbar.md
  70. 5 1
      website/src/docs/react.md
  71. 25 6
      website/src/docs/uppy.md
  72. 2 2
      website/src/examples/i18n/app.html
  73. 2 3
      website/src/privacy.md
  74. 2 2
      website/themes/uppy/layout/index.ejs
  75. 2 0
      website/themes/uppy/layout/layout.ejs

+ 5 - 5
.browsersync.js

@@ -27,12 +27,12 @@ module.exports = {
     "middleware": false,
     "middleware": false,
     "serveStatic": ["examples/bundle"],
     "serveStatic": ["examples/bundle"],
     "ghostMode": {
     "ghostMode": {
-        "clicks": true,
-        "scroll": true,
+        "clicks": false,
+        "scroll": false,
         "forms": {
         "forms": {
-            "submit": true,
-            "inputs": true,
-            "toggles": true
+            "submit": false,
+            "inputs": false,
+            "toggles": false
         }
         }
     },
     },
     "logLevel": "info",
     "logLevel": "info",

+ 59 - 10
CHANGELOG.md

@@ -50,13 +50,11 @@ PRs are welcome! Please do open an issue to discuss first if it's a big feature,
 - [ ] test: add deepFreeze to test that state in not mutated anywhere by accident #320
 - [ ] test: add deepFreeze to test that state in not mutated anywhere by accident #320
 - [ ] audio: audio recording similar to Webcam #143
 - [ ] audio: audio recording similar to Webcam #143
 - [ ] add typescript definitions and JSDoc everywhere? https://github.com/Microsoft/TypeScript/wiki/Type-Checking-JavaScript-Files
 - [ ] add typescript definitions and JSDoc everywhere? https://github.com/Microsoft/TypeScript/wiki/Type-Checking-JavaScript-Files
-- [ ] transloadit plugin: maybe add option to disable uppy server endpoint overrides
+- [ ] transloadit plugin: maybe add option to disable Companion endpoint overrides
 - [ ] dragdrop: change border color when files doesn’t pass restrictions on drag https://github.com/transloadit/uppy/issues/607
 - [ ] dragdrop: change border color when files doesn’t pass restrictions on drag https://github.com/transloadit/uppy/issues/607
 - [ ] website: automatically generated page with all locale strings used in plugins
 - [ ] website: automatically generated page with all locale strings used in plugins
 - [ ] transloadit: option for StatusBar’s upload button to act as a "Start assembly" button? Useful if an assembly uses only import robots, such as /s3/import to start a batch transcoding job.
 - [ ] transloadit: option for StatusBar’s upload button to act as a "Start assembly" button? Useful if an assembly uses only import robots, such as /s3/import to start a batch transcoding job.
-- [ ] provider: Add Facebook
-- [ ] provider: Add OneDrive
-- [ ] provider: Add Box
+- [ ] provider: Add Facebook, OneDrive, Box
 - [ ] provider: change ProviderViews signature to receive Provider instance in second param. ref https://github.com/transloadit/uppy/pull/743#discussion_r180106070
 - [ ] provider: change ProviderViews signature to receive Provider instance in second param. ref https://github.com/transloadit/uppy/pull/743#discussion_r180106070
 - [ ] core: css-in-js, while keeping non-random classnames (ideally prefixed) and useful preprocessor features. also see simple https://github.com/codemirror/CodeMirror/blob/master/lib/codemirror.css (@arturi, @goto-bus-stop)
 - [ ] core: css-in-js, while keeping non-random classnames (ideally prefixed) and useful preprocessor features. also see simple https://github.com/codemirror/CodeMirror/blob/master/lib/codemirror.css (@arturi, @goto-bus-stop)
 - [ ] webcam: Stop recording when file size is exceeded, should be possible given how the MediaRecorder API works
 - [ ] webcam: Stop recording when file size is exceeded, should be possible given how the MediaRecorder API works
@@ -66,7 +64,19 @@ PRs are welcome! Please do open an issue to discuss first if it's a big feature,
 - [ ] dashboard: hiding pause/resume from the UI by default (with option) would be good too probably (we could auto pause and show a resume button when detecting a network change to a metered network using https://devdocs.io/dom/networkinformation/type)
 - [ ] dashboard: hiding pause/resume from the UI by default (with option) would be good too probably (we could auto pause and show a resume button when detecting a network change to a metered network using https://devdocs.io/dom/networkinformation/type)
 - [ ] test: Add a prepublish test that checks if `npm pack` is not massive
 - [ ] test: Add a prepublish test that checks if `npm pack` is not massive
 - [ ] dashboard: add image cropping, study https://github.com/MattKetmo/darkroomjs/, https://github.com/fengyuanchen/cropperjs #151
 - [ ] dashboard: add image cropping, study https://github.com/MattKetmo/darkroomjs/, https://github.com/fengyuanchen/cropperjs #151
+- [ ] Feature: Plugins - Keybase.io Remote provider plugin! #943
+- [ ] Dashboard allow selecting folders (add separate hidden input button for folders) #447 #1027
+- [ ] core: Add total max size to restrictions #514
+- [ ] core: normalize file names when uploading from iOS? $678
 - [ ] webcam: Pick format based on `restrictions.allowedFileTypes`, eg. use PNG for snapshot instead of JPG if `allowedFileTypes: ['.png']` is set
 - [ ] webcam: Pick format based on `restrictions.allowedFileTypes`, eg. use PNG for snapshot instead of JPG if `allowedFileTypes: ['.png']` is set
+- [ ] webcam: UI or separate plugins for choosing between webcam audio-video/video-only/audio-only modes #198
+- [ ] webcam: Specify the resolution of the webcam images. We should add a way to specify any custom constraints to the Webcam plugin #876
+- [ ] transloadit: consider adding option to append result link from transloadit to the link thing in the Dashboard file block #1177
+- [ ] Consider uploading image thumbnails too #1212
+- [ ] dashboard: if you specified a delete endpoint, the “remove/cancel upload” button remains after the upload and it not only removes, but also sends a request to that endpoint #1216
+- [ ] dashboard: Show upload speed too if `showProgressDetails: true`. Maybe have separate options for which things are displayed, or at least have css-classes that can be hidden with `display: none` #766
+- [ ] react: Component wrappers to manage the Uppy instance, many people initialize it in render() which does not work correctly so this could make it easier for them https://github.com/transloadit/uppy/pull/1247#issuecomment-458063951
+- [ ] core: Fire event when a restriction fails #1251
 
 
 ## 1.0 Goals
 ## 1.0 Goals
 
 
@@ -104,23 +114,62 @@ What we need to do to release Uppy 1.0
 - [x] uppy-server: security audit
 - [x] uppy-server: security audit
 - [x] uppy-server: storing tokens in user’s browser only (d040281cc9a63060e2f2685c16de0091aee5c7b4)
 - [x] uppy-server: storing tokens in user’s browser only (d040281cc9a63060e2f2685c16de0091aee5c7b4)
 
 
+## 0.31.0
+
+- [ ] core: customizing metadata fields, boolean metadata; see #809, #454 and related (@arturi)
+- [ ] goldenretriever: confirmation before restore, add “ghost” files #443 #257 (@arturi)
+- [ ] build: utilize https://github.com/jonathantneal/postcss-preset-env, maybe https://github.com/jonathantneal/postcss-normalize (@arturi)
+- [ ] fix incorrectly rotated image thumbnails #472
+
 # next
 # next
 
 
 ## 0.30.0
 ## 0.30.0
 
 
-- [ ] add polyfils to uppy bundle 
 - [ ] dashboard: allow minimizing the Dashboard during upload (Uppy then becomes just a tiny progress indicator) (@arturi)
 - [ ] dashboard: allow minimizing the Dashboard during upload (Uppy then becomes just a tiny progress indicator) (@arturi)
-- [ ] core: customizing metadata fields, boolean metadata; see #809, #454 and related (@arturi)
-- [ ] goldenretriever: confirmation before restore, add “ghost” files #443 #257 (@arturi)
 - [ ] 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)
 - [ ] dragdrop: allow customizing arrow icon https://github.com/transloadit/uppy/pull/374#issuecomment-334116208 (@arturi)
 - [ ] dashboard: cancel button for transloadit assemblies (@arturi, @goto-bus-stop)
 - [ ] dashboard: cancel button for transloadit assemblies (@arturi, @goto-bus-stop)
 - [ ] dashboard: optional alert `onbeforeunload` while upload is in progress, safeguarding from accidentaly navigating away from a page with an ongoing upload
 - [ ] dashboard: optional alert `onbeforeunload` while upload is in progress, safeguarding from accidentaly navigating away from a page with an ongoing upload
-- [ ] transloadit: add error reporting (@goto-bus-stop)
-- [ ] core: utilize https://github.com/jonathantneal/postcss-preset-env, maybe https://github.com/jonathantneal/postcss-normalize (@arturi)
-- [ ] core: update babel to v7
+- [ ] transloadit: add error reporting, see https://github.com/transloadit/jquery-sdk/blob/891e99b08dd8142d8d8adc0553e6511967635ad7/js/lib/Modal.js#L122-L136 (@goto-bus-stop, @arturi)
 - [ ] server: bump minor and deprecate that on npm in favour of @uppy/companion (@ifedapoolarewaju)
 - [ ] server: bump minor and deprecate that on npm in favour of @uppy/companion (@ifedapoolarewaju)
 - [ ] companion: rename `serverUrl` and `serverPattern` to `companionUrl` and `companionAllowedHosts` (@ifedapoolarewaju)
 - [ ] companion: rename `serverUrl` and `serverPattern` to `companionUrl` and `companionAllowedHosts` (@ifedapoolarewaju)
+- [ ] show thumbnails when connecting with Google Drive #1162
+
+## 0.29.1
+
+| Package | Version | Package | Version |
+|-|-|-|-|
+| @uppy/aws-s3-multipart | 0.29.1 | @uppy/provider-views | 0.29.1 |
+| @uppy/aws-s3 | 0.29.1 | @uppy/react | 0.29.1 |
+| @uppy/companion-client | 0.27.3 | @uppy/redux-dev-tools | 0.29.1 |
+| @uppy/companion | 0.16.1 | @uppy/status-bar | 0.29.1 |
+| @uppy/core | 0.29.1 | @uppy/store-default | 0.27.1 |
+| @uppy/dashboard | 0.29.1 | @uppy/store-redux | 0.27.1 |
+| @uppy/drag-drop | 0.29.1 | @uppy/thumbnail-generator | 0.29.1 |
+| @uppy/dropbox | 0.29.1 | @uppy/transloadit | 0.29.1 |
+| @uppy/file-input | 0.29.1 | @uppy/tus | 0.29.1 |
+| @uppy/form | 0.29.1 | @uppy/url | 0.29.1 |
+| @uppy/golden-retriever | 0.29.1 | @uppy/utils | 0.29.1 |
+| @uppy/google-drive | 0.29.1 | @uppy/webcam | 0.29.1 |
+| @uppy/informer | 0.29.1 | @uppy/xhr-upload | 0.29.1 |
+| @uppy/instagram | 0.29.1 | uppy | 0.29.1 |
+| @uppy/progress-bar | 0.29.1 | - | - |
+
+- @uppy/react: ⚠️ Make Uppy’s React components usable from Typescript (#1131 / @mattes3)
+- build: ⚠️ CJSify @uppy/core typings + add more typings tests (#1194 / @goto-bus-stop)
+- build: ⚠️ Added Promise and Fetch polyfills to uppy bundle (#1187 / @arturi)
+- build: ⚠️ Only rebuild changed files with `npm run build:lib` (#1237 / @goto-bus-stop)
+- build: ⚠️ Remove jsnext:main since it’s been deprecated https://github.com/stereobooster/package.json#jsnextmain (#1242 / @arturi)
+- @uppy/companion: ⚠️ Fix: return next page path for ig only when posts exist (e5a2694a2d95e1923dd2ca515e7d37132a5828ba / @ifedapoolarewaju)
+- @uppy/status-bar: Account for MS Edge’s missing progress updates, fixes #945. Previously, upload progress would be stuck at 0% until everything is finished. With this patch, in the affected MS Edge versions, the status bar is transformed into an “indeterminate” progress state (#1184 / @goto-bus-stop)
+- @uppy/dashboard: Log error if `trigger` is not found (#1217 / @goto-bus-stop)
+- @uppy/xhr-upload: Fix `responseType` in IE 11, fixes #1228: The same restriction applies to responseType as to withCredentials. Both must be set after the open() call in Internet Explorer. (#1231 / @goto-bus-stop)
+- @uppy/xhr-upload: Postpone timeout countdown until upload has started (i.e. has left browser concurrency queue (fixes #1190) (#1195 / @davilima6)
+- website: Add polyfills to website examples that do not use prebundled uppy.js (#1229 / @goto-bus-stop)
+- docs: Add privacy policy (#1196 / @arturi)
+- docs: Update aws-s3.md wrt S3 public access settings (#1236 / @manuelkiessling)
+- @uppy/companion: deprecate deprecate debugLogger (8f9946346904217e714e256db06b759cc3bb66b0 / @ifedapoolarewaju)
+- @uppy/companion: Update morgan dependency, fixes #1227 (#1232 / @goto-bus-stop)
 
 
 ## 0.29.0
 ## 0.29.0
 
 

+ 31 - 31
README.md

@@ -65,7 +65,7 @@ $ npm install @uppy/core @uppy/dashboard @uppy/tus
 
 
 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.29.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.29.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,10 +73,10 @@ Alternatively, you can also use a pre-built bundle from Transloadit's CDN: Edgly
 
 
 ```html
 ```html
 <!-- 1. Add CSS to `<head>` -->
 <!-- 1. Add CSS to `<head>` -->
-<link href="https://transloadit.edgly.net/releases/uppy/v0.29.0/dist/uppy.min.css" rel="stylesheet">
+<link href="https://transloadit.edgly.net/releases/uppy/v0.29.1/dist/uppy.min.css" rel="stylesheet">
 
 
 <!-- 2. Add JS before the closing `</body>` -->
 <!-- 2. Add JS before the closing `</body>` -->
-<script src="https://transloadit.edgly.net/releases/uppy/v0.29.0/dist/uppy.min.js"></script>
+<script src="https://transloadit.edgly.net/releases/uppy/v0.29.1/dist/uppy.min.js"></script>
 
 
 <!-- 3. Initialize -->
 <!-- 3. Initialize -->
 <div class="UppyDragDrop"></div>
 <div class="UppyDragDrop"></div>
@@ -163,7 +163,7 @@ If you're using Uppy via a script tag, you can load the polyfills from [JSDelivr
 ```html
 ```html
 <script src="https://cdn.jsdelivr.net/npm/es6-promise@4.2.5/dist/es6-promise.auto.min.js"></script>
 <script src="https://cdn.jsdelivr.net/npm/es6-promise@4.2.5/dist/es6-promise.auto.min.js"></script>
 <script src="https://cdn.jsdelivr.net/npm/whatwg-fetch@3.0.0/dist/fetch.umd.min.js"></script>
 <script src="https://cdn.jsdelivr.net/npm/whatwg-fetch@3.0.0/dist/fetch.umd.min.js"></script>
-<script src="https://transloadit.edgly.net/releases/uppy/v0.29.0/dist/uppy.min.js"></script>
+<script src="https://transloadit.edgly.net/releases/uppy/v0.29.1/dist/uppy.min.js"></script>
 ```
 ```
 
 
 ## FAQ
 ## FAQ
@@ -228,57 +228,57 @@ Use Uppy in your project? [Let us know](https://github.com/transloadit/uppy/issu
 :---: |:---: |:---: |:---: |:---: |:---: |
 :---: |:---: |:---: |:---: |:---: |:---: |
 [kiloreux](https://github.com/kiloreux) |[sadovnychyi](https://github.com/sadovnychyi) |[richardwillars](https://github.com/richardwillars) |[zcallan](https://github.com/zcallan) |[wilkoklak](https://github.com/wilkoklak) |[oliverpool](https://github.com/oliverpool) |
 [kiloreux](https://github.com/kiloreux) |[sadovnychyi](https://github.com/sadovnychyi) |[richardwillars](https://github.com/richardwillars) |[zcallan](https://github.com/zcallan) |[wilkoklak](https://github.com/wilkoklak) |[oliverpool](https://github.com/oliverpool) |
 
 
-[<img alt="nqst" src="https://avatars0.githubusercontent.com/u/375537?v=4&s=117" width="117">](https://github.com/nqst) |[<img alt="janko-m" src="https://avatars2.githubusercontent.com/u/795488?v=4&s=117" width="117">](https://github.com/janko-m) |[<img alt="DJWassink" src="https://avatars3.githubusercontent.com/u/1822404?v=4&s=117" width="117">](https://github.com/DJWassink) |[<img alt="taoqf" src="https://avatars3.githubusercontent.com/u/15901911?v=4&s=117" width="117">](https://github.com/taoqf) |[<img alt="gavboulton" src="https://avatars0.githubusercontent.com/u/3900826?v=4&s=117" width="117">](https://github.com/gavboulton) |[<img alt="bertho-zero" src="https://avatars0.githubusercontent.com/u/8525267?v=4&s=117" width="117">](https://github.com/bertho-zero) |
+[<img alt="nqst" src="https://avatars0.githubusercontent.com/u/375537?v=4&s=117" width="117">](https://github.com/nqst) |[<img alt="janko-m" src="https://avatars2.githubusercontent.com/u/795488?v=4&s=117" width="117">](https://github.com/janko-m) |[<img alt="mattes3" src="https://avatars2.githubusercontent.com/u/2496674?v=4&s=117" width="117">](https://github.com/mattes3) |[<img alt="DJWassink" src="https://avatars3.githubusercontent.com/u/1822404?v=4&s=117" width="117">](https://github.com/DJWassink) |[<img alt="taoqf" src="https://avatars3.githubusercontent.com/u/15901911?v=4&s=117" width="117">](https://github.com/taoqf) |[<img alt="gavboulton" src="https://avatars0.githubusercontent.com/u/3900826?v=4&s=117" width="117">](https://github.com/gavboulton) |
 :---: |:---: |:---: |:---: |:---: |:---: |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[nqst](https://github.com/nqst) |[janko-m](https://github.com/janko-m) |[DJWassink](https://github.com/DJWassink) |[taoqf](https://github.com/taoqf) |[gavboulton](https://github.com/gavboulton) |[bertho-zero](https://github.com/bertho-zero) |
+[nqst](https://github.com/nqst) |[janko-m](https://github.com/janko-m) |[mattes3](https://github.com/mattes3) |[DJWassink](https://github.com/DJWassink) |[taoqf](https://github.com/taoqf) |[gavboulton](https://github.com/gavboulton) |
 
 
-[<img alt="frederikhors" src="https://avatars3.githubusercontent.com/u/41120635?v=4&s=117" width="117">](https://github.com/frederikhors) |[<img alt="pauln" src="https://avatars3.githubusercontent.com/u/574359?v=4&s=117" width="117">](https://github.com/pauln) |[<img alt="toadkicker" src="https://avatars1.githubusercontent.com/u/523330?v=4&s=117" width="117">](https://github.com/toadkicker) |[<img alt="mrbatista" src="https://avatars0.githubusercontent.com/u/6544817?v=4&s=117" width="117">](https://github.com/mrbatista) |[<img alt="phitranphitranphitran" src="https://avatars2.githubusercontent.com/u/14257077?v=4&s=117" width="117">](https://github.com/phitranphitranphitran) |[<img alt="sunil-shrestha" src="https://avatars3.githubusercontent.com/u/2129058?v=4&s=117" width="117">](https://github.com/sunil-shrestha) |
+[<img alt="bertho-zero" src="https://avatars0.githubusercontent.com/u/8525267?v=4&s=117" width="117">](https://github.com/bertho-zero) |[<img alt="frederikhors" src="https://avatars3.githubusercontent.com/u/41120635?v=4&s=117" width="117">](https://github.com/frederikhors) |[<img alt="pauln" src="https://avatars3.githubusercontent.com/u/574359?v=4&s=117" width="117">](https://github.com/pauln) |[<img alt="toadkicker" src="https://avatars1.githubusercontent.com/u/523330?v=4&s=117" width="117">](https://github.com/toadkicker) |[<img alt="mrbatista" src="https://avatars0.githubusercontent.com/u/6544817?v=4&s=117" width="117">](https://github.com/mrbatista) |[<img alt="phitranphitranphitran" src="https://avatars2.githubusercontent.com/u/14257077?v=4&s=117" width="117">](https://github.com/phitranphitranphitran) |
 :---: |:---: |:---: |:---: |:---: |:---: |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[frederikhors](https://github.com/frederikhors) |[pauln](https://github.com/pauln) |[toadkicker](https://github.com/toadkicker) |[mrbatista](https://github.com/mrbatista) |[phitranphitranphitran](https://github.com/phitranphitranphitran) |[sunil-shrestha](https://github.com/sunil-shrestha) |
+[bertho-zero](https://github.com/bertho-zero) |[frederikhors](https://github.com/frederikhors) |[pauln](https://github.com/pauln) |[toadkicker](https://github.com/toadkicker) |[mrbatista](https://github.com/mrbatista) |[phitranphitranphitran](https://github.com/phitranphitranphitran) |
 
 
-[<img alt="tranvansang" src="https://avatars1.githubusercontent.com/u/13043196?v=4&s=117" width="117">](https://github.com/tranvansang) |[<img alt="ap--" src="https://avatars1.githubusercontent.com/u/1463443?v=4&s=117" width="117">](https://github.com/ap--) |[<img alt="tim-kos" src="https://avatars1.githubusercontent.com/u/15005?v=4&s=117" width="117">](https://github.com/tim-kos) |[<img alt="ogtfaber" src="https://avatars2.githubusercontent.com/u/320955?v=4&s=117" width="117">](https://github.com/ogtfaber) |[<img alt="btrice" src="https://avatars2.githubusercontent.com/u/4358225?v=4&s=117" width="117">](https://github.com/btrice) |[<img alt="pekala" src="https://avatars1.githubusercontent.com/u/4643658?v=4&s=117" width="117">](https://github.com/pekala) |
+[<img alt="sunil-shrestha" src="https://avatars3.githubusercontent.com/u/2129058?v=4&s=117" width="117">](https://github.com/sunil-shrestha) |[<img alt="tranvansang" src="https://avatars1.githubusercontent.com/u/13043196?v=4&s=117" width="117">](https://github.com/tranvansang) |[<img alt="ap--" src="https://avatars1.githubusercontent.com/u/1463443?v=4&s=117" width="117">](https://github.com/ap--) |[<img alt="tim-kos" src="https://avatars1.githubusercontent.com/u/15005?v=4&s=117" width="117">](https://github.com/tim-kos) |[<img alt="ogtfaber" src="https://avatars2.githubusercontent.com/u/320955?v=4&s=117" width="117">](https://github.com/ogtfaber) |[<img alt="btrice" src="https://avatars2.githubusercontent.com/u/4358225?v=4&s=117" width="117">](https://github.com/btrice) |
 :---: |:---: |:---: |:---: |:---: |:---: |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[tranvansang](https://github.com/tranvansang) |[ap--](https://github.com/ap--) |[tim-kos](https://github.com/tim-kos) |[ogtfaber](https://github.com/ogtfaber) |[btrice](https://github.com/btrice) |[pekala](https://github.com/pekala) |
+[sunil-shrestha](https://github.com/sunil-shrestha) |[tranvansang](https://github.com/tranvansang) |[ap--](https://github.com/ap--) |[tim-kos](https://github.com/tim-kos) |[ogtfaber](https://github.com/ogtfaber) |[btrice](https://github.com/btrice) |
 
 
-[<img alt="Martin005" src="https://avatars0.githubusercontent.com/u/10096404?v=4&s=117" width="117">](https://github.com/Martin005) |[<img alt="martiuslim" src="https://avatars2.githubusercontent.com/u/17944339?v=4&s=117" width="117">](https://github.com/martiuslim) |[<img alt="msand" src="https://avatars2.githubusercontent.com/u/1131362?v=4&s=117" width="117">](https://github.com/msand) |[<img alt="richartkeil" src="https://avatars0.githubusercontent.com/u/8680858?v=4&s=117" width="117">](https://github.com/richartkeil) |[<img alt="Burkes" src="https://avatars2.githubusercontent.com/u/9220052?v=4&s=117" width="117">](https://github.com/Burkes) |[<img alt="rosenfeld" src="https://avatars1.githubusercontent.com/u/32246?v=4&s=117" width="117">](https://github.com/rosenfeld) |
+[<img alt="pekala" src="https://avatars1.githubusercontent.com/u/4643658?v=4&s=117" width="117">](https://github.com/pekala) |[<img alt="manuelkiessling" src="https://avatars2.githubusercontent.com/u/206592?v=4&s=117" width="117">](https://github.com/manuelkiessling) |[<img alt="Martin005" src="https://avatars0.githubusercontent.com/u/10096404?v=4&s=117" width="117">](https://github.com/Martin005) |[<img alt="martiuslim" src="https://avatars2.githubusercontent.com/u/17944339?v=4&s=117" width="117">](https://github.com/martiuslim) |[<img alt="msand" src="https://avatars2.githubusercontent.com/u/1131362?v=4&s=117" width="117">](https://github.com/msand) |[<img alt="Burkes" src="https://avatars2.githubusercontent.com/u/9220052?v=4&s=117" width="117">](https://github.com/Burkes) |
 :---: |:---: |:---: |:---: |:---: |:---: |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[Martin005](https://github.com/Martin005) |[martiuslim](https://github.com/martiuslim) |[msand](https://github.com/msand) |[richartkeil](https://github.com/richartkeil) |[Burkes](https://github.com/Burkes) |[rosenfeld](https://github.com/rosenfeld) |
+[pekala](https://github.com/pekala) |[manuelkiessling](https://github.com/manuelkiessling) |[Martin005](https://github.com/Martin005) |[martiuslim](https://github.com/martiuslim) |[msand](https://github.com/msand) |[Burkes](https://github.com/Burkes) |
 
 
-[<img alt="ThomasG77" src="https://avatars2.githubusercontent.com/u/642120?v=4&s=117" width="117">](https://github.com/ThomasG77) |[<img alt="zhuangya" src="https://avatars2.githubusercontent.com/u/499038?v=4&s=117" width="117">](https://github.com/zhuangya) |[<img alt="fortrieb" src="https://avatars0.githubusercontent.com/u/4126707?v=4&s=117" width="117">](https://github.com/fortrieb) |[<img alt="muhammadInam" src="https://avatars1.githubusercontent.com/u/7801708?v=4&s=117" width="117">](https://github.com/muhammadInam) |[<img alt="richmeij" src="https://avatars0.githubusercontent.com/u/9741858?v=4&s=117" width="117">](https://github.com/richmeij) |[<img alt="ajschmidt8" src="https://avatars0.githubusercontent.com/u/7400326?v=4&s=117" width="117">](https://github.com/ajschmidt8) |
+[<img alt="richmeij" src="https://avatars0.githubusercontent.com/u/9741858?v=4&s=117" width="117">](https://github.com/richmeij) |[<img alt="rosenfeld" src="https://avatars1.githubusercontent.com/u/32246?v=4&s=117" width="117">](https://github.com/rosenfeld) |[<img alt="ThomasG77" src="https://avatars2.githubusercontent.com/u/642120?v=4&s=117" width="117">](https://github.com/ThomasG77) |[<img alt="zhuangya" src="https://avatars2.githubusercontent.com/u/499038?v=4&s=117" width="117">](https://github.com/zhuangya) |[<img alt="fortrieb" src="https://avatars0.githubusercontent.com/u/4126707?v=4&s=117" width="117">](https://github.com/fortrieb) |[<img alt="muhammadInam" src="https://avatars1.githubusercontent.com/u/7801708?v=4&s=117" width="117">](https://github.com/muhammadInam) |
 :---: |:---: |:---: |:---: |:---: |:---: |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[ThomasG77](https://github.com/ThomasG77) |[zhuangya](https://github.com/zhuangya) |[fortrieb](https://github.com/fortrieb) |[muhammadInam](https://github.com/muhammadInam) |[richmeij](https://github.com/richmeij) |[ajschmidt8](https://github.com/ajschmidt8) |
+[richmeij](https://github.com/richmeij) |[rosenfeld](https://github.com/rosenfeld) |[ThomasG77](https://github.com/ThomasG77) |[zhuangya](https://github.com/zhuangya) |[fortrieb](https://github.com/fortrieb) |[muhammadInam](https://github.com/muhammadInam) |
 
 
-[<img alt="asmt3" src="https://avatars1.githubusercontent.com/u/1777709?v=4&s=117" width="117">](https://github.com/asmt3) |[<img alt="tuoxiansp" src="https://avatars1.githubusercontent.com/u/3960056?v=4&s=117" width="117">](https://github.com/tuoxiansp) |[<img alt="functino" src="https://avatars0.githubusercontent.com/u/415498?v=4&s=117" width="117">](https://github.com/functino) |[<img alt="radarhere" src="https://avatars2.githubusercontent.com/u/3112309?v=4&s=117" width="117">](https://github.com/radarhere) |[<img alt="azeemba" src="https://avatars0.githubusercontent.com/u/2160795?v=4&s=117" width="117">](https://github.com/azeemba) |[<img alt="bducharme" src="https://avatars2.githubusercontent.com/u/4173569?v=4&s=117" width="117">](https://github.com/bducharme) |
+[<img alt="richartkeil" src="https://avatars0.githubusercontent.com/u/8680858?v=4&s=117" width="117">](https://github.com/richartkeil) |[<img alt="ajschmidt8" src="https://avatars0.githubusercontent.com/u/7400326?v=4&s=117" width="117">](https://github.com/ajschmidt8) |[<img alt="tuoxiansp" src="https://avatars1.githubusercontent.com/u/3960056?v=4&s=117" width="117">](https://github.com/tuoxiansp) |[<img alt="amitport" src="https://avatars1.githubusercontent.com/u/1131991?v=4&s=117" width="117">](https://github.com/amitport) |[<img alt="functino" src="https://avatars0.githubusercontent.com/u/415498?v=4&s=117" width="117">](https://github.com/functino) |[<img alt="radarhere" src="https://avatars2.githubusercontent.com/u/3112309?v=4&s=117" width="117">](https://github.com/radarhere) |
 :---: |:---: |:---: |:---: |:---: |:---: |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[asmt3](https://github.com/asmt3) |[tuoxiansp](https://github.com/tuoxiansp) |[functino](https://github.com/functino) |[radarhere](https://github.com/radarhere) |[azeemba](https://github.com/azeemba) |[bducharme](https://github.com/bducharme) |
+[richartkeil](https://github.com/richartkeil) |[ajschmidt8](https://github.com/ajschmidt8) |[tuoxiansp](https://github.com/tuoxiansp) |[amitport](https://github.com/amitport) |[functino](https://github.com/functino) |[radarhere](https://github.com/radarhere) |
 
 
-[<img alt="chao" src="https://avatars2.githubusercontent.com/u/55872?v=4&s=117" width="117">](https://github.com/chao) |[<img alt="csprance" src="https://avatars0.githubusercontent.com/u/7902617?v=4&s=117" width="117">](https://github.com/csprance) |[<img alt="cbush06" src="https://avatars0.githubusercontent.com/u/15720146?v=4&s=117" width="117">](https://github.com/cbush06) |[<img alt="danmichaelo" src="https://avatars1.githubusercontent.com/u/434495?v=4&s=117" width="117">](https://github.com/danmichaelo) |[<img alt="mrboomer" src="https://avatars0.githubusercontent.com/u/5942912?v=4&s=117" width="117">](https://github.com/mrboomer) |[<img alt="yoldar" src="https://avatars3.githubusercontent.com/u/1597578?v=4&s=117" width="117">](https://github.com/yoldar) |
+[<img alt="azeemba" src="https://avatars0.githubusercontent.com/u/2160795?v=4&s=117" width="117">](https://github.com/azeemba) |[<img alt="bducharme" src="https://avatars2.githubusercontent.com/u/4173569?v=4&s=117" width="117">](https://github.com/bducharme) |[<img alt="chao" src="https://avatars2.githubusercontent.com/u/55872?v=4&s=117" width="117">](https://github.com/chao) |[<img alt="csprance" src="https://avatars0.githubusercontent.com/u/7902617?v=4&s=117" width="117">](https://github.com/csprance) |[<img alt="cbush06" src="https://avatars0.githubusercontent.com/u/15720146?v=4&s=117" width="117">](https://github.com/cbush06) |[<img alt="danmichaelo" src="https://avatars1.githubusercontent.com/u/434495?v=4&s=117" width="117">](https://github.com/danmichaelo) |
 :---: |:---: |:---: |:---: |:---: |:---: |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[chao](https://github.com/chao) |[csprance](https://github.com/csprance) |[cbush06](https://github.com/cbush06) |[danmichaelo](https://github.com/danmichaelo) |[mrboomer](https://github.com/mrboomer) |[yoldar](https://github.com/yoldar) |
+[azeemba](https://github.com/azeemba) |[bducharme](https://github.com/bducharme) |[chao](https://github.com/chao) |[csprance](https://github.com/csprance) |[cbush06](https://github.com/cbush06) |[danmichaelo](https://github.com/danmichaelo) |
 
 
-[<img alt="lowsprofile" src="https://avatars1.githubusercontent.com/u/11029687?v=4&s=117" width="117">](https://github.com/lowsprofile) |[<img alt="FWirtz" src="https://avatars1.githubusercontent.com/u/6052785?v=4&s=117" width="117">](https://github.com/FWirtz) |[<img alt="geoffappleford" src="https://avatars2.githubusercontent.com/u/731678?v=4&s=117" width="117">](https://github.com/geoffappleford) |[<img alt="gjungb" src="https://avatars0.githubusercontent.com/u/3391068?v=4&s=117" width="117">](https://github.com/gjungb) |[<img alt="JacobMGEvans" src="https://avatars1.githubusercontent.com/u/27247160?v=4&s=117" width="117">](https://github.com/JacobMGEvans) |[<img alt="jcjmcclean" src="https://avatars3.githubusercontent.com/u/1822574?v=4&s=117" width="117">](https://github.com/jcjmcclean) |
+[<img alt="mrboomer" src="https://avatars0.githubusercontent.com/u/5942912?v=4&s=117" width="117">](https://github.com/mrboomer) |[<img alt="davilima6" src="https://avatars0.githubusercontent.com/u/422130?v=4&s=117" width="117">](https://github.com/davilima6) |[<img alt="yoldar" src="https://avatars3.githubusercontent.com/u/1597578?v=4&s=117" width="117">](https://github.com/yoldar) |[<img alt="lowsprofile" src="https://avatars1.githubusercontent.com/u/11029687?v=4&s=117" width="117">](https://github.com/lowsprofile) |[<img alt="FWirtz" src="https://avatars1.githubusercontent.com/u/6052785?v=4&s=117" width="117">](https://github.com/FWirtz) |[<img alt="geoffappleford" src="https://avatars2.githubusercontent.com/u/731678?v=4&s=117" width="117">](https://github.com/geoffappleford) |
 :---: |:---: |:---: |:---: |:---: |:---: |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[lowsprofile](https://github.com/lowsprofile) |[FWirtz](https://github.com/FWirtz) |[geoffappleford](https://github.com/geoffappleford) |[gjungb](https://github.com/gjungb) |[JacobMGEvans](https://github.com/JacobMGEvans) |[jcjmcclean](https://github.com/jcjmcclean) |
+[mrboomer](https://github.com/mrboomer) |[davilima6](https://github.com/davilima6) |[yoldar](https://github.com/yoldar) |[lowsprofile](https://github.com/lowsprofile) |[FWirtz](https://github.com/FWirtz) |[geoffappleford](https://github.com/geoffappleford) |
 
 
-[<img alt="vith" src="https://avatars1.githubusercontent.com/u/3265539?v=4&s=117" width="117">](https://github.com/vith) |[<img alt="jessica-coursera" src="https://avatars1.githubusercontent.com/u/35155465?v=4&s=117" width="117">](https://github.com/jessica-coursera) |[<img alt="jderrough" src="https://avatars3.githubusercontent.com/u/1108358?v=4&s=117" width="117">](https://github.com/jderrough) |[<img alt="firesharkstudios" src="https://avatars1.githubusercontent.com/u/17069637?v=4&s=117" width="117">](https://github.com/firesharkstudios) |[<img alt="dviry" src="https://avatars3.githubusercontent.com/u/1230260?v=4&s=117" width="117">](https://github.com/dviry) |[<img alt="leods92" src="https://avatars0.githubusercontent.com/u/879395?v=4&s=117" width="117">](https://github.com/leods92) |
+[<img alt="gjungb" src="https://avatars0.githubusercontent.com/u/3391068?v=4&s=117" width="117">](https://github.com/gjungb) |[<img alt="JacobMGEvans" src="https://avatars1.githubusercontent.com/u/27247160?v=4&s=117" width="117">](https://github.com/JacobMGEvans) |[<img alt="jcjmcclean" src="https://avatars3.githubusercontent.com/u/1822574?v=4&s=117" width="117">](https://github.com/jcjmcclean) |[<img alt="vith" src="https://avatars1.githubusercontent.com/u/3265539?v=4&s=117" width="117">](https://github.com/vith) |[<img alt="jessica-coursera" src="https://avatars1.githubusercontent.com/u/35155465?v=4&s=117" width="117">](https://github.com/jessica-coursera) |[<img alt="jderrough" src="https://avatars3.githubusercontent.com/u/1108358?v=4&s=117" width="117">](https://github.com/jderrough) |
 :---: |:---: |:---: |:---: |:---: |:---: |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[vith](https://github.com/vith) |[jessica-coursera](https://github.com/jessica-coursera) |[jderrough](https://github.com/jderrough) |[firesharkstudios](https://github.com/firesharkstudios) |[dviry](https://github.com/dviry) |[leods92](https://github.com/leods92) |
+[gjungb](https://github.com/gjungb) |[JacobMGEvans](https://github.com/JacobMGEvans) |[jcjmcclean](https://github.com/jcjmcclean) |[vith](https://github.com/vith) |[jessica-coursera](https://github.com/jessica-coursera) |[jderrough](https://github.com/jderrough) |
 
 
-[<img alt="lucaperret" src="https://avatars1.githubusercontent.com/u/1887122?v=4&s=117" width="117">](https://github.com/lucaperret) |[<img alt="mperrando" src="https://avatars2.githubusercontent.com/u/525572?v=4&s=117" width="117">](https://github.com/mperrando) |[<img alt="mnafees" src="https://avatars1.githubusercontent.com/u/1763885?v=4&s=117" width="117">](https://github.com/mnafees) |[<img alt="phillipalexander" src="https://avatars0.githubusercontent.com/u/1577682?v=4&s=117" width="117">](https://github.com/phillipalexander) |[<img alt="luarmr" src="https://avatars3.githubusercontent.com/u/817416?v=4&s=117" width="117">](https://github.com/luarmr) |[<img alt="phobos101" src="https://avatars2.githubusercontent.com/u/7114944?v=4&s=117" width="117">](https://github.com/phobos101) |
+[<img alt="firesharkstudios" src="https://avatars1.githubusercontent.com/u/17069637?v=4&s=117" width="117">](https://github.com/firesharkstudios) |[<img alt="kyleparisi" src="https://avatars0.githubusercontent.com/u/1286753?v=4&s=117" width="117">](https://github.com/kyleparisi) |[<img alt="dviry" src="https://avatars3.githubusercontent.com/u/1230260?v=4&s=117" width="117">](https://github.com/dviry) |[<img alt="leods92" src="https://avatars0.githubusercontent.com/u/879395?v=4&s=117" width="117">](https://github.com/leods92) |[<img alt="lucaperret" src="https://avatars1.githubusercontent.com/u/1887122?v=4&s=117" width="117">](https://github.com/lucaperret) |[<img alt="mperrando" src="https://avatars2.githubusercontent.com/u/525572?v=4&s=117" width="117">](https://github.com/mperrando) |
 :---: |:---: |:---: |:---: |:---: |:---: |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[lucaperret](https://github.com/lucaperret) |[mperrando](https://github.com/mperrando) |[mnafees](https://github.com/mnafees) |[phillipalexander](https://github.com/phillipalexander) |[luarmr](https://github.com/luarmr) |[phobos101](https://github.com/phobos101) |
+[firesharkstudios](https://github.com/firesharkstudios) |[kyleparisi](https://github.com/kyleparisi) |[dviry](https://github.com/dviry) |[leods92](https://github.com/leods92) |[lucaperret](https://github.com/lucaperret) |[mperrando](https://github.com/mperrando) |
 
 
-[<img alt="fortunto2" src="https://avatars1.githubusercontent.com/u/1236751?v=4&s=117" width="117">](https://github.com/fortunto2) |[<img alt="sergei-zelinsky" src="https://avatars2.githubusercontent.com/u/19428086?v=4&s=117" width="117">](https://github.com/sergei-zelinsky) |[<img alt="tomsaleeba" src="https://avatars0.githubusercontent.com/u/1773838?v=4&s=117" width="117">](https://github.com/tomsaleeba) |[<img alt="vially" src="https://avatars1.githubusercontent.com/u/433598?v=4&s=117" width="117">](https://github.com/vially) |[<img alt="eltercero" src="https://avatars0.githubusercontent.com/u/545235?v=4&s=117" width="117">](https://github.com/eltercero) |[<img alt="xhocquet" src="https://avatars2.githubusercontent.com/u/8116516?v=4&s=117" width="117">](https://github.com/xhocquet) |
+[<img alt="mnafees" src="https://avatars1.githubusercontent.com/u/1763885?v=4&s=117" width="117">](https://github.com/mnafees) |[<img alt="phillipalexander" src="https://avatars0.githubusercontent.com/u/1577682?v=4&s=117" width="117">](https://github.com/phillipalexander) |[<img alt="luarmr" src="https://avatars3.githubusercontent.com/u/817416?v=4&s=117" width="117">](https://github.com/luarmr) |[<img alt="phobos101" src="https://avatars2.githubusercontent.com/u/7114944?v=4&s=117" width="117">](https://github.com/phobos101) |[<img alt="fortunto2" src="https://avatars1.githubusercontent.com/u/1236751?v=4&s=117" width="117">](https://github.com/fortunto2) |[<img alt="sergei-zelinsky" src="https://avatars2.githubusercontent.com/u/19428086?v=4&s=117" width="117">](https://github.com/sergei-zelinsky) |
 :---: |:---: |:---: |:---: |:---: |:---: |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[fortunto2](https://github.com/fortunto2) |[sergei-zelinsky](https://github.com/sergei-zelinsky) |[tomsaleeba](https://github.com/tomsaleeba) |[vially](https://github.com/vially) |[eltercero](https://github.com/eltercero) |[xhocquet](https://github.com/xhocquet) |
+[mnafees](https://github.com/mnafees) |[phillipalexander](https://github.com/phillipalexander) |[luarmr](https://github.com/luarmr) |[phobos101](https://github.com/phobos101) |[fortunto2](https://github.com/fortunto2) |[sergei-zelinsky](https://github.com/sergei-zelinsky) |
 
 
-[<img alt="avalla" src="https://avatars1.githubusercontent.com/u/986614?v=4&s=117" width="117">](https://github.com/avalla) |[<img alt="bartvde" src="https://avatars3.githubusercontent.com/u/319678?v=4&s=117" width="117">](https://github.com/bartvde) |[<img alt="c0b41" src="https://avatars1.githubusercontent.com/u/2834954?v=4&s=117" width="117">](https://github.com/c0b41) |[<img alt="craigcbrunner" src="https://avatars3.githubusercontent.com/u/2780521?v=4&s=117" width="117">](https://github.com/craigcbrunner) |[<img alt="franckl" src="https://avatars0.githubusercontent.com/u/3875803?v=4&s=117" width="117">](https://github.com/franckl) |[<img alt="luntta" src="https://avatars0.githubusercontent.com/u/14221637?v=4&s=117" width="117">](https://github.com/luntta) |
+[<img alt="tomsaleeba" src="https://avatars0.githubusercontent.com/u/1773838?v=4&s=117" width="117">](https://github.com/tomsaleeba) |[<img alt="vially" src="https://avatars1.githubusercontent.com/u/433598?v=4&s=117" width="117">](https://github.com/vially) |[<img alt="eltercero" src="https://avatars0.githubusercontent.com/u/545235?v=4&s=117" width="117">](https://github.com/eltercero) |[<img alt="xhocquet" src="https://avatars2.githubusercontent.com/u/8116516?v=4&s=117" width="117">](https://github.com/xhocquet) |[<img alt="avalla" src="https://avatars1.githubusercontent.com/u/986614?v=4&s=117" width="117">](https://github.com/avalla) |[<img alt="c0b41" src="https://avatars1.githubusercontent.com/u/2834954?v=4&s=117" width="117">](https://github.com/c0b41) |
 :---: |:---: |:---: |:---: |:---: |:---: |
 :---: |:---: |:---: |:---: |:---: |:---: |
-[avalla](https://github.com/avalla) |[bartvde](https://github.com/bartvde) |[c0b41](https://github.com/c0b41) |[craigcbrunner](https://github.com/craigcbrunner) |[franckl](https://github.com/franckl) |[luntta](https://github.com/luntta) |
+[tomsaleeba](https://github.com/tomsaleeba) |[vially](https://github.com/vially) |[eltercero](https://github.com/eltercero) |[xhocquet](https://github.com/xhocquet) |[avalla](https://github.com/avalla) |[c0b41](https://github.com/c0b41) |
 
 
-[<img alt="rhymes" src="https://avatars3.githubusercontent.com/u/146201?v=4&s=117" width="117">](https://github.com/rhymes) |[<img alt="amitport" src="https://avatars1.githubusercontent.com/u/1131991?v=4&s=117" width="117">](https://github.com/amitport) |
-:---: |:---: |
-[rhymes](https://github.com/rhymes) |[amitport](https://github.com/amitport) |
+[<img alt="craigcbrunner" src="https://avatars3.githubusercontent.com/u/2780521?v=4&s=117" width="117">](https://github.com/craigcbrunner) |[<img alt="franckl" src="https://avatars0.githubusercontent.com/u/3875803?v=4&s=117" width="117">](https://github.com/franckl) |[<img alt="luntta" src="https://avatars0.githubusercontent.com/u/14221637?v=4&s=117" width="117">](https://github.com/luntta) |[<img alt="rhymes" src="https://avatars3.githubusercontent.com/u/146201?v=4&s=117" width="117">](https://github.com/rhymes) |[<img alt="asmt3" src="https://avatars1.githubusercontent.com/u/1777709?v=4&s=117" width="117">](https://github.com/asmt3) |
+:---: |:---: |:---: |:---: |:---: |
+[craigcbrunner](https://github.com/craigcbrunner) |[franckl](https://github.com/franckl) |[luntta](https://github.com/luntta) |[rhymes](https://github.com/rhymes) |[asmt3](https://github.com/asmt3) |
 <!--/contributors-->
 <!--/contributors-->
 
 
 ## License
 ## License

+ 0 - 0
uppy-screenshot.jpg → assets/uppy-screenshot.jpg


+ 30 - 1
bin/build-lib.js

@@ -8,17 +8,45 @@ const path = require('path')
 
 
 const transformFile = promisify(babel.transformFile)
 const transformFile = promisify(babel.transformFile)
 const writeFile = promisify(fs.writeFile)
 const writeFile = promisify(fs.writeFile)
+const stat = promisify(fs.stat)
 
 
 const SOURCE = 'packages/{*,@uppy/*}/src/**/*.js'
 const SOURCE = 'packages/{*,@uppy/*}/src/**/*.js'
 // Files not to build (such as tests)
 // Files not to build (such as tests)
 const IGNORE = /\.test\.js$|__mocks__|companion\//
 const IGNORE = /\.test\.js$|__mocks__|companion\//
+// Files that should trigger a rebuild of everything on change
+const META_FILES = [
+  '.babelrc',
+  'package.json',
+  'package-lock.json',
+  'bin/build-lib.js'
+]
+
+function lastModified (file) {
+  return stat(file).then((s) => s.mtime)
+}
 
 
 async function buildLib () {
 async function buildLib () {
+  const metaMtimes = await Promise.all(META_FILES.map((filename) =>
+    lastModified(path.join(__dirname, '..', filename))
+  ))
+  const metaMtime = Math.max(...metaMtimes)
+
   const files = await glob(SOURCE)
   const files = await glob(SOURCE)
   for (const file of files) {
   for (const file of files) {
     if (IGNORE.test(file)) continue
     if (IGNORE.test(file)) continue
-
     const libFile = file.replace('/src/', '/lib/')
     const libFile = file.replace('/src/', '/lib/')
+
+    // on a fresh build, rebuild everything.
+    if (!process.env.FRESH) {
+      const srcMtime = await lastModified(file)
+      const libMtime = await lastModified(libFile)
+        .catch(() => 0) // probably doesn't exist
+      // Skip files that haven't changed
+      if (srcMtime < libMtime && metaMtime < libMtime) {
+        continue
+      }
+    }
+
     const { code, map } = await transformFile(file, {})
     const { code, map } = await transformFile(file, {})
     await mkdirp(path.dirname(libFile))
     await mkdirp(path.dirname(libFile))
     await Promise.all([
     await Promise.all([
@@ -29,6 +57,7 @@ async function buildLib () {
   }
   }
 }
 }
 
 
+console.log('Using Babel version:', require('babel-core/package.json').version)
 buildLib().catch((err) => {
 buildLib().catch((err) => {
   console.error(err.stack)
   console.error(err.stack)
   process.exit(1)
   process.exit(1)

+ 1 - 1
bin/release

@@ -59,7 +59,7 @@ git add README.md
 cp README.md packages/uppy/README.md
 cp README.md packages/uppy/README.md
 
 
 npm run clean
 npm run clean
-npm run build
+FRESH=1 npm run build
 
 
 git commit -m "Release"
 git commit -m "Release"
 lerna version --amend --no-push --exact
 lerna version --amend --no-push --exact

+ 10 - 0
bin/to-gif-hd.sh

@@ -0,0 +1,10 @@
+#!/bin/sh
+# Convert a video file to a gif.
+# `to-gif /path/to/input.mp4 /path/to/output.gif`
+palette="/tmp/to-gif-palette.png"
+filters="fps=15"
+ffmpeg -v warning -i $1 -vf "$filters,palettegen" -y $palette
+ffmpeg -v warning -i $1 -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y $2
+
+# resize after
+# gifsicle --resize-fit-width 1000 -i animation.gif > animation-1000px.gif

+ 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.29.0/dist/uppy.css
+#  - Runs npm pack, and stores files to e.g. https://transloadit.edgly.net/releases/uppy/v0.29.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.29.0/dist/uppy.min.css" rel="stylesheet">
+    <link href="https://transloadit.edgly.net/releases/uppy/v0.29.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.29.0/dist/uppy.min.js"></script>
+    <script src="https://transloadit.edgly.net/releases/uppy/v0.29.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 - 4
examples/react-example/App.js

@@ -14,16 +14,14 @@ module.exports = class App extends React.Component {
       open: false
       open: false
     }
     }
 
 
-    this.handleModalClick = this.handleModalClick.bind(this)
-  }
-
-  componentWillMount () {
     this.uppy = new Uppy({ id: 'uppy1', autoProceed: true, debug: true })
     this.uppy = new Uppy({ id: 'uppy1', autoProceed: true, debug: true })
       .use(Tus, { endpoint: 'https://master.tus.io/files/' })
       .use(Tus, { endpoint: 'https://master.tus.io/files/' })
       .use(GoogleDrive, { serverUrl: 'https://companion.uppy.io' })
       .use(GoogleDrive, { serverUrl: 'https://companion.uppy.io' })
 
 
     this.uppy2 = new Uppy({ id: 'uppy2', autoProceed: false, debug: true })
     this.uppy2 = new Uppy({ id: 'uppy2', autoProceed: false, debug: true })
       .use(Tus, { endpoint: 'https://master.tus.io/files/' })
       .use(Tus, { endpoint: 'https://master.tus.io/files/' })
+
+    this.handleModalClick = this.handleModalClick.bind(this)
   }
   }
 
 
   componentWillUnmount () {
   componentWillUnmount () {

+ 2 - 2
examples/uppy-with-companion/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.29.0/dist/uppy.min.css" rel="stylesheet">
+    <link href="https://transloadit.edgly.net/releases/uppy/v0.29.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.29.0/dist/uppy.min.js"></script>
+    <script src="https://transloadit.edgly.net/releases/uppy/v0.29.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' })

Разлика између датотеке није приказан због своје велике величине
+ 472 - 93
package-lock.json


+ 4 - 3
package.json

@@ -85,7 +85,7 @@
     "build:gzip": "node ./bin/gzip.js",
     "build:gzip": "node ./bin/gzip.js",
     "size": "echo 'JS Bundle mingz:' && cat ./packages/uppy/dist/uppy.min.js | gzip | wc -c && echo 'CSS Bundle mingz:' && cat ./packages/uppy/dist/uppy.min.css | gzip | wc -c",
     "size": "echo 'JS Bundle mingz:' && cat ./packages/uppy/dist/uppy.min.js | gzip | wc -c && echo 'CSS Bundle mingz:' && cat ./packages/uppy/dist/uppy.min.css | gzip | wc -c",
     "build:js": "npm-run-all build:lib build:bundle",
     "build:js": "npm-run-all build:lib build:bundle",
-    "build:lib": "babel --version && node ./bin/build-lib.js",
+    "build:lib": "node ./bin/build-lib.js",
     "build": "npm-run-all --parallel build:js build:css build:companion --serial build:gzip size",
     "build": "npm-run-all --parallel build:js build:css build:companion --serial build:gzip size",
     "clean": "rm -rf packages/*/lib packages/@uppy/*/lib && rm -rf packages/uppy/dist",
     "clean": "rm -rf packages/*/lib packages/@uppy/*/lib && rm -rf packages/uppy/dist",
     "lint:fix": "npm run lint -- --fix",
     "lint:fix": "npm run lint -- --fix",
@@ -101,7 +101,7 @@
     "test:prepare-ci": "npm-run-all --parallel --race test:registry test:build-ci",
     "test:prepare-ci": "npm-run-all --parallel --race test:registry test:build-ci",
     "test:acceptance": "npm run test:prepare-ci && wdio test/endtoend/wdio.remote.conf.js",
     "test:acceptance": "npm run test:prepare-ci && wdio test/endtoend/wdio.remote.conf.js",
     "test:acceptance:local": "npm run test:build && wdio test/endtoend/wdio.local.conf.js",
     "test:acceptance:local": "npm run test:build && wdio test/endtoend/wdio.local.conf.js",
-    "test:unit": "jest",
+    "test:unit": "npm run build:lib && jest",
     "test:companion": "cd ./packages/@uppy/companion && npm run test",
     "test:companion": "cd ./packages/@uppy/companion && npm run test",
     "test:type": "tsc -p .",
     "test:type": "tsc -p .",
     "test": "npm run lint && npm run test:unit && npm run test:type && npm run test:companion",
     "test": "npm run lint && npm run test:unit && npm run test:type && npm run test:companion",
@@ -141,5 +141,6 @@
     "testMatch": [
     "testMatch": [
       "**/packages/**/*.test.js"
       "**/packages/**/*.test.js"
     ]
     ]
-  }
+  },
+  "dependencies": {}
 }
 }

+ 4 - 5
packages/@uppy/aws-s3-multipart/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/aws-s3-multipart",
   "name": "@uppy/aws-s3-multipart",
   "description": "Upload to Amazon S3 with Uppy and S3's Multipart upload strategy",
   "description": "Upload to Amazon S3 with Uppy and S3's Multipart upload strategy",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",
@@ -24,12 +23,12 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/companion-client": "0.27.2",
-    "@uppy/utils": "0.29.0",
+    "@uppy/companion-client": "0.27.3",
+    "@uppy/utils": "0.29.1",
     "resolve-url": "^0.2.1"
     "resolve-url": "^0.2.1"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 10 - 2
packages/@uppy/aws-s3-multipart/src/index.js

@@ -171,7 +171,11 @@ module.exports = class AwsS3Multipart extends Plugin {
           reject(err)
           reject(err)
         },
         },
         onSuccess: (result) => {
         onSuccess: (result) => {
-          this.uppy.emit('upload-success', file, upload, result.location)
+          const uploadResp = {
+            uploadURL: result.location
+          }
+
+          this.uppy.emit('upload-success', file, uploadResp)
 
 
           if (result.location) {
           if (result.location) {
             this.uppy.log('Download ' + upload.file.name + ' from ' + result.location)
             this.uppy.log('Download ' + upload.file.name + ' from ' + result.location)
@@ -328,7 +332,11 @@ module.exports = class AwsS3Multipart extends Plugin {
       })
       })
 
 
       socket.on('success', (data) => {
       socket.on('success', (data) => {
-        this.uppy.emit('upload-success', file, data, data.url)
+        const uploadResp = {
+          uploadURL: data.url
+        }
+
+        this.uppy.emit('upload-success', file, uploadResp)
         resolve()
         resolve()
       })
       })
     })
     })

+ 5 - 6
packages/@uppy/aws-s3/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/aws-s3",
   "name": "@uppy/aws-s3",
   "description": "Upload to Amazon S3 with Uppy",
   "description": "Upload to Amazon S3 with Uppy",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",
@@ -23,13 +22,13 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/companion-client": "0.27.2",
-    "@uppy/utils": "0.29.0",
-    "@uppy/xhr-upload": "0.29.0",
+    "@uppy/companion-client": "0.27.3",
+    "@uppy/utils": "0.29.1",
+    "@uppy/xhr-upload": "0.29.1",
     "resolve-url": "^0.2.1"
     "resolve-url": "^0.2.1"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 2 - 2
packages/@uppy/aws-s3/src/index.js

@@ -70,8 +70,8 @@ module.exports = class AwsS3 extends Plugin {
       throw new Error('Expected a `serverUrl` option containing a Companion address.')
       throw new Error('Expected a `serverUrl` option containing a Companion address.')
     }
     }
 
 
-    const filename = encodeURIComponent(file.name)
-    const type = encodeURIComponent(file.type)
+    const filename = encodeURIComponent(file.meta.name)
+    const type = encodeURIComponent(file.meta.type)
     return this.client.get(`s3/params?filename=${filename}&type=${type}`)
     return this.client.get(`s3/params?filename=${filename}&type=${type}`)
       .then(assertServerError)
       .then(assertServerError)
   }
   }

+ 1 - 2
packages/@uppy/companion-client/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/companion-client",
   "name": "@uppy/companion-client",
   "description": "Client library for communication with Companion. Intended for use in Uppy plugins.",
   "description": "Client library for communication with Companion. Intended for use in Uppy plugins.",
-  "version": "0.27.2",
+  "version": "0.27.3",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",

+ 19 - 19
packages/@uppy/companion/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@uppy/companion",
   "name": "@uppy/companion",
-  "version": "0.16.0",
+  "version": "0.16.1",
   "description": "OAuth helper and remote fetcher for Uppy's (https://uppy.io) 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:",
   "description": "OAuth helper and remote fetcher for Uppy's (https://uppy.io) 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:",
   "main": "lib/uppy.js",
   "main": "lib/uppy.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
@@ -30,34 +30,34 @@
   },
   },
   "dependencies": {
   "dependencies": {
     "@purest/providers": "1.0.0",
     "@purest/providers": "1.0.0",
-    "@uppy/fs-tail-stream": "^1.2.0",
+    "@uppy/fs-tail-stream": "1.2.0",
     "atob": "2.1.0",
     "atob": "2.1.0",
-    "aws-sdk": "^2.254.1",
+    "aws-sdk": "2.388.0",
     "body-parser": "1.18.2",
     "body-parser": "1.18.2",
-    "common-tags": "^1.7.2",
-    "connect-redis": "^3.3.0",
+    "common-tags": "1.8.0",
+    "connect-redis": "3.4.0",
     "cookie-parser": "1.4.3",
     "cookie-parser": "1.4.3",
-    "express": "^4.16.0",
-    "express-interceptor": "^1.2.0",
-    "express-prom-bundle": "^3.1.0",
+    "express": "4.16.3",
+    "express-interceptor": "1.2.0",
+    "express-prom-bundle": "3.3.0",
     "express-session": "1.15.6",
     "express-session": "1.15.6",
     "grant-express": "4.1.2",
     "grant-express": "4.1.2",
     "helmet": "3.8.2",
     "helmet": "3.8.2",
     "isobject": "3.0.1",
     "isobject": "3.0.1",
-    "jsonwebtoken": "^8.0.1",
-    "lodash.merge": "^4.6.0",
+    "jsonwebtoken": "8.3.0",
+    "lodash.merge": "4.6.1",
     "morgan": "1.9.1",
     "morgan": "1.9.1",
-    "ms": "^2.0.0",
-    "node-redis-pubsub": "^2.0.0",
-    "node-schedule": "^1.3.0",
-    "prom-client": "^10.0.2",
+    "ms": "2.1.1",
+    "node-redis-pubsub": "2.0.0",
+    "node-schedule": "1.3.1",
+    "prom-client": "10.2.3",
     "purest": "3.0.0",
     "purest": "3.0.0",
-    "redis": "^2.7.1",
+    "redis": "2.8.0",
     "request": "2.85.0",
     "request": "2.85.0",
-    "serialize-error": "^2.1.0",
-    "tus-js-client": "^1.5.1",
-    "uuid": "2.0.2",
-    "validator": "^9.0.0",
+    "serialize-error": "2.1.0",
+    "tus-js-client": "1.6.0",
+    "uuid": "3.3.2",
+    "validator": "9.4.1",
     "ws": "1.1.5"
     "ws": "1.1.5"
   },
   },
   "devDependencies": {
   "devDependencies": {

+ 1 - 1
packages/@uppy/companion/src/uppy.js

@@ -51,7 +51,7 @@ module.exports.app = (options = {}) => {
 
 
   // create singleton redis client
   // create singleton redis client
   if (options.redisUrl) {
   if (options.redisUrl) {
-    redis.client({ url: options.redisUrl })
+    redis.client(merge({ url: options.redisUrl }, options.redisOptions || {}))
   }
   }
   emitter(options.multipleInstances && options.redisUrl)
   emitter(options.multipleInstances && options.redisUrl)
 
 

+ 3 - 4
packages/@uppy/core/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/core",
   "name": "@uppy/core",
   "description": "Core module for the 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:",
   "description": "Core module for the 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:",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
@@ -21,8 +20,8 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/store-default": "0.27.0",
-    "@uppy/utils": "0.29.0",
+    "@uppy/store-default": "0.27.1",
+    "@uppy/utils": "0.29.1",
     "cuid": "^2.1.1",
     "cuid": "^2.1.1",
     "lodash.throttle": "^4.1.1",
     "lodash.throttle": "^4.1.1",
     "mime-match": "^1.0.2",
     "mime-match": "^1.0.2",

+ 9 - 4
packages/@uppy/core/src/index.js

@@ -695,8 +695,12 @@ class Uppy {
       this.setState({ error: error.message })
       this.setState({ error: error.message })
     })
     })
 
 
-    this.on('upload-error', (file, error) => {
-      this.setFileState(file.id, { error: error.message })
+    this.on('upload-error', (file, error, response) => {
+      this.setFileState(file.id, {
+        error: error.message,
+        response
+      })
+
       this.setState({ error: error.message })
       this.setState({ error: error.message })
 
 
       let message = this.i18n('failedToUpload', { file: file.name })
       let message = this.i18n('failedToUpload', { file: file.name })
@@ -734,7 +738,7 @@ class Uppy {
 
 
     this.on('upload-progress', this._calculateProgress)
     this.on('upload-progress', this._calculateProgress)
 
 
-    this.on('upload-success', (file, uploadResp, uploadURL) => {
+    this.on('upload-success', (file, uploadResp) => {
       const currentProgress = this.getFile(file.id).progress
       const currentProgress = this.getFile(file.id).progress
       this.setFileState(file.id, {
       this.setFileState(file.id, {
         progress: Object.assign({}, currentProgress, {
         progress: Object.assign({}, currentProgress, {
@@ -742,7 +746,8 @@ class Uppy {
           percentage: 100,
           percentage: 100,
           bytesUploaded: currentProgress.bytesTotal
           bytesUploaded: currentProgress.bytesTotal
         }),
         }),
-        uploadURL: uploadURL,
+        response: uploadResp,
+        uploadURL: uploadResp.uploadURL,
         isPaused: false
         isPaused: false
       })
       })
 
 

+ 9 - 9
packages/@uppy/dashboard/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/dashboard",
   "name": "@uppy/dashboard",
   "description": "Universal UI plugin for Uppy.",
   "description": "Universal UI plugin for Uppy.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
@@ -23,12 +22,13 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/informer": "0.29.0",
-    "@uppy/provider-views": "0.29.0",
-    "@uppy/status-bar": "0.29.0",
-    "@uppy/thumbnail-generator": "0.29.0",
-    "@uppy/utils": "0.29.0",
+    "@uppy/informer": "0.29.1",
+    "@uppy/provider-views": "0.29.1",
+    "@uppy/status-bar": "0.29.1",
+    "@uppy/thumbnail-generator": "0.29.1",
+    "@uppy/utils": "0.29.1",
     "classnames": "^2.2.6",
     "classnames": "^2.2.6",
+    "cuid": "^2.1.1",
     "drag-drop": "2.13.3",
     "drag-drop": "2.13.3",
     "lodash.throttle": "^4.1.1",
     "lodash.throttle": "^4.1.1",
     "preact": "^8.2.9",
     "preact": "^8.2.9",
@@ -37,8 +37,8 @@
     "resize-observer-polyfill": "^1.5.0"
     "resize-observer-polyfill": "^1.5.0"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0",
-    "@uppy/google-drive": "0.29.0"
+    "@uppy/core": "0.29.1",
+    "@uppy/google-drive": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 14 - 4
packages/@uppy/dashboard/src/index.js

@@ -7,6 +7,7 @@ const Informer = require('@uppy/informer')
 const ThumbnailGenerator = require('@uppy/thumbnail-generator')
 const ThumbnailGenerator = require('@uppy/thumbnail-generator')
 const findAllDOMElements = require('@uppy/utils/lib/findAllDOMElements')
 const findAllDOMElements = require('@uppy/utils/lib/findAllDOMElements')
 const toArray = require('@uppy/utils/lib/toArray')
 const toArray = require('@uppy/utils/lib/toArray')
+const cuid = require('cuid')
 // const prettyBytes = require('prettier-bytes')
 // const prettyBytes = require('prettier-bytes')
 const ResizeObserver = require('resize-observer-polyfill').default || require('resize-observer-polyfill')
 const ResizeObserver = require('resize-observer-polyfill').default || require('resize-observer-polyfill')
 const { defaultTabIcon } = require('./components/icons')
 const { defaultTabIcon } = require('./components/icons')
@@ -40,7 +41,7 @@ module.exports = class Dashboard extends Plugin {
     this.id = this.opts.id || 'Dashboard'
     this.id = this.opts.id || 'Dashboard'
     this.title = 'Dashboard'
     this.title = 'Dashboard'
     this.type = 'orchestrator'
     this.type = 'orchestrator'
-    this.modalName = 'uppy-Dashboard'
+    this.modalName = `uppy-Dashboard-${cuid()}`
 
 
     const defaultLocale = {
     const defaultLocale = {
       strings: {
       strings: {
@@ -140,7 +141,7 @@ module.exports = class Dashboard extends Plugin {
     }
     }
 
 
     // merge default options with the ones set by user
     // merge default options with the ones set by user
-    this.opts = Object.assign({}, defaultOptions, opts)
+    this.opts = { ...defaultOptions, ...opts }
 
 
     // i18n
     // i18n
     this.translator = new Translator([ defaultLocale, this.uppy.locale, this.opts.locale ])
     this.translator = new Translator([ defaultLocale, this.uppy.locale, this.opts.locale ])
@@ -256,7 +257,10 @@ module.exports = class Dashboard extends Plugin {
     // Ensure history state does not already contain our modal name to avoid double-pushing
     // Ensure history state does not already contain our modal name to avoid double-pushing
     if (!history.state || !history.state[this.modalName]) {
     if (!history.state || !history.state[this.modalName]) {
       // Push to history so that the page is not lost on browser back button press
       // Push to history so that the page is not lost on browser back button press
-      history.pushState({ [this.modalName]: true }, '')
+      history.pushState({
+        ...history.state,
+        [this.modalName]: true
+      }, '')
     }
     }
 
 
     // Listen for back button presses
     // Listen for back button presses
@@ -265,7 +269,7 @@ module.exports = class Dashboard extends Plugin {
 
 
   handlePopState (event) {
   handlePopState (event) {
     // Close the modal if the history state no longer contains our modal name
     // Close the modal if the history state no longer contains our modal name
-    if (!event.state || !event.state[this.modalName]) {
+    if (this.isModalOpen() && (!event.state || !event.state[this.modalName])) {
       this.closeModal({ manualClose: false })
       this.closeModal({ manualClose: false })
     }
     }
 
 
@@ -337,6 +341,12 @@ module.exports = class Dashboard extends Plugin {
       manualClose = true // Whether the modal is being closed by the user (`true`) or by other means (e.g. browser back button)
       manualClose = true // Whether the modal is being closed by the user (`true`) or by other means (e.g. browser back button)
     } = opts
     } = opts
 
 
+    const { isHidden, isClosing } = this.getPluginState()
+    if (isHidden || isClosing) {
+      // short-circuit if animation is ongoing
+      return
+    }
+
     if (this.opts.disablePageScrollWhenModalOpen) {
     if (this.opts.disablePageScrollWhenModalOpen) {
       document.body.classList.remove('uppy-Dashboard-isFixed')
       document.body.classList.remove('uppy-Dashboard-isFixed')
     }
     }

+ 3 - 4
packages/@uppy/drag-drop/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/drag-drop",
   "name": "@uppy/drag-drop",
   "description": "Droppable zone UI for Uppy. Drag and drop files into it to upload.",
   "description": "Droppable zone UI for Uppy. Drag and drop files into it to upload.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
@@ -26,12 +25,12 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/utils": "0.29.0",
+    "@uppy/utils": "0.29.1",
     "drag-drop": "2.13.3",
     "drag-drop": "2.13.3",
     "preact": "^8.2.9"
     "preact": "^8.2.9"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 5 - 6
packages/@uppy/dropbox/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/dropbox",
   "name": "@uppy/dropbox",
   "description": "Import files from Dropbox, into Uppy.",
   "description": "Import files from Dropbox, into Uppy.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",
@@ -21,13 +20,13 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/companion-client": "0.27.2",
-    "@uppy/provider-views": "0.29.0",
-    "@uppy/utils": "0.29.0",
+    "@uppy/companion-client": "0.27.3",
+    "@uppy/provider-views": "0.29.1",
+    "@uppy/utils": "0.29.1",
     "preact": "^8.2.9"
     "preact": "^8.2.9"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 3 - 4
packages/@uppy/file-input/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/file-input",
   "name": "@uppy/file-input",
   "description": "Simple UI of a file input button that works with Uppy right out of the box",
   "description": "Simple UI of a file input button that works with Uppy right out of the box",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
@@ -23,11 +22,11 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/utils": "0.29.0",
+    "@uppy/utils": "0.29.1",
     "preact": "^8.2.9"
     "preact": "^8.2.9"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 3 - 4
packages/@uppy/form/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/form",
   "name": "@uppy/form",
   "description": "Connect Uppy to an existing HTML <form>.",
   "description": "Connect Uppy to an existing HTML <form>.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",
@@ -21,11 +20,11 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/utils": "0.29.0",
+    "@uppy/utils": "0.29.1",
     "get-form-data": "^2.0.0"
     "get-form-data": "^2.0.0"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 3 - 4
packages/@uppy/golden-retriever/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/golden-retriever",
   "name": "@uppy/golden-retriever",
   "description": "The GoldenRetriever Uppy plugin saves selected files in browser cache to seamlessly resume uploding after browser crash or accidentally closed tab",
   "description": "The GoldenRetriever Uppy plugin saves selected files in browser cache to seamlessly resume uploding after browser crash or accidentally closed tab",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",
@@ -24,11 +23,11 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/utils": "0.29.0",
+    "@uppy/utils": "0.29.1",
     "prettier-bytes": "^1.0.4"
     "prettier-bytes": "^1.0.4"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 5 - 6
packages/@uppy/google-drive/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/google-drive",
   "name": "@uppy/google-drive",
   "description": "The Google Drive plugin for Uppy lets users import files from their Google Drive account",
   "description": "The Google Drive plugin for Uppy lets users import files from their Google Drive account",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",
@@ -22,13 +21,13 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/companion-client": "0.27.2",
-    "@uppy/provider-views": "0.29.0",
-    "@uppy/utils": "0.29.0",
+    "@uppy/companion-client": "0.27.3",
+    "@uppy/provider-views": "0.29.1",
+    "@uppy/utils": "0.29.1",
     "preact": "^8.2.9"
     "preact": "^8.2.9"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 3 - 4
packages/@uppy/informer/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/informer",
   "name": "@uppy/informer",
   "description": "A notification and error pop-up bar for Uppy.",
   "description": "A notification and error pop-up bar for Uppy.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
@@ -24,11 +23,11 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/utils": "0.29.0",
+    "@uppy/utils": "0.29.1",
     "preact": "^8.2.9"
     "preact": "^8.2.9"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 5 - 6
packages/@uppy/instagram/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/instagram",
   "name": "@uppy/instagram",
   "description": "Import photos and videos from Instagram, into Uppy.",
   "description": "Import photos and videos from Instagram, into Uppy.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",
@@ -24,13 +23,13 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/companion-client": "0.27.2",
-    "@uppy/provider-views": "0.29.0",
-    "@uppy/utils": "0.29.0",
+    "@uppy/companion-client": "0.27.3",
+    "@uppy/provider-views": "0.29.1",
+    "@uppy/utils": "0.29.1",
     "preact": "^8.2.9"
     "preact": "^8.2.9"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 3 - 4
packages/@uppy/progress-bar/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/progress-bar",
   "name": "@uppy/progress-bar",
   "description": "A progress bar UI for Uppy",
   "description": "A progress bar UI for Uppy",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
@@ -24,11 +23,11 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/utils": "0.29.0",
+    "@uppy/utils": "0.29.1",
     "preact": "^8.2.9"
     "preact": "^8.2.9"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 3 - 4
packages/@uppy/provider-views/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/provider-views",
   "name": "@uppy/provider-views",
   "description": "View library for Uppy remote provider plugins.",
   "description": "View library for Uppy remote provider plugins.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
@@ -20,12 +19,12 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/utils": "0.29.0",
+    "@uppy/utils": "0.29.1",
     "classnames": "^2.2.6",
     "classnames": "^2.2.6",
     "preact": "^8.2.9"
     "preact": "^8.2.9"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 2 - 2
packages/@uppy/provider-views/src/index.js

@@ -81,6 +81,7 @@ module.exports = class ProviderView {
   }
   }
 
 
   _updateFilesAndFolders (res, files, folders) {
   _updateFilesAndFolders (res, files, folders) {
+    this.nextPagePath = res.nextPagePath
     res.items.forEach((item) => {
     res.items.forEach((item) => {
       if (item.isFolder) {
       if (item.isFolder) {
         folders.push(item)
         folders.push(item)
@@ -128,7 +129,6 @@ module.exports = class ProviderView {
         }
         }
 
 
         this.username = this.username ? this.username : res.username
         this.username = this.username ? this.username : res.username
-        this.nextPagePath = res.nextPagePath
         this._updateFilesAndFolders(res, files, folders)
         this._updateFilesAndFolders(res, files, folders)
         this.plugin.setPluginState({ directories: updatedDirectories })
         this.plugin.setPluginState({ directories: updatedDirectories })
       },
       },
@@ -463,7 +463,7 @@ module.exports = class ProviderView {
 
 
   handleScroll (e) {
   handleScroll (e) {
     const scrollPos = e.target.scrollHeight - (e.target.scrollTop + e.target.offsetHeight)
     const scrollPos = e.target.scrollHeight - (e.target.scrollTop + e.target.offsetHeight)
-    const path = this.nextPagePath ? this.nextPagePath : null
+    const path = this.nextPagePath || null
 
 
     if (scrollPos < 50 && path && !this._isHandlingScroll) {
     if (scrollPos < 50 && path && !this._isHandlingScroll) {
       this.provider.list(path)
       this.provider.list(path)

+ 7 - 7
packages/@uppy/react/package.json

@@ -1,7 +1,7 @@
 {
 {
   "name": "@uppy/react",
   "name": "@uppy/react",
   "description": "React component wrappers around Uppy's official UI plugins.",
   "description": "React component wrappers around Uppy's official UI plugins.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "index.js",
   "main": "index.js",
   "module": "index.mjs",
   "module": "index.mjs",
@@ -22,15 +22,15 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/dashboard": "0.29.0",
-    "@uppy/drag-drop": "0.29.0",
-    "@uppy/progress-bar": "0.29.0",
-    "@uppy/status-bar": "0.29.0",
-    "@uppy/utils": "0.29.0",
+    "@uppy/dashboard": "0.29.1",
+    "@uppy/drag-drop": "0.29.1",
+    "@uppy/progress-bar": "0.29.1",
+    "@uppy/status-bar": "0.29.1",
+    "@uppy/utils": "0.29.1",
     "prop-types": "^15.6.1"
     "prop-types": "^15.6.1"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 17 - 2
packages/@uppy/react/src/Dashboard.js

@@ -11,6 +11,21 @@ const h = React.createElement
 
 
 class Dashboard extends React.Component {
 class Dashboard extends React.Component {
   componentDidMount () {
   componentDidMount () {
+    this.installPlugin()
+  }
+
+  componentDidUpdate (prevProps) {
+    if (prevProps.uppy !== this.props.uppy) {
+      this.uninstallPlugin(prevProps)
+      this.installPlugin()
+    }
+  }
+
+  componentWillUnmount () {
+    this.uninstallPlugin()
+  }
+
+  installPlugin () {
     const uppy = this.props.uppy
     const uppy = this.props.uppy
     const options = Object.assign(
     const options = Object.assign(
       { id: 'react:Dashboard' },
       { id: 'react:Dashboard' },
@@ -23,8 +38,8 @@ class Dashboard extends React.Component {
     this.plugin = uppy.getPlugin(options.id)
     this.plugin = uppy.getPlugin(options.id)
   }
   }
 
 
-  componentWillUnmount () {
-    const uppy = this.props.uppy
+  uninstallPlugin (props = this.props) {
+    const uppy = props.uppy
 
 
     uppy.removePlugin(this.plugin)
     uppy.removePlugin(this.plugin)
   }
   }

+ 1 - 1
packages/@uppy/react/src/DashboardModal.d.ts

@@ -1,7 +1,7 @@
 import { DashboardProps } from './Dashboard';
 import { DashboardProps } from './Dashboard';
 
 
 export interface DashboardModalProps extends DashboardProps {
 export interface DashboardModalProps extends DashboardProps {
-  target: string | HTMLElement;
+  target?: string | HTMLElement;
   open?: boolean;
   open?: boolean;
   onRequestClose?: VoidFunction;
   onRequestClose?: VoidFunction;
   closeModalOnClickOutside?: boolean;
   closeModalOnClickOutside?: boolean;

+ 17 - 2
packages/@uppy/react/src/DashboardModal.js

@@ -12,6 +12,21 @@ const h = React.createElement
 
 
 class DashboardModal extends React.Component {
 class DashboardModal extends React.Component {
   componentDidMount () {
   componentDidMount () {
+    this.installPlugin()
+  }
+
+  componentDidUpdate (prevProps) {
+    if (prevProps.uppy !== this.props.uppy) {
+      this.uninstallPlugin(prevProps)
+      this.installPlugin()
+    }
+  }
+
+  componentWillUnmount () {
+    this.uninstallPlugin()
+  }
+
+  installPlugin () {
     const uppy = this.props.uppy
     const uppy = this.props.uppy
     const options = Object.assign(
     const options = Object.assign(
       { id: 'react:DashboardModal' },
       { id: 'react:DashboardModal' },
@@ -34,8 +49,8 @@ class DashboardModal extends React.Component {
     }
     }
   }
   }
 
 
-  componentWillUnmount () {
-    const uppy = this.props.uppy
+  uninstallPlugin (props = this.props) {
+    const uppy = props.uppy
 
 
     uppy.removePlugin(this.plugin)
     uppy.removePlugin(this.plugin)
   }
   }

+ 17 - 2
packages/@uppy/react/src/DragDrop.js

@@ -11,6 +11,21 @@ const h = React.createElement
 
 
 class DragDrop extends React.Component {
 class DragDrop extends React.Component {
   componentDidMount () {
   componentDidMount () {
+    this.installPlugin()
+  }
+
+  componentDidUpdate (prevProps) {
+    if (prevProps.uppy !== this.props.uppy) {
+      this.uninstallPlugin(prevProps)
+      this.installPlugin()
+    }
+  }
+
+  componentWillUnmount () {
+    this.uninstallPlugin()
+  }
+
+  installPlugin () {
     const uppy = this.props.uppy
     const uppy = this.props.uppy
     const options = Object.assign(
     const options = Object.assign(
       { id: 'react:DragDrop' },
       { id: 'react:DragDrop' },
@@ -24,8 +39,8 @@ class DragDrop extends React.Component {
     this.plugin = uppy.getPlugin(options.id)
     this.plugin = uppy.getPlugin(options.id)
   }
   }
 
 
-  componentWillUnmount () {
-    const uppy = this.props.uppy
+  uninstallPlugin (props = this.props) {
+    const uppy = props.uppy
 
 
     uppy.removePlugin(this.plugin)
     uppy.removePlugin(this.plugin)
   }
   }

+ 17 - 2
packages/@uppy/react/src/ProgressBar.js

@@ -11,6 +11,21 @@ const h = React.createElement
 
 
 class ProgressBar extends React.Component {
 class ProgressBar extends React.Component {
   componentDidMount () {
   componentDidMount () {
+    this.installPlugin()
+  }
+
+  componentDidUpdate (prevProps) {
+    if (prevProps.uppy !== this.props.uppy) {
+      this.uninstallPlugin(prevProps)
+      this.installPlugin()
+    }
+  }
+
+  componentWillUnmount () {
+    this.uninstallPlugin()
+  }
+
+  installPlugin () {
     const uppy = this.props.uppy
     const uppy = this.props.uppy
     const options = Object.assign(
     const options = Object.assign(
       { id: 'react:ProgressBar' },
       { id: 'react:ProgressBar' },
@@ -24,8 +39,8 @@ class ProgressBar extends React.Component {
     this.plugin = uppy.getPlugin(options.id)
     this.plugin = uppy.getPlugin(options.id)
   }
   }
 
 
-  componentWillUnmount () {
-    const uppy = this.props.uppy
+  uninstallPlugin (props = this.props) {
+    const uppy = props.uppy
 
 
     uppy.removePlugin(this.plugin)
     uppy.removePlugin(this.plugin)
   }
   }

+ 17 - 2
packages/@uppy/react/src/StatusBar.js

@@ -12,6 +12,21 @@ const h = React.createElement
 
 
 class StatusBar extends React.Component {
 class StatusBar extends React.Component {
   componentDidMount () {
   componentDidMount () {
+    this.installPlugin()
+  }
+
+  componentDidUpdate (prevProps) {
+    if (prevProps.uppy !== this.props.uppy) {
+      this.uninstallPlugin(prevProps)
+      this.installPlugin()
+    }
+  }
+
+  componentWillUnmount () {
+    this.uninstallPlugin()
+  }
+
+  installPlugin () {
     const uppy = this.props.uppy
     const uppy = this.props.uppy
     const options = Object.assign(
     const options = Object.assign(
       { id: 'react:StatusBar' },
       { id: 'react:StatusBar' },
@@ -25,8 +40,8 @@ class StatusBar extends React.Component {
     this.plugin = uppy.getPlugin(options.id)
     this.plugin = uppy.getPlugin(options.id)
   }
   }
 
 
-  componentWillUnmount () {
-    const uppy = this.props.uppy
+  uninstallPlugin (props = this.props) {
+    const uppy = props.uppy
 
 
     uppy.removePlugin(this.plugin)
     uppy.removePlugin(this.plugin)
   }
   }

+ 17 - 2
packages/@uppy/react/src/Wrapper.js

@@ -12,14 +12,29 @@ class UppyWrapper extends React.Component {
   }
   }
 
 
   componentDidMount () {
   componentDidMount () {
+    this.installPlugin()
+  }
+
+  componentDidUpdate (prevProps) {
+    if (prevProps.uppy !== this.props.uppy) {
+      this.uninstallPlugin(prevProps)
+      this.installPlugin()
+    }
+  }
+
+  componentWillUnmount () {
+    this.uninstallPlugin()
+  }
+
+  installPlugin () {
     const plugin = this.props.uppy
     const plugin = this.props.uppy
       .getPlugin(this.props.plugin)
       .getPlugin(this.props.plugin)
 
 
     plugin.mount(this.container, plugin)
     plugin.mount(this.container, plugin)
   }
   }
 
 
-  componentWillUnmount () {
-    const plugin = this.props.uppy
+  uninstallPlugin (props = this.props) {
+    const plugin = props.uppy
       .getPlugin(this.props.plugin)
       .getPlugin(this.props.plugin)
 
 
     plugin.unmount()
     plugin.unmount()

+ 2 - 3
packages/@uppy/redux-dev-tools/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/redux-dev-tools",
   "name": "@uppy/redux-dev-tools",
   "description": "Redux developer tools plugin for Uppy that simply syncs Uppy’s state with redux-devtools browser or JS extensions, and allows for basic time travel",
   "description": "Redux developer tools plugin for Uppy that simply syncs Uppy’s state with redux-devtools browser or JS extensions, and allows for basic time travel",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",
@@ -22,7 +21,7 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 3 - 4
packages/@uppy/status-bar/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/status-bar",
   "name": "@uppy/status-bar",
   "description": "A progress bar for Uppy, with many bells and whistles.",
   "description": "A progress bar for Uppy, with many bells and whistles.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
@@ -27,14 +26,14 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/utils": "0.29.0",
+    "@uppy/utils": "0.29.1",
     "classnames": "^2.2.6",
     "classnames": "^2.2.6",
     "lodash.throttle": "^4.1.1",
     "lodash.throttle": "^4.1.1",
     "preact": "^8.2.9",
     "preact": "^8.2.9",
     "prettier-bytes": "^1.0.4"
     "prettier-bytes": "^1.0.4"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 14 - 8
packages/@uppy/status-bar/src/StatusBar.js

@@ -165,13 +165,14 @@ const RetryBtn = (props) => {
 }
 }
 
 
 const CancelBtn = (props) => {
 const CancelBtn = (props) => {
-  return <button type="button"
+  return <button
+    type="button"
     class="uppy-u-reset uppy-StatusBar-actionCircleBtn"
     class="uppy-u-reset uppy-StatusBar-actionCircleBtn"
     title={props.i18n('cancel')}
     title={props.i18n('cancel')}
     aria-label={props.i18n('cancel')}
     aria-label={props.i18n('cancel')}
     onclick={props.cancelAll}>
     onclick={props.cancelAll}>
-    <svg aria-hidden="true" class="UppyIcon" width="8" height="8" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-      <path d="M5.21 4.104l1.658 1.658-1.106 1.106-1.658-1.659-1.659 1.659L1.34 5.762l1.658-1.658L1.34 2.445 2.445 1.34l1.659 1.658L5.762 1.34l1.106 1.105-1.659 1.659z" fill-rule="evenodd" />
+    <svg aria-hidden="true" class="UppyIcon" width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+      <path d="M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16zm1.414-8l2.122-2.121-1.415-1.415L8 6.586 5.879 4.464 4.464 5.88 6.586 8l-2.122 2.121 1.415 1.415L8 9.414l2.121 2.122 1.415-1.415L9.414 8z" fill="#949494" fill-rule="evenodd" />
     </svg>
     </svg>
   </button>
   </button>
 }
 }
@@ -180,13 +181,18 @@ const PauseResumeButton = (props) => {
   const { isAllPaused, i18n } = props
   const { isAllPaused, i18n } = props
   const title = isAllPaused ? i18n('resume') : i18n('pause')
   const title = isAllPaused ? i18n('resume') : i18n('pause')
 
 
-  return <button title={title} class="uppy-u-reset uppy-StatusBar-actionCircleBtn" type="button" onclick={() => togglePauseResume(props)}>
+  return <button
+    title={title}
+    aria-label={title}
+    class="uppy-u-reset uppy-StatusBar-actionCircleBtn"
+    type="button"
+    onclick={() => togglePauseResume(props)}>
     {isAllPaused
     {isAllPaused
-      ? <svg aria-hidden="true" class="UppyIcon" width="8" height="8" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-        <path d="M6.736 3.852l-4.472 2.84V1.075z" fill-rule="evenodd" />
+      ? <svg aria-hidden="true" class="UppyIcon" width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+        <path d="M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16zM6 5v6l5-3-5-3z" fill="#949494" fill-rule="evenodd" />
       </svg>
       </svg>
-      : <svg aria-hidden="true" class="UppyIcon" width="8" height="8" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg">
-        <path d="M1 1h2v6H1zM5 1h2v6H5z" fill-rule="evenodd" />
+      : <svg aria-hidden="true" class="UppyIcon" width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+        <path d="M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16zM5 5v6h2V5H5zm4 0v6h2V5H9z" fill="#949494" fill-rule="evenodd" />
       </svg>
       </svg>
     }
     }
   </button>
   </button>

+ 23 - 16
packages/@uppy/status-bar/src/style.scss

@@ -16,7 +16,7 @@
 }
 }
 
 
   .uppy-size--md .uppy-StatusBar {
   .uppy-size--md .uppy-StatusBar {
-    height: 45px;
+    height: 46px;
     font-size: 14px;
     font-size: 14px;
   }
   }
 
 
@@ -197,31 +197,38 @@
 }
 }
 
 
 .uppy-StatusBar-actionCircleBtn {
 .uppy-StatusBar-actionCircleBtn {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  width: 20px;
-  height: 20px;
-  border-radius: 50%;
+  line-height: 1;
   cursor: pointer;
   cursor: pointer;
-  color: rgba($color-black, 0.6);
-  background-color: rgba($color-gray, 0.3);
-  text-align: center;
+  padding: 4px;
+  // display: flex;
+  // align-items: center;
+  // justify-content: center;
+  // width: 20px;
+  // height: 20px;
+  // border-radius: 50%;
+  // color: rgba($color-black, 0.6);
+  // background-color: rgba($color-gray, 0.3);
+  // text-align: center;
 }
 }
 
 
-  .uppy-StatusBar-actionCircleBtn:not(:last-child) {
-    margin-right: 8px;
+  .uppy-StatusBar-actionCircleBtn:focus {
+    outline: 2px solid $color-cornflower-blue;
+    outline-offset: 0;
   }
   }
 
 
+  // .uppy-StatusBar-actionCircleBtn:not(:last-child) {
+  //   margin-right: 2px;
+  // }
+
   // .uppy-size--md .uppy-StatusBar-actionCircleBtn {
   // .uppy-size--md .uppy-StatusBar-actionCircleBtn {
   //   padding: 1px 4px;
   //   padding: 1px 4px;
   // }
   // }
 
 
   .uppy-StatusBar-actionCircleBtn svg {
   .uppy-StatusBar-actionCircleBtn svg {
-    width: 12px;
-    height: 12px;
-    fill: currentColor;
-    // vertical-align: middle;
+    // width: 12px;
+    // height: 12px;
+    // fill: currentColor;
+    vertical-align: bottom;
   }
   }
 
 
 .uppy-StatusBar-actionBtn {
 .uppy-StatusBar-actionBtn {

+ 1 - 2
packages/@uppy/store-default/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/store-default",
   "name": "@uppy/store-default",
   "description": "The default simple object-based store for Uppy.",
   "description": "The default simple object-based store for Uppy.",
-  "version": "0.27.0",
+  "version": "0.27.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",

+ 1 - 2
packages/@uppy/store-redux/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/store-redux",
   "name": "@uppy/store-redux",
   "description": "Make Uppy use your existing Redux store.",
   "description": "Make Uppy use your existing Redux store.",
-  "version": "0.27.0",
+  "version": "0.27.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",

+ 3 - 4
packages/@uppy/thumbnail-generator/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/thumbnail-generator",
   "name": "@uppy/thumbnail-generator",
   "description": "Uppy plugin that generates small previews of images to show on your upload UI.",
   "description": "Uppy plugin that generates small previews of images to show on your upload UI.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",
@@ -23,10 +22,10 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/utils": "0.29.0"
+    "@uppy/utils": "0.29.1"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0",
+    "@uppy/core": "0.29.1",
     "namespace-emitter": "^2.0.1"
     "namespace-emitter": "^2.0.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {

+ 6 - 7
packages/@uppy/transloadit/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/transloadit",
   "name": "@uppy/transloadit",
   "description": "The Transloadit plugin can be used to upload files to Transloadit for all kinds of processing, such as transcoding video, resizing images, zipping/unzipping, and more",
   "description": "The Transloadit plugin can be used to upload files to Transloadit for all kinds of processing, such as transcoding video, resizing images, zipping/unzipping, and more",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",
@@ -28,15 +27,15 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/companion-client": "0.27.2",
-    "@uppy/provider-views": "0.29.0",
-    "@uppy/tus": "0.29.0",
-    "@uppy/utils": "0.29.0",
+    "@uppy/companion-client": "0.27.3",
+    "@uppy/provider-views": "0.29.1",
+    "@uppy/tus": "0.29.1",
+    "@uppy/utils": "0.29.1",
     "component-emitter": "^1.2.1",
     "component-emitter": "^1.2.1",
     "socket.io-client": "^2.1.1"
     "socket.io-client": "^2.1.1"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 5 - 6
packages/@uppy/tus/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/tus",
   "name": "@uppy/tus",
   "description": "Resumable uploads for Uppy using Tus.io",
   "description": "Resumable uploads for Uppy using Tus.io",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",
@@ -23,12 +22,12 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/companion-client": "0.27.2",
-    "@uppy/utils": "0.29.0",
-    "tus-js-client": "^1.5.1"
+    "@uppy/companion-client": "0.27.3",
+    "@uppy/utils": "0.29.1",
+    "tus-js-client": "1.6.0"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 10 - 2
packages/@uppy/tus/src/index.js

@@ -154,7 +154,11 @@ module.exports = class Tus extends Plugin {
       }
       }
 
 
       optsTus.onSuccess = () => {
       optsTus.onSuccess = () => {
-        this.uppy.emit('upload-success', file, upload, upload.url)
+        const uploadResp = {
+          uploadURL: upload.url
+        }
+
+        this.uppy.emit('upload-success', file, uploadResp)
 
 
         if (upload.url) {
         if (upload.url) {
           this.uppy.log('Download ' + upload.file.name + ' from ' + upload.url)
           this.uppy.log('Download ' + upload.file.name + ' from ' + upload.url)
@@ -327,7 +331,11 @@ module.exports = class Tus extends Plugin {
       })
       })
 
 
       socket.on('success', (data) => {
       socket.on('success', (data) => {
-        this.uppy.emit('upload-success', file, data, data.url)
+        const uploadResp = {
+          uploadURL: data.url
+        }
+
+        this.uppy.emit('upload-success', file, uploadResp)
         this.resetUploaderReferences(file.id)
         this.resetUploaderReferences(file.id)
         resolve()
         resolve()
       })
       })

+ 4 - 5
packages/@uppy/url/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/url",
   "name": "@uppy/url",
   "description": "The Url plugin lets users import files from the Internet. Paste any URL and it’ll be added!",
   "description": "The Url plugin lets users import files from the Internet. Paste any URL and it’ll be added!",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
@@ -23,12 +22,12 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/companion-client": "0.27.2",
-    "@uppy/utils": "0.29.0",
+    "@uppy/companion-client": "0.27.3",
+    "@uppy/utils": "0.29.1",
     "preact": "^8.2.9"
     "preact": "^8.2.9"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 1 - 2
packages/@uppy/utils/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/utils",
   "name": "@uppy/utils",
   "description": "Shared utility functions for Uppy Core and plugins maintained by the Uppy team.",
   "description": "Shared utility functions for Uppy Core and plugins maintained by the Uppy team.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",

+ 3 - 4
packages/@uppy/webcam/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/webcam",
   "name": "@uppy/webcam",
   "description": "Uppy plugin that takes photos or records videos using the device's camera.",
   "description": "Uppy plugin that takes photos or records videos using the device's camera.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
@@ -27,11 +26,11 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/utils": "0.29.0",
+    "@uppy/utils": "0.29.1",
     "preact": "^8.2.9"
     "preact": "^8.2.9"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 4 - 5
packages/@uppy/xhr-upload/package.json

@@ -1,10 +1,9 @@
 {
 {
   "name": "@uppy/xhr-upload",
   "name": "@uppy/xhr-upload",
   "description": "Plain and simple classic HTML multipart form uploads with Uppy, as well as uploads using the HTTP PUT method.",
   "description": "Plain and simple classic HTML multipart form uploads with Uppy, as well as uploads using the HTTP PUT method.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "types": "types/index.d.ts",
   "keywords": [
   "keywords": [
     "file uploader",
     "file uploader",
@@ -25,12 +24,12 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/companion-client": "0.27.2",
-    "@uppy/utils": "0.29.0",
+    "@uppy/companion-client": "0.27.3",
+    "@uppy/utils": "0.29.1",
     "cuid": "^2.1.1"
     "cuid": "^2.1.1"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   },
   "peerDependencies": {
   "peerDependencies": {
     "@uppy/core": "^0.29.0"
     "@uppy/core": "^0.29.0"

+ 19 - 12
packages/@uppy/xhr-upload/src/index.js

@@ -232,15 +232,13 @@ module.exports = class XHRUpload extends Plugin {
           const body = opts.getResponseData(xhr.responseText, xhr)
           const body = opts.getResponseData(xhr.responseText, xhr)
           const uploadURL = body[opts.responseUrlFieldName]
           const uploadURL = body[opts.responseUrlFieldName]
 
 
-          const response = {
+          const uploadResp = {
             status: ev.target.status,
             status: ev.target.status,
             body,
             body,
             uploadURL
             uploadURL
           }
           }
 
 
-          this.uppy.setFileState(file.id, { response })
-
-          this.uppy.emit('upload-success', file, body, uploadURL)
+          this.uppy.emit('upload-success', file, uploadResp)
 
 
           if (uploadURL) {
           if (uploadURL) {
             this.uppy.log(`Download ${file.name} from ${file.uploadURL}`)
             this.uppy.log(`Download ${file.name} from ${file.uploadURL}`)
@@ -256,9 +254,7 @@ module.exports = class XHRUpload extends Plugin {
             body
             body
           }
           }
 
 
-          this.uppy.setFileState(file.id, { response })
-
-          this.uppy.emit('upload-error', file, error)
+          this.uppy.emit('upload-error', file, error, response)
           return reject(error)
           return reject(error)
         }
         }
       })
       })
@@ -332,9 +328,16 @@ module.exports = class XHRUpload extends Plugin {
         socket.on('progress', (progressData) => emitSocketProgress(this, progressData, file))
         socket.on('progress', (progressData) => emitSocketProgress(this, progressData, file))
 
 
         socket.on('success', (data) => {
         socket.on('success', (data) => {
-          const resp = opts.getResponseData(data.response.responseText, data.response)
-          const uploadURL = resp[opts.responseUrlFieldName]
-          this.uppy.emit('upload-success', file, resp, uploadURL)
+          const body = opts.getResponseData(data.response.responseText, data.response)
+          const uploadURL = body[opts.responseUrlFieldName]
+
+          const uploadResp = {
+            status: data.response.status,
+            body,
+            uploadURL
+          }
+
+          this.uppy.emit('upload-success', file, uploadResp)
           socket.close()
           socket.close()
           return resolve()
           return resolve()
         })
         })
@@ -399,9 +402,13 @@ module.exports = class XHRUpload extends Plugin {
         timer.done()
         timer.done()
 
 
         if (ev.target.status >= 200 && ev.target.status < 300) {
         if (ev.target.status >= 200 && ev.target.status < 300) {
-          const resp = this.opts.getResponseData(xhr.responseText, xhr)
+          const body = this.opts.getResponseData(xhr.responseText, xhr)
+          const uploadResp = {
+            status: ev.target.status,
+            body
+          }
           files.forEach((file) => {
           files.forEach((file) => {
-            this.uppy.emit('upload-success', file, resp)
+            this.uppy.emit('upload-success', file, uploadResp)
           })
           })
           return resolve()
           return resolve()
         }
         }

+ 26 - 26
packages/uppy/package.json

@@ -1,7 +1,7 @@
 {
 {
   "name": "uppy",
   "name": "uppy",
   "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:",
   "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:",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "license": "MIT",
   "main": "index.js",
   "main": "index.js",
   "module": "index.mjs",
   "module": "index.mjs",
@@ -30,31 +30,31 @@
     "url": "git+https://github.com/transloadit/uppy.git"
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@uppy/aws-s3": "0.29.0",
-    "@uppy/aws-s3-multipart": "0.29.0",
-    "@uppy/companion-client": "0.27.2",
-    "@uppy/core": "0.29.0",
-    "@uppy/dashboard": "0.29.0",
-    "@uppy/drag-drop": "0.29.0",
-    "@uppy/dropbox": "0.29.0",
-    "@uppy/file-input": "0.29.0",
-    "@uppy/form": "0.29.0",
-    "@uppy/golden-retriever": "0.29.0",
-    "@uppy/google-drive": "0.29.0",
-    "@uppy/informer": "0.29.0",
-    "@uppy/instagram": "0.29.0",
-    "@uppy/progress-bar": "0.29.0",
-    "@uppy/provider-views": "0.29.0",
-    "@uppy/redux-dev-tools": "0.29.0",
-    "@uppy/status-bar": "0.29.0",
-    "@uppy/store-default": "0.27.0",
-    "@uppy/store-redux": "0.27.0",
-    "@uppy/thumbnail-generator": "0.29.0",
-    "@uppy/transloadit": "0.29.0",
-    "@uppy/tus": "0.29.0",
-    "@uppy/url": "0.29.0",
-    "@uppy/webcam": "0.29.0",
-    "@uppy/xhr-upload": "0.29.0"
+    "@uppy/aws-s3": "0.29.1",
+    "@uppy/aws-s3-multipart": "0.29.1",
+    "@uppy/companion-client": "0.27.3",
+    "@uppy/core": "0.29.1",
+    "@uppy/dashboard": "0.29.1",
+    "@uppy/drag-drop": "0.29.1",
+    "@uppy/dropbox": "0.29.1",
+    "@uppy/file-input": "0.29.1",
+    "@uppy/form": "0.29.1",
+    "@uppy/golden-retriever": "0.29.1",
+    "@uppy/google-drive": "0.29.1",
+    "@uppy/informer": "0.29.1",
+    "@uppy/instagram": "0.29.1",
+    "@uppy/progress-bar": "0.29.1",
+    "@uppy/provider-views": "0.29.1",
+    "@uppy/redux-dev-tools": "0.29.1",
+    "@uppy/status-bar": "0.29.1",
+    "@uppy/store-default": "0.27.1",
+    "@uppy/store-redux": "0.27.1",
+    "@uppy/thumbnail-generator": "0.29.1",
+    "@uppy/transloadit": "0.29.1",
+    "@uppy/tus": "0.29.1",
+    "@uppy/url": "0.29.1",
+    "@uppy/webcam": "0.29.1",
+    "@uppy/xhr-upload": "0.29.1"
   },
   },
   "devDependencies": {
   "devDependencies": {
     "es6-promise": "4.2.5",
     "es6-promise": "4.2.5",

+ 1 - 1
test/endtoend/url-plugin/test.js

@@ -17,7 +17,7 @@ describe('File upload with URL plugin', () => {
     browser.click('button.uppy-Url-importButton')
     browser.click('button.uppy-Url-importButton')
 
 
     // do the upload
     // do the upload
-    browser.waitForVisible('.uppy-u-reset.uppy-c-btn.uppy-c-btn-primary.uppy-StatusBar-actionBtn--upload')
+    browser.waitForVisible('.uppy-u-reset.uppy-c-btn.uppy-c-btn-primary.uppy-StatusBar-actionBtn--upload', 10000)
     browser.click('.uppy-u-reset.uppy-c-btn.uppy-c-btn-primary.uppy-StatusBar-actionBtn--upload')
     browser.click('.uppy-u-reset.uppy-c-btn.uppy-c-btn-primary.uppy-StatusBar-actionBtn--upload')
     browser.waitForExist('.uppy-StatusBar.is-complete', 20000)
     browser.waitForExist('.uppy-StatusBar.is-complete', 20000)
   })
   })

+ 2 - 1
test/endtoend/wdio.base.conf.js

@@ -22,7 +22,8 @@ exports.config = {
 
 
   // Patterns to exclude.
   // Patterns to exclude.
   exclude: [
   exclude: [
-    // 'path/to/excluded/files'
+    // 'test/endtoend/url-plugin/*',
+    'test/endtoend/transloadit/*'
   ],
   ],
 
 
   // Suites allows you to do `wdio config.js --suite $name` to run a subset of tests.
   // Suites allows you to do `wdio config.js --suite $name` to run a subset of tests.

+ 2 - 2
website/src/_posts/2017-10-0.20.md

@@ -33,7 +33,7 @@ ReactDOM.render(<Uploader />, document.querySelector('#uploader'))
 
 
 ## Redux
 ## Redux
 
 
-[@richardwillars](https://github.com/richardwillars) contributed a plugin that will sync Uppy's internal state with an existing Redux store.
+[@richardwillars](https://github.com/richardwillars) contributed a plugin that will sync Uppys internal state with an existing Redux store.
 To use it, define a Redux action and reducer:
 To use it, define a Redux action and reducer:
 
 
 ```js
 ```js
@@ -69,7 +69,7 @@ uppy.use(ReduxStore, {
 })
 })
 ```
 ```
 
 
-[See the docs](/docs/react/redux-sync)
+[See the docs](/docs/redux/)
 
 
 ## Redux DevTools
 ## Redux DevTools
 
 

+ 1 - 1
website/src/docs/form.md

@@ -9,7 +9,7 @@ permalink: docs/form/
 The `@uppy/form` plugin has several features to integrate with HTML `<form>` elements.
 The `@uppy/form` plugin has several features to integrate with HTML `<form>` elements.
 
 
 - It collects user-specified metadata from form fields, right before Uppy begins uploading/processing files.
 - It collects user-specified metadata from form fields, right before Uppy begins uploading/processing files.
-- It can append upload results back to the form as a hidden field. Currently the appended result is a stringified version of a [`result`](docs/uppy/#uppy-upload) returned from `uppy.upload()` or `complete` event.
+- It can append upload results back to the form as a hidden field. Currently the appended result is a stringified version of a [`result`](/docs/uppy/#uppy-upload) returned from `uppy.upload()` or `complete` event.
 
 
 ```js
 ```js
 const Form = require('@uppy/form')
 const Form = require('@uppy/form')

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

@@ -6,7 +6,7 @@ alias: api/
 order: 0
 order: 0
 ---
 ---
 
 
-Uppy is a sleek and modular file uploader. It fetches files from local disk, Google Drive,Instagram, remote urls, cameras etc, and then uploads them to the final destination. It’s fast, easy to use and lets you worry about more important problems than building a file uploader.
+Uppy is a sleek and modular file uploader. It fetches files from local disk, Google Drive, Instagram, remote urls, cameras etc, and then uploads them to the final destination. It’s fast, easy to use and lets you worry about more important problems than building a file uploader.
 
 
 Uppy consists of a core module and [various plugins](/docs/plugins/) for selecting, manipulating and uploading files.
 Uppy consists of a core module and [various plugins](/docs/plugins/) for selecting, manipulating and uploading files.
 
 
@@ -18,12 +18,12 @@ Here’s the simplest example html page with Uppy (it uses a CDN bundle, while w
   <head>
   <head>
     <meta charset="utf-8">
     <meta charset="utf-8">
     <title>Uppy</title>
     <title>Uppy</title>
-    <link href="https://transloadit.edgly.net/releases/uppy/v0.29.0/dist/uppy.min.css" rel="stylesheet">
+    <link href="https://transloadit.edgly.net/releases/uppy/v0.29.1/dist/uppy.min.css" rel="stylesheet">
   </head>
   </head>
   <body>
   <body>
     <div id="drag-drop-area"></div>
     <div id="drag-drop-area"></div>
 
 
-    <script src="https://transloadit.edgly.net/releases/uppy/v0.29.0/dist/uppy.min.js"></script>
+    <script src="https://transloadit.edgly.net/releases/uppy/v0.29.1/dist/uppy.min.js"></script>
     <script>
     <script>
       var uppy = Uppy.Core()
       var uppy = Uppy.Core()
         .use(Uppy.Dashboard, {
         .use(Uppy.Dashboard, {
@@ -112,12 +112,12 @@ You can also use a pre-built bundle from Transloadit's CDN: Edgly. `Uppy` will a
 1\. Add a script at the bottom of the closing `</body>` tag:
 1\. Add a script at the bottom of the closing `</body>` tag:
 
 
 ``` html
 ``` html
-<script src="https://transloadit.edgly.net/releases/uppy/v0.29.0/dist/uppy.min.js"></script>
+<script src="https://transloadit.edgly.net/releases/uppy/v0.29.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.29.0/dist/uppy.min.css" rel="stylesheet">
+<link href="https://transloadit.edgly.net/releases/uppy/v0.29.1/dist/uppy.min.css" rel="stylesheet">
 ```
 ```
 
 
 3\. Initialize at the bottom of the closing `</body>` tag:
 3\. Initialize at the bottom of the closing `</body>` tag:
@@ -168,5 +168,5 @@ If you're using Uppy via a script tag, you can load the polyfills from [JSDelivr
 ```html
 ```html
 <script src="https://cdn.jsdelivr.net/npm/es6-promise@4.2.5/dist/es6-promise.auto.min.js"></script>
 <script src="https://cdn.jsdelivr.net/npm/es6-promise@4.2.5/dist/es6-promise.auto.min.js"></script>
 <script src="https://cdn.jsdelivr.net/npm/whatwg-fetch@3.0.0/dist/fetch.umd.min.js"></script>
 <script src="https://cdn.jsdelivr.net/npm/whatwg-fetch@3.0.0/dist/fetch.umd.min.js"></script>
-<script src="https://transloadit.edgly.net/releases/uppy/v0.29.0/dist/uppy.min.js"></script>
+<script src="https://transloadit.edgly.net/releases/uppy/v0.29.1/dist/uppy.min.js"></script>
 ```
 ```

+ 26 - 0
website/src/docs/react-dashboard-modal.md

@@ -35,6 +35,32 @@ Import general Core styles from `@uppy/core/dist/style.css` first, then add the
 
 
 Styles for Provider plugins, like Google Drive and Instagram, are also bundled with Dashboard styles. Styles for other plugins, such as `@uppy/url` and `@uppy/webcam`, are not inluded. If you are using those, please see their docs and make sure to include styles for them as well.
 Styles for Provider plugins, like Google Drive and Instagram, are also bundled with Dashboard styles. Styles for other plugins, such as `@uppy/url` and `@uppy/webcam`, are not inluded. If you are using those, please see their docs and make sure to include styles for them as well.
 
 
+## Initializing Uppy
+
+Your Uppy instance must be initialized before passing it to an `uppy={}` prop, and should be cleaned up using `uppy.close()` when you are done with it. A simple approach is to initialize it in your React component's `constructor()` and destroy it in `componentWillUnmount()`.
+
+> ⚠ Uppy instances are stateful, so the same instance must be used across different renders.
+> Do **NOT** initialize Uppy in a `render()` method!
+> Do **NOT** initialize Uppy in a function component!
+
+```js
+class MyComponent extends React.Component {
+  constructor (props) {
+    super(props)
+    this.uppy = Uppy()
+      .use(Transloadit, {})
+  }
+
+  componentWillUnmount () {
+    this.uppy.close()
+  }
+
+  render () {
+    return <DashboardModal uppy={this.uppy} />
+  }
+}
+```
+
 <!-- Make sure the old name of this section still works -->
 <!-- Make sure the old name of this section still works -->
 <a id="Options"></a>
 <a id="Options"></a>
 
 

+ 26 - 0
website/src/docs/react-dashboard.md

@@ -35,6 +35,32 @@ Import general Core styles from `@uppy/core/dist/style.css` first, then add the
 
 
 Styles for Provider plugins, like Google Drive and Instagram, are also bundled with Dashboard styles. Styles for other plugins, such as `@uppy/url` and `@uppy/webcam`, are not inluded. If you are using those, please see their docs and make sure to include styles for them as well.
 Styles for Provider plugins, like Google Drive and Instagram, are also bundled with Dashboard styles. Styles for other plugins, such as `@uppy/url` and `@uppy/webcam`, are not inluded. If you are using those, please see their docs and make sure to include styles for them as well.
 
 
+## Initializing Uppy
+
+Your Uppy instance must be initialized before passing it to an `uppy={}` prop, and should be cleaned up using `uppy.close()` when you are done with it. A simple approach is to initialize it in your React component's `constructor()` and destroy it in `componentWillUnmount()`.
+
+> ⚠ Uppy instances are stateful, so the same instance must be used across different renders.
+> Do **NOT** initialize Uppy in a `render()` method!
+> Do **NOT** initialize Uppy in a function component!
+
+```js
+class MyComponent extends React.Component {
+  constructor (props) {
+    super(props)
+    this.uppy = Uppy()
+      .use(Transloadit, {})
+  }
+
+  componentWillUnmount () {
+    this.uppy.close()
+  }
+
+  render () {
+    return <Dashboard uppy={this.uppy} />
+  }
+}
+```
+
 ## Props
 ## Props
 
 
 The `<Dashboard />` component supports all [`@uppy/dashboard`][] options as props.
 The `<Dashboard />` component supports all [`@uppy/dashboard`][] options as props.

+ 26 - 0
website/src/docs/react-dragdrop.md

@@ -32,6 +32,32 @@ import '@uppy/drag-drop/dist/style.css'
 
 
 Import general Core styles from `@uppy/core/dist/style.css` first, then add the Drag & Drop styles from `@uppy/drag-drop/dist/style.css`. A minified version is also available as `style.min.css` at the same path. The way to do import depends on your build system.
 Import general Core styles from `@uppy/core/dist/style.css` first, then add the Drag & Drop styles from `@uppy/drag-drop/dist/style.css`. A minified version is also available as `style.min.css` at the same path. The way to do import depends on your build system.
 
 
+## Initializing Uppy
+
+Your Uppy instance must be initialized before passing it to an `uppy={}` prop, and should be cleaned up using `uppy.close()` when you are done with it. A simple approach is to initialize it in your React component's `constructor()` and destroy it in `componentWillUnmount()`.
+
+> ⚠ Uppy instances are stateful, so the same instance must be used across different renders.
+> Do **NOT** initialize Uppy in a `render()` method!
+> Do **NOT** initialize Uppy in a function component!
+
+```js
+class MyComponent extends React.Component {
+  constructor (props) {
+    super(props)
+    this.uppy = Uppy()
+      .use(Transloadit, {})
+  }
+
+  componentWillUnmount () {
+    this.uppy.close()
+  }
+
+  render () {
+    return <DragDrop uppy={this.uppy} />
+  }
+}
+```
+
 ## Props
 ## Props
 
 
 The `<DragDrop />` component supports all [DragDrop][] options as props.
 The `<DragDrop />` component supports all [DragDrop][] options as props.

+ 26 - 0
website/src/docs/react-progressbar.md

@@ -32,6 +32,32 @@ import '@uppy/progress-bar/dist/style.css'
 
 
 Import general Core styles from `@uppy/core/dist/style.css` first, then add the Progress Bar styles from `@uppy/progress-bar/dist/style.css`. A minified version is also available as `style.min.css` at the same path. The way to do import depends on your build system.
 Import general Core styles from `@uppy/core/dist/style.css` first, then add the Progress Bar styles from `@uppy/progress-bar/dist/style.css`. A minified version is also available as `style.min.css` at the same path. The way to do import depends on your build system.
 
 
+## Initializing Uppy
+
+Your Uppy instance must be initialized before passing it to an `uppy={}` prop, and should be cleaned up using `uppy.close()` when you are done with it. A simple approach is to initialize it in your React component's `constructor()` and destroy it in `componentWillUnmount()`.
+
+> ⚠ Uppy instances are stateful, so the same instance must be used across different renders.
+> Do **NOT** initialize Uppy in a `render()` method!
+> Do **NOT** initialize Uppy in a function component!
+
+```js
+class MyComponent extends React.Component {
+  constructor (props) {
+    super(props)
+    this.uppy = Uppy()
+      .use(Transloadit, {})
+  }
+
+  componentWillUnmount () {
+    this.uppy.close()
+  }
+
+  render () {
+    return <ProgressBar uppy={this.uppy} />
+  }
+}
+```
+
 ## Props
 ## Props
 
 
 The `<ProgressBar />` component supports all [`@uppy/progress-bar`][] options as props.
 The `<ProgressBar />` component supports all [`@uppy/progress-bar`][] options as props.

+ 26 - 0
website/src/docs/react-statusbar.md

@@ -32,6 +32,32 @@ import '@uppy/status-bar/dist/style.css'
 
 
 Import general Core styles from `@uppy/core/dist/style.css` first, then add the Status Bar styles from `@uppy/status-bar/dist/style.css`. A minified version is also available as `style.min.css` at the same path. The way to do import depends on your build system.
 Import general Core styles from `@uppy/core/dist/style.css` first, then add the Status Bar styles from `@uppy/status-bar/dist/style.css`. A minified version is also available as `style.min.css` at the same path. The way to do import depends on your build system.
 
 
+## Initializing Uppy
+
+Your Uppy instance must be initialized before passing it to an `uppy={}` prop, and should be cleaned up using `uppy.close()` when you are done with it. A simple approach is to initialize it in your React component's `constructor()` and destroy it in `componentWillUnmount()`.
+
+> ⚠ Uppy instances are stateful, so the same instance must be used across different renders.
+> Do **NOT** initialize Uppy in a `render()` method!
+> Do **NOT** initialize Uppy in a function component!
+
+```js
+class MyComponent extends React.Component {
+  constructor (props) {
+    super(props)
+    this.uppy = Uppy()
+      .use(Transloadit, {})
+  }
+
+  componentWillUnmount () {
+    this.uppy.close()
+  }
+
+  render () {
+    return <StatusBar uppy={this.uppy} />
+  }
+}
+```
+
 ## Props
 ## Props
 
 
 The `<StatusBar />` component supports all [`@uppy/status-bar`][] options as props.
 The `<StatusBar />` component supports all [`@uppy/status-bar`][] options as props.

+ 5 - 1
website/src/docs/react.md

@@ -57,7 +57,11 @@ const AvatarPicker = ({ currentAvatar }) => {
         uppy={uppy}
         uppy={uppy}
         locale={{
         locale={{
           strings: {
           strings: {
-            chooseFile: 'Pick a new avatar'
+            // Text to show on the droppable area.
+            // `%{browse}` is replaced with a link that opens the system file selection dialog.
+            dropHereOr: 'Drop here or %{browse}',
+            // Used as the label for the link that opens the system file selection dialog.
+            browse: 'browse'
           }
           }
         }}
         }}
       />
       />

+ 25 - 6
website/src/docs/uppy.md

@@ -549,13 +549,23 @@ uppy.on('upload-progress', (file, progress) => {
 
 
 Fired each time a single upload is completed.
 Fired each time a single upload is completed.
 
 
+`response` object (depending on the uploader plugin used, it might contain less info, the example is for `@uppy/xhr-upload`):
+
+```js
+{
+  status, // HTTP status code (0, 200, 300)
+  body, // response body
+  uploadURL // the file url, if it was returned
+}
+```
+
 ``` javascript
 ``` javascript
-uppy.on('upload-success', (file, resp, uploadURL) => {
-  console.log(file.name, uploadURL)
+uppy.on('upload-success', (file, response) => {
+  console.log(file.name, response.uploadURL)
   var img = new Image()
   var img = new Image()
   img.width = 300
   img.width = 300
-  img.alt = fileId
-  img.src = uploadURL
+  img.alt = file.id
+  img.src = response.uploadURL
   document.body.appendChild(img)
   document.body.appendChild(img)
 })
 })
 ```
 ```
@@ -579,10 +589,19 @@ Fired when Uppy fails to upload/encode the entire upload. That error is then set
 
 
 ### `upload-error`
 ### `upload-error`
 
 
-Fired when an error occurs with a specific file:
+Fired each time a single upload has errored.
+
+`response` object (depending on the uploader plugin used, it might contain less info, the example is for `@uppy/xhr-upload`):
+
+```js
+{
+  status, // HTTP status code (0, 200, 300)
+  body // response body
+}
+```
 
 
 ``` javascript
 ``` javascript
-uppy.on('upload-error', (file, error) => {
+uppy.on('upload-error', (file, error, response) => {
   console.log('error with file:', file.id)
   console.log('error with file:', file.id)
   console.log('error message:', error)
   console.log('error message:', error)
 })
 })

+ 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.29.0/dist/uppy.min.css -->
+https://transloadit.edgly.net/releases/uppy/v0.29.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.29.0/dist/uppy.min.js -->
+https://transloadit.edgly.net/releases/uppy/v0.29.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, autoProceed: true });
   var uppy = Uppy.Core({ debug: true, autoProceed: true });

+ 2 - 3
website/src/privacy.md

@@ -95,7 +95,7 @@ Their privacy policy is located here: https://policies.google.com/privacy.
 
 
 ## How to disable cookies
 ## How to disable cookies
 
 
-You may be able to configure your browser or our website to restrict cookies or block all cookies, if you wish. If you disable cookies, you may find that this affects your ability to use certain parts of our website. For more information about cookies and instructions on how to adjust your browser settings to accept, delete or reject cookies, see the [www.allaboutcookies.org](www.allaboutcookies.org) website.
+You may be able to configure your browser or our website to restrict cookies or block all cookies, if you wish. If you disable cookies, you may find that this affects your ability to use certain parts of our website. For more information about cookies and instructions on how to adjust your browser settings to accept, delete or reject cookies, see the [allaboutcookies.org](http://allaboutcookies.org) website.
 
 
 ## Data Processing Addendum (DPA)
 ## Data Processing Addendum (DPA)
 
 
@@ -103,5 +103,4 @@ If you require a countersigned copy of our DPA, please  <a href="mailto:hello@tr
 
 
 ## Last Updated
 ## Last Updated
 
 
-This privacy policy was last updated on Dec 12, 2018.
-
+This privacy policy was last updated on Jan 23, 2018.

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

@@ -82,8 +82,8 @@
   <p><a href="/privacy-policy/">Privacy Policy</a></p>
   <p><a href="/privacy-policy/">Privacy Policy</a></p>
 </footer>
 </footer>
 
 
-<link href="https://transloadit.edgly.net/releases/uppy/v0.29.0/dist/uppy.min.css" rel="stylesheet">
-<script src="https://transloadit.edgly.net/releases/uppy/v0.29.0/dist/uppy.min.js"></script>
+<link href="https://transloadit.edgly.net/releases/uppy/v0.29.1/dist/uppy.min.css" rel="stylesheet">
+<script src="https://transloadit.edgly.net/releases/uppy/v0.29.1/dist/uppy.min.js"></script>
 
 
 <script>
 <script>
   var TUS_ENDPOINT = 'https://master.tus.io/files/'
   var TUS_ENDPOINT = 'https://master.tus.io/files/'

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

@@ -20,6 +20,8 @@
     <meta name="twitter:description" content="<%- excerpt %>">
     <meta name="twitter:description" content="<%- excerpt %>">
     <meta property="og:image" content="<%- image %>">
     <meta property="og:image" content="<%- image %>">
     <meta name="twitter:image" content="<%- image %>">
     <meta name="twitter:image" content="<%- image %>">
+    
+    <meta name="google-site-verification" content="JxARoHXoCI8bD07pLV_u3z6xpuWNcSIZIcHEytyCkUc" />
 
 
     <link rel="icon" href="<%- config.logo_icon %>" type="image/x-icon">
     <link rel="icon" href="<%- config.logo_icon %>" type="image/x-icon">
     <link rel="alternate" type="application/rss+xml" title="<%= config.title %>" href="/atom.xml">
     <link rel="alternate" type="application/rss+xml" title="<%= config.title %>" href="/atom.xml">

Неке датотеке нису приказане због велике количине промена