Browse Source

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

Kevin van Zonneveld 6 năm trước cách đây
mục cha
commit
f877010d5b
75 tập tin đã thay đổi với 1149 bổ sung412 xóa
  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,
     "serveStatic": ["examples/bundle"],
     "ghostMode": {
-        "clicks": true,
-        "scroll": true,
+        "clicks": false,
+        "scroll": false,
         "forms": {
-            "submit": true,
-            "inputs": true,
-            "toggles": true
+            "submit": false,
+            "inputs": false,
+            "toggles": false
         }
     },
     "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
 - [ ] audio: audio recording similar to Webcam #143
 - [ ] 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
 - [ ] 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.
-- [ ] 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
 - [ ] 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
@@ -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)
 - [ ] 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
+- [ ] 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: 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
 
@@ -104,23 +114,62 @@ What we need to do to release Uppy 1.0
 - [x] uppy-server: security audit
 - [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
 
 ## 0.30.0
 
-- [ ] add polyfils to uppy bundle 
 - [ ] 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)
 - [ ] 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: 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)
 - [ ] 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
 

+ 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/).
 
-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.
 
@@ -73,10 +73,10 @@ Alternatively, you can also use a pre-built bundle from Transloadit's CDN: Edgly
 
 ```html
 <!-- 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>` -->
-<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 -->
 <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
 <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://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
@@ -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) |
 
-[<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-->
 
 ## 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 writeFile = promisify(fs.writeFile)
+const stat = promisify(fs.stat)
 
 const SOURCE = 'packages/{*,@uppy/*}/src/**/*.js'
 // Files not to build (such as tests)
 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 () {
+  const metaMtimes = await Promise.all(META_FILES.map((filename) =>
+    lastModified(path.join(__dirname, '..', filename))
+  ))
+  const metaMtime = Math.max(...metaMtimes)
+
   const files = await glob(SOURCE)
   for (const file of files) {
     if (IGNORE.test(file)) continue
-
     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, {})
     await mkdirp(path.dirname(libFile))
     await Promise.all([
@@ -29,6 +57,7 @@ async function buildLib () {
   }
 }
 
+console.log('Using Babel version:', require('babel-core/package.json').version)
 buildLib().catch((err) => {
   console.error(err.stack)
   process.exit(1)

+ 1 - 1
bin/release

@@ -59,7 +59,7 @@ git add README.md
 cp README.md packages/uppy/README.md
 
 npm run clean
-npm run build
+FRESH=1 npm run build
 
 git commit -m "Release"
 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)
 #  - Installs AWS CLI if needed
 #  - Assumed a fully built uppy is in root dir (unless a specific tag was specified, then it's fetched from npm)
-#  - Runs npm pack, and stores files to e.g. https://transloadit.edgly.net/releases/uppy/v0.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
 #
 # Run as:

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

@@ -4,11 +4,11 @@
     <title></title>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1">
-    <link href="https://transloadit.edgly.net/releases/uppy/v0.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>
   <body>
     <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>
       const uppy = Uppy.Core({debug: true, autoProceed: false})
         .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
     }
 
-    this.handleModalClick = this.handleModalClick.bind(this)
-  }
-
-  componentWillMount () {
     this.uppy = new Uppy({ id: 'uppy1', autoProceed: true, debug: true })
       .use(Tus, { endpoint: 'https://master.tus.io/files/' })
       .use(GoogleDrive, { serverUrl: 'https://companion.uppy.io' })
 
     this.uppy2 = new Uppy({ id: 'uppy2', autoProceed: false, debug: true })
       .use(Tus, { endpoint: 'https://master.tus.io/files/' })
+
+    this.handleModalClick = this.handleModalClick.bind(this)
   }
 
   componentWillUnmount () {

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

@@ -4,11 +4,11 @@
     <title></title>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1">
-    <link href="https://transloadit.edgly.net/releases/uppy/v0.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>
   <body>
     <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>
       const uppy = Uppy.Core({debug: true, autoProceed: false})
         .use(Uppy.Dashboard, { trigger: '#uppyModalOpener' })

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 472 - 93
package-lock.json


+ 4 - 3
package.json

@@ -85,7 +85,7 @@
     "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",
     "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",
     "clean": "rm -rf packages/*/lib packages/@uppy/*/lib && rm -rf packages/uppy/dist",
     "lint:fix": "npm run lint -- --fix",
@@ -101,7 +101,7 @@
     "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: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:type": "tsc -p .",
     "test": "npm run lint && npm run test:unit && npm run test:type && npm run test:companion",
@@ -141,5 +141,6 @@
     "testMatch": [
       "**/packages/**/*.test.js"
     ]
-  }
+  },
+  "dependencies": {}
 }

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

@@ -1,10 +1,9 @@
 {
   "name": "@uppy/aws-s3-multipart",
   "description": "Upload to Amazon S3 with Uppy and S3's Multipart upload strategy",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "keywords": [
     "file uploader",
@@ -24,12 +23,12 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "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"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   "peerDependencies": {
     "@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)
         },
         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) {
             this.uppy.log('Download ' + upload.file.name + ' from ' + result.location)
@@ -328,7 +332,11 @@ module.exports = class AwsS3Multipart extends Plugin {
       })
 
       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()
       })
     })

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

@@ -1,10 +1,9 @@
 {
   "name": "@uppy/aws-s3",
   "description": "Upload to Amazon S3 with Uppy",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "keywords": [
     "file uploader",
@@ -23,13 +22,13 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "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"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   "peerDependencies": {
     "@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.')
     }
 
-    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}`)
       .then(assertServerError)
   }

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

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

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

@@ -1,6 +1,6 @@
 {
   "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:",
   "main": "lib/uppy.js",
   "types": "types/index.d.ts",
@@ -30,34 +30,34 @@
   },
   "dependencies": {
     "@purest/providers": "1.0.0",
-    "@uppy/fs-tail-stream": "^1.2.0",
+    "@uppy/fs-tail-stream": "1.2.0",
     "atob": "2.1.0",
-    "aws-sdk": "^2.254.1",
+    "aws-sdk": "2.388.0",
     "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",
-    "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",
     "grant-express": "4.1.2",
     "helmet": "3.8.2",
     "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",
-    "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",
-    "redis": "^2.7.1",
+    "redis": "2.8.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"
   },
   "devDependencies": {

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

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

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

@@ -1,10 +1,9 @@
 {
   "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:",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "keywords": [
@@ -21,8 +20,8 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "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",
     "lodash.throttle": "^4.1.1",
     "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.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 })
 
       let message = this.i18n('failedToUpload', { file: file.name })
@@ -734,7 +738,7 @@ class Uppy {
 
     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
       this.setFileState(file.id, {
         progress: Object.assign({}, currentProgress, {
@@ -742,7 +746,8 @@ class Uppy {
           percentage: 100,
           bytesUploaded: currentProgress.bytesTotal
         }),
-        uploadURL: uploadURL,
+        response: uploadResp,
+        uploadURL: uploadResp.uploadURL,
         isPaused: false
       })
 

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

@@ -1,10 +1,9 @@
 {
   "name": "@uppy/dashboard",
   "description": "Universal UI plugin for Uppy.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "keywords": [
@@ -23,12 +22,13 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "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",
+    "cuid": "^2.1.1",
     "drag-drop": "2.13.3",
     "lodash.throttle": "^4.1.1",
     "preact": "^8.2.9",
@@ -37,8 +37,8 @@
     "resize-observer-polyfill": "^1.5.0"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0",
-    "@uppy/google-drive": "0.29.0"
+    "@uppy/core": "0.29.1",
+    "@uppy/google-drive": "0.29.1"
   },
   "peerDependencies": {
     "@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 findAllDOMElements = require('@uppy/utils/lib/findAllDOMElements')
 const toArray = require('@uppy/utils/lib/toArray')
+const cuid = require('cuid')
 // const prettyBytes = require('prettier-bytes')
 const ResizeObserver = require('resize-observer-polyfill').default || require('resize-observer-polyfill')
 const { defaultTabIcon } = require('./components/icons')
@@ -40,7 +41,7 @@ module.exports = class Dashboard extends Plugin {
     this.id = this.opts.id || 'Dashboard'
     this.title = 'Dashboard'
     this.type = 'orchestrator'
-    this.modalName = 'uppy-Dashboard'
+    this.modalName = `uppy-Dashboard-${cuid()}`
 
     const defaultLocale = {
       strings: {
@@ -140,7 +141,7 @@ module.exports = class Dashboard extends Plugin {
     }
 
     // merge default options with the ones set by user
-    this.opts = Object.assign({}, defaultOptions, opts)
+    this.opts = { ...defaultOptions, ...opts }
 
     // i18n
     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
     if (!history.state || !history.state[this.modalName]) {
       // 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
@@ -265,7 +269,7 @@ module.exports = class Dashboard extends Plugin {
 
   handlePopState (event) {
     // 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 })
     }
 
@@ -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)
     } = opts
 
+    const { isHidden, isClosing } = this.getPluginState()
+    if (isHidden || isClosing) {
+      // short-circuit if animation is ongoing
+      return
+    }
+
     if (this.opts.disablePageScrollWhenModalOpen) {
       document.body.classList.remove('uppy-Dashboard-isFixed')
     }

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

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

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

@@ -1,10 +1,9 @@
 {
   "name": "@uppy/dropbox",
   "description": "Import files from Dropbox, into Uppy.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "keywords": [
     "file uploader",
@@ -21,13 +20,13 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "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"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   "peerDependencies": {
     "@uppy/core": "^0.29.0"

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

@@ -1,10 +1,9 @@
 {
   "name": "@uppy/file-input",
   "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",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "keywords": [
@@ -23,11 +22,11 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "dependencies": {
-    "@uppy/utils": "0.29.0",
+    "@uppy/utils": "0.29.1",
     "preact": "^8.2.9"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   "peerDependencies": {
     "@uppy/core": "^0.29.0"

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

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

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

@@ -1,10 +1,9 @@
 {
   "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",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "keywords": [
     "file uploader",
@@ -24,11 +23,11 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "dependencies": {
-    "@uppy/utils": "0.29.0",
+    "@uppy/utils": "0.29.1",
     "prettier-bytes": "^1.0.4"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   "peerDependencies": {
     "@uppy/core": "^0.29.0"

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

@@ -1,10 +1,9 @@
 {
   "name": "@uppy/google-drive",
   "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",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "keywords": [
     "file uploader",
@@ -22,13 +21,13 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "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"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   "peerDependencies": {
     "@uppy/core": "^0.29.0"

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

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

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

@@ -1,10 +1,9 @@
 {
   "name": "@uppy/instagram",
   "description": "Import photos and videos from Instagram, into Uppy.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "keywords": [
     "file uploader",
@@ -24,13 +23,13 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "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"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   "peerDependencies": {
     "@uppy/core": "^0.29.0"

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

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

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

@@ -1,10 +1,9 @@
 {
   "name": "@uppy/provider-views",
   "description": "View library for Uppy remote provider plugins.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "keywords": [
@@ -20,12 +19,12 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "dependencies": {
-    "@uppy/utils": "0.29.0",
+    "@uppy/utils": "0.29.1",
     "classnames": "^2.2.6",
     "preact": "^8.2.9"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   "peerDependencies": {
     "@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) {
+    this.nextPagePath = res.nextPagePath
     res.items.forEach((item) => {
       if (item.isFolder) {
         folders.push(item)
@@ -128,7 +129,6 @@ module.exports = class ProviderView {
         }
 
         this.username = this.username ? this.username : res.username
-        this.nextPagePath = res.nextPagePath
         this._updateFilesAndFolders(res, files, folders)
         this.plugin.setPluginState({ directories: updatedDirectories })
       },
@@ -463,7 +463,7 @@ module.exports = class ProviderView {
 
   handleScroll (e) {
     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) {
       this.provider.list(path)

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

@@ -1,7 +1,7 @@
 {
   "name": "@uppy/react",
   "description": "React component wrappers around Uppy's official UI plugins.",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "main": "index.js",
   "module": "index.mjs",
@@ -22,15 +22,15 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "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"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   "peerDependencies": {
     "@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 {
   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 options = Object.assign(
       { id: 'react:Dashboard' },
@@ -23,8 +38,8 @@ class Dashboard extends React.Component {
     this.plugin = uppy.getPlugin(options.id)
   }
 
-  componentWillUnmount () {
-    const uppy = this.props.uppy
+  uninstallPlugin (props = this.props) {
+    const uppy = props.uppy
 
     uppy.removePlugin(this.plugin)
   }

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

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

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

@@ -12,6 +12,21 @@ const h = React.createElement
 
 class DashboardModal extends React.Component {
   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 options = Object.assign(
       { 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)
   }

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

@@ -11,6 +11,21 @@ const h = React.createElement
 
 class DragDrop extends React.Component {
   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 options = Object.assign(
       { id: 'react:DragDrop' },
@@ -24,8 +39,8 @@ class DragDrop extends React.Component {
     this.plugin = uppy.getPlugin(options.id)
   }
 
-  componentWillUnmount () {
-    const uppy = this.props.uppy
+  uninstallPlugin (props = this.props) {
+    const uppy = props.uppy
 
     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 {
   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 options = Object.assign(
       { id: 'react:ProgressBar' },
@@ -24,8 +39,8 @@ class ProgressBar extends React.Component {
     this.plugin = uppy.getPlugin(options.id)
   }
 
-  componentWillUnmount () {
-    const uppy = this.props.uppy
+  uninstallPlugin (props = this.props) {
+    const uppy = props.uppy
 
     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 {
   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 options = Object.assign(
       { id: 'react:StatusBar' },
@@ -25,8 +40,8 @@ class StatusBar extends React.Component {
     this.plugin = uppy.getPlugin(options.id)
   }
 
-  componentWillUnmount () {
-    const uppy = this.props.uppy
+  uninstallPlugin (props = this.props) {
+    const uppy = props.uppy
 
     uppy.removePlugin(this.plugin)
   }

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

@@ -12,14 +12,29 @@ class UppyWrapper extends React.Component {
   }
 
   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
       .getPlugin(this.props.plugin)
 
     plugin.mount(this.container, plugin)
   }
 
-  componentWillUnmount () {
-    const plugin = this.props.uppy
+  uninstallPlugin (props = this.props) {
+    const plugin = props.uppy
       .getPlugin(this.props.plugin)
 
     plugin.unmount()

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

@@ -1,10 +1,9 @@
 {
   "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",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "keywords": [
     "file uploader",
@@ -22,7 +21,7 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   "peerDependencies": {
     "@uppy/core": "^0.29.0"

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

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

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

@@ -165,13 +165,14 @@ const RetryBtn = (props) => {
 }
 
 const CancelBtn = (props) => {
-  return <button type="button"
+  return <button
+    type="button"
     class="uppy-u-reset uppy-StatusBar-actionCircleBtn"
     title={props.i18n('cancel')}
     aria-label={props.i18n('cancel')}
     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>
   </button>
 }
@@ -180,13 +181,18 @@ const PauseResumeButton = (props) => {
   const { isAllPaused, i18n } = props
   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
-      ? <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 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>
     }
   </button>

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

@@ -16,7 +16,7 @@
 }
 
   .uppy-size--md .uppy-StatusBar {
-    height: 45px;
+    height: 46px;
     font-size: 14px;
   }
 
@@ -197,31 +197,38 @@
 }
 
 .uppy-StatusBar-actionCircleBtn {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  width: 20px;
-  height: 20px;
-  border-radius: 50%;
+  line-height: 1;
   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 {
   //   padding: 1px 4px;
   // }
 
   .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 {

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

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

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

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

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

@@ -1,10 +1,9 @@
 {
   "name": "@uppy/thumbnail-generator",
   "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",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "keywords": [
     "file uploader",
@@ -23,10 +22,10 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "dependencies": {
-    "@uppy/utils": "0.29.0"
+    "@uppy/utils": "0.29.1"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0",
+    "@uppy/core": "0.29.1",
     "namespace-emitter": "^2.0.1"
   },
   "peerDependencies": {

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

@@ -1,10 +1,9 @@
 {
   "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",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "keywords": [
     "file uploader",
@@ -28,15 +27,15 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "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",
     "socket.io-client": "^2.1.1"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   "peerDependencies": {
     "@uppy/core": "^0.29.0"

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

@@ -1,10 +1,9 @@
 {
   "name": "@uppy/tus",
   "description": "Resumable uploads for Uppy using Tus.io",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "keywords": [
     "file uploader",
@@ -23,12 +22,12 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "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": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   "peerDependencies": {
     "@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 = () => {
-        this.uppy.emit('upload-success', file, upload, upload.url)
+        const uploadResp = {
+          uploadURL: upload.url
+        }
+
+        this.uppy.emit('upload-success', file, uploadResp)
 
         if (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) => {
-        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)
         resolve()
       })

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

@@ -1,10 +1,9 @@
 {
   "name": "@uppy/url",
   "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",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
   "keywords": [
@@ -23,12 +22,12 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "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"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   "peerDependencies": {
     "@uppy/core": "^0.29.0"

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

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

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

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

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

@@ -1,10 +1,9 @@
 {
   "name": "@uppy/xhr-upload",
   "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",
   "main": "lib/index.js",
-  "jsnext:main": "src/index.js",
   "types": "types/index.d.ts",
   "keywords": [
     "file uploader",
@@ -25,12 +24,12 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "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"
   },
   "devDependencies": {
-    "@uppy/core": "0.29.0"
+    "@uppy/core": "0.29.1"
   },
   "peerDependencies": {
     "@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 uploadURL = body[opts.responseUrlFieldName]
 
-          const response = {
+          const uploadResp = {
             status: ev.target.status,
             body,
             uploadURL
           }
 
-          this.uppy.setFileState(file.id, { response })
-
-          this.uppy.emit('upload-success', file, body, uploadURL)
+          this.uppy.emit('upload-success', file, uploadResp)
 
           if (uploadURL) {
             this.uppy.log(`Download ${file.name} from ${file.uploadURL}`)
@@ -256,9 +254,7 @@ module.exports = class XHRUpload extends Plugin {
             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)
         }
       })
@@ -332,9 +328,16 @@ module.exports = class XHRUpload extends Plugin {
         socket.on('progress', (progressData) => emitSocketProgress(this, progressData, file))
 
         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()
           return resolve()
         })
@@ -399,9 +402,13 @@ module.exports = class XHRUpload extends Plugin {
         timer.done()
 
         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) => {
-            this.uppy.emit('upload-success', file, resp)
+            this.uppy.emit('upload-success', file, uploadResp)
           })
           return resolve()
         }

+ 26 - 26
packages/uppy/package.json

@@ -1,7 +1,7 @@
 {
   "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:",
-  "version": "0.29.0",
+  "version": "0.29.1",
   "license": "MIT",
   "main": "index.js",
   "module": "index.mjs",
@@ -30,31 +30,31 @@
     "url": "git+https://github.com/transloadit/uppy.git"
   },
   "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": {
     "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')
 
     // 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.waitForExist('.uppy-StatusBar.is-complete', 20000)
   })

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

@@ -22,7 +22,8 @@ exports.config = {
 
   // Patterns to 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.

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

@@ -33,7 +33,7 @@ ReactDOM.render(<Uploader />, document.querySelector('#uploader'))
 
 ## 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:
 
 ```js
@@ -69,7 +69,7 @@ uppy.use(ReduxStore, {
 })
 ```
 
-[See the docs](/docs/react/redux-sync)
+[See the docs](/docs/redux/)
 
 ## 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.
 
 - 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
 const Form = require('@uppy/form')

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

@@ -6,7 +6,7 @@ alias: api/
 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.
 
@@ -18,12 +18,12 @@ Here’s the simplest example html page with Uppy (it uses a CDN bundle, while w
   <head>
     <meta charset="utf-8">
     <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>
   <body>
     <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>
       var uppy = Uppy.Core()
         .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:
 
 ``` 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>`:
 ``` 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:
@@ -168,5 +168,5 @@ If you're using Uppy via a script tag, you can load the polyfills from [JSDelivr
 ```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/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.
 
+## 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 -->
 <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.
 
+## 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
 
 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.
 
+## 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
 
 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.
 
+## 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
 
 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.
 
+## 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
 
 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}
         locale={{
           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.
 
+`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
-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()
   img.width = 300
-  img.alt = fileId
-  img.src = uploadURL
+  img.alt = file.id
+  img.src = response.uploadURL
   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`
 
-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
-uppy.on('upload-error', (file, error) => {
+uppy.on('upload-error', (file, error, response) => {
   console.log('error with file:', file.id)
   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:
-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">
 
 <div class="UppyDragDrop"></div>
 
 <!-- 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>
   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
 
-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)
 
@@ -103,5 +103,4 @@ If you require a countersigned copy of our DPA, please  <a href="mailto:hello@tr
 
 ## 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>
 </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>
   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 property="og: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="alternate" type="application/rss+xml" title="<%= config.title %>" href="/atom.xml">

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác