Skip to content

Conversation

@craig-rueda
Copy link

No description provided.

Murderlon and others added 26 commits March 13, 2025 09:45
Before

Add a file
Call uppy.upload() but make it fail (set throttling to offline in your browser)
Call uppy.upload() again but no throttling
Events are not fired, endless uploading state.
You must call retryAll() instead but it's better DX if you can simply call upload() again and let us figure it out.

After

upload() behaves like retryAll() when errors occurred in a backwards compatible way.

What if an upload fails and you also add a new file?

Backwards compatible behaviour similar to how it currently works when using the dashboard. In the dashboard you can only click the retry button and once that upload is done you can click upload again to upload the new files.

When a previous upload partially failed, you add a new file, and call upload() this PR makes sure two uploads are done in a row. That does mean you get the 'complete' event twice.
| Package     | Version | Package     | Version |
| ----------- | ------- | ----------- | ------- |
| @uppy/core  |   4.4.3 | uppy        |  4.13.4 |
| @uppy/react |   4.2.2 |             |         |

- @uppy/core: make upload() idempotent (Merlijn Vos / transloadit#5677)
- @uppy/react: pass getServerSnapshot to useSyncExternalStoreWithSelector (Merlijn Vos / transloadit#5685)
- meta: Fix BasePlugin export for CDN bundle (Merlijn Vos / transloadit#5684)
- meta: build(deps): bump docker/build-push-action from 6.14.0 to 6.15.0 (dependabot[bot] / transloadit#5673)
- meta: build(deps): bump docker/setup-qemu-action from 3.4.0 to 3.6.0 (dependabot[bot] / transloadit#5675)
- meta: build(deps): bump docker/metadata-action from 5.6.1 to 5.7.0 (dependabot[bot] / transloadit#5674)
we spent a lot of time on implementing it but google decided to remove it,
so we have no choice
closes transloadit#5469
* always release locales

seems to have been broken for a while

* make script more verbose

* try to fix script

* fix again

* fix building of locales
…t#5689)

Bumps [docker/login-action](https://github.com/docker/login-action) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](docker/login-action@9780b0c...74a5d14)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.14 to 5.4.15.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.15/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.15/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* implement dropbox business teams

this adds support for team spaces folders
note: Do **not** enable any Team scopes (permissions) at https://www.dropbox.com/developers/apps
that will break the app (making it a team admin app instead)

* fix tests

* fix lint
Revert "Support Angular 19 (transloadit#5709)"

This reverts commit 86fb71f.
* dry retryAll() and upload()

improvement of transloadit#5677

* fix bug

* make it private

* fix botched merge
| Package                    | Version | Package                    | Version |
| -------------------------- | ------- | -------------------------- | ------- |
| @uppy/audio                |   2.1.2 | @uppy/locales              |   4.5.2 |
| @uppy/box                  |   3.2.2 | @uppy/onedrive             |   4.2.3 |
| @uppy/companion            |   5.6.0 | @uppy/react                |   4.2.3 |
| @uppy/core                 |   4.4.4 | @uppy/remote-sources       |   2.3.2 |
| @uppy/dashboard            |   4.3.3 | @uppy/screen-capture       |   4.2.2 |
| @uppy/drag-drop            |   4.1.2 | @uppy/status-bar           |   4.1.3 |
| @uppy/dropbox              |   4.2.2 | @uppy/transloadit          |   4.2.2 |
| @uppy/facebook             |   4.2.2 | @uppy/unsplash             |   4.3.3 |
| @uppy/file-input           |   4.1.2 | @uppy/url                  |   4.2.3 |
| @uppy/google-drive         |   4.3.2 | @uppy/utils                |   6.1.3 |
| @uppy/google-drive-picker  |   0.3.4 | @uppy/webcam               |   4.1.2 |
| @uppy/google-photos-picker |   0.3.4 | @uppy/webdav               |   0.3.2 |
| @uppy/image-editor         |   3.3.2 | @uppy/zoom                 |   3.2.2 |
| @uppy/instagram            |   4.2.2 | uppy                       |  4.14.0 |

- @uppy/core: dry retryAll() and upload() (Mikael Finstad / transloadit#5691)
- @uppy/angular: Revert "Support Angular 19" (Mikael Finstad / transloadit#5710)
- @uppy/angular: Support Angular 19 (Arnaud Flaesch / transloadit#5709)
- @uppy/companion: implement dropbox business teams (Mikael Finstad / transloadit#5708)
- @uppy/utils: add msg mimetype (Merlijn Vos / transloadit#5699)
- @uppy/core: fix locale type for plugins (Merlijn Vos / transloadit#5700)
- examples: build(deps-dev): bump vite from 5.4.14 to 5.4.15 (dependabot[bot] / transloadit#5703)
- @uppy/locales: Update nb_NO.ts (Tore Sinding Bekkedal / transloadit#5678)
- meta: build(deps): bump docker/login-action from 3.3.0 to 3.4.0 (dependabot[bot] / transloadit#5689)
- examples: @uppy-example/aws-nodejs: fix fileType not present in S3 objects (Prakash / transloadit#5680)
- @uppy/core: fix events when retrying with upload() (Prakash / transloadit#5696)
- meta: Fix locales building (Mikael Finstad / transloadit#5693)
- @uppy/google-photos: remove google photos 😢 (Mikael Finstad / transloadit#5690)
- @uppy/locales: Update cs_CZ.ts (David Petrásek / transloadit#5658)
in an attempt to fix the problem where e2e tests are not always being run on main
have already enabled for the repo "Require approval for all external contributors: All users that are not a member or owner of this repository and not a member of the transloadit organization will require approval to run workflows."
* Fix type check on CI

it doesn't actually check types in all files
because it used tsconfig.build.json
hence some type errors go unnoticed

* like this

* and this

* add missing references

* fix build command
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.16 to 5.4.17.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.17/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.17/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 5.4.17
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Mikael Finstad <[email protected]>
Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.7 to 5.1.2.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](ai/nanoid@3.3.7...5.1.2)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Mikael Finstad <[email protected]>
@github-actions
Copy link

github-actions bot commented Apr 10, 2025

Diff output files
diff --git a/packages/@uppy/audio/lib/Audio.js b/packages/@uppy/audio/lib/Audio.js
index 0bde7d2..b2cdeeb 100644
--- a/packages/@uppy/audio/lib/Audio.js
+++ b/packages/@uppy/audio/lib/Audio.js
@@ -24,7 +24,7 @@ import PermissionsScreen from "./PermissionsScreen.js";
 import RecordingScreen from "./RecordingScreen.js";
 import supportsMediaRecorder from "./supportsMediaRecorder.js";
 const packageJson = {
-  "version": "2.1.1",
+  "version": "2.1.2",
 };
 var _recordingLengthTimer = _classPrivateFieldLooseKey("recordingLengthTimer");
 var _stream = _classPrivateFieldLooseKey("stream");
diff --git a/packages/@uppy/box/lib/Box.js b/packages/@uppy/box/lib/Box.js
index ea2be44..bf9e95c 100644
--- a/packages/@uppy/box/lib/Box.js
+++ b/packages/@uppy/box/lib/Box.js
@@ -4,7 +4,7 @@ import { ProviderViews } from "@uppy/provider-views";
 import { h } from "preact";
 import locale from "./locale.js";
 const packageJson = {
-  "version": "3.2.1",
+  "version": "3.2.2",
 };
 export default class Box extends UIPlugin {
   constructor(uppy, opts) {
diff --git a/packages/@uppy/companion/lib/config/grant.d.ts b/packages/@uppy/companion/lib/config/grant.d.ts
index 183e854..33574f1 100644
--- a/packages/@uppy/companion/lib/config/grant.d.ts
+++ b/packages/@uppy/companion/lib/config/grant.d.ts
@@ -1,8 +1,5 @@
 declare function _exports(): {
     googledrive: {
-        state: boolean;
-        callback: string;
-        scope: string[];
         custom_params: {
             access_type: string;
             prompt: string;
@@ -11,21 +8,10 @@ declare function _exports(): {
         access_url: string;
         oauth: number;
         scope_delimiter: string;
-        transport: string;
-    };
-    googlephotos: {
+        state: boolean;
         callback: string;
         scope: string[];
-        custom_params: {
-            access_type: string;
-            prompt: string;
-        };
-        authorize_url: string;
-        access_url: string;
-        oauth: number;
-        scope_delimiter: string;
         transport: string;
-        state: boolean;
     };
     dropbox: {
         authorize_url: string;
diff --git a/packages/@uppy/companion/lib/config/grant.js b/packages/@uppy/companion/lib/config/grant.js
index f475ecd..5f32f2d 100644
--- a/packages/@uppy/companion/lib/config/grant.js
+++ b/packages/@uppy/companion/lib/config/grant.js
@@ -1,18 +1,5 @@
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
-const google = {
-  // access_type: offline is needed in order to get refresh tokens.
-  // prompt: 'consent' is needed because sometimes a user will get stuck in an authenticated state where we will
-  // receive no refresh tokens from them. This seems to be happen when running on different subdomains.
-  // therefore to be safe that we always get refresh tokens, we set this.
-  // https://stackoverflow.com/questions/10827920/not-receiving-google-oauth-refresh-token/65108513#65108513
-  custom_params: { access_type: "offline", prompt: "consent" },
-  // copied from https://github.com/simov/grant/blob/master/config/oauth.json
-  "authorize_url": "https://accounts.google.com/o/oauth2/v2/auth",
-  "access_url": "https://oauth2.googleapis.com/token",
-  "oauth": 2,
-  "scope_delimiter": " ",
-};
 const defaults = {
   transport: "session",
   state: true, // Enable CSRF check
@@ -24,20 +11,21 @@ module.exports = () => {
     // and because it would be a too big rewrite to allow reuse of the same provider.
     googledrive: {
       ...defaults,
-      ...google,
+      // access_type: offline is needed in order to get refresh tokens.
+      // prompt: 'consent' is needed because sometimes a user will get stuck in an authenticated state where we will
+      // receive no refresh tokens from them. This seems to be happen when running on different subdomains.
+      // therefore to be safe that we always get refresh tokens, we set this.
+      // https://stackoverflow.com/questions/10827920/not-receiving-google-oauth-refresh-token/65108513#65108513
+      custom_params: { access_type: "offline", prompt: "consent" },
+      // copied from https://github.com/simov/grant/blob/master/config/oauth.json
+      authorize_url: "https://accounts.google.com/o/oauth2/v2/auth",
+      access_url: "https://oauth2.googleapis.com/token",
+      oauth: 2,
+      scope_delimiter: " ",
       state: true,
       callback: "/drive/callback",
       scope: ["https://www.googleapis.com/auth/drive.readonly"],
     },
-    googlephotos: {
-      ...defaults,
-      ...google,
-      callback: "/googlephotos/callback",
-      scope: [
-        "https://www.googleapis.com/auth/photoslibrary.readonly",
-        "https://www.googleapis.com/auth/userinfo.email",
-      ], // if name is needed, then add https://www.googleapis.com/auth/userinfo.profile too
-    },
     dropbox: {
       ...defaults,
       authorize_url: "https://www.dropbox.com/oauth2/authorize",
diff --git a/packages/@uppy/companion/lib/server/provider/dropbox/index.js b/packages/@uppy/companion/lib/server/provider/dropbox/index.js
index 09b9de0..919063f 100644
--- a/packages/@uppy/companion/lib/server/provider/dropbox/index.js
+++ b/packages/@uppy/companion/lib/server/provider/dropbox/index.js
@@ -6,7 +6,8 @@ const adaptData = require("./adapter");
 const { withProviderErrorHandling } = require("../providerErrors");
 const { prepareStream } = require("../../helpers/utils");
 const { MAX_AGE_REFRESH_TOKEN } = require("../../helpers/jwt");
-const got = require("../../got");
+const logger = require("../../logger");
+const gotPromise = require("../../got");
 // From https://www.dropbox.com/developers/reference/json-encoding:
 //
 // This function is simple and has OK performance compared to more
@@ -17,19 +18,42 @@ function httpHeaderSafeJson(v) {
     return `\\u${(`000${c.charCodeAt(0).toString(16)}`).slice(-4)}`;
   });
 }
-const getClient = async ({ token }) =>
-  (await got).extend({
-    prefixUrl: "https://api.dropboxapi.com/2",
-    headers: {
-      authorization: `Bearer ${token}`,
-    },
-  });
+async function getUserInfo({ client }) {
+  return client.post("users/get_current_account", { responseType: "json" }).json();
+}
+async function getClient({ token, namespaced }) {
+  const got = await gotPromise;
+  const makeClient = (namespace) =>
+    got.extend({
+      prefixUrl: "https://api.dropboxapi.com/2",
+      headers: {
+        authorization: `Bearer ${token}`,
+        ...(namespace ? { "Dropbox-API-Path-Root": JSON.stringify({ ".tag": "root", "root": namespace }) } : {}),
+      },
+    });
+  let client = makeClient();
+  const userInfo = await getUserInfo({ client });
+  // console.log('userInfo', userInfo)
+  // https://www.dropboxforum.com/discussions/101000014/how-to-list-the-contents-of-a-team-folder/258310
+  // https://developers.dropbox.com/dbx-team-files-guide#namespaces
+  // https://www.dropbox.com/developers/reference/path-root-header-modes
+  if (
+    namespaced && userInfo.root_info != null
+    && userInfo.root_info.root_namespace_id !== userInfo.root_info.home_namespace_id
+  ) {
+    logger.debug("using root_namespace_id", userInfo.root_info.root_namespace_id);
+    client = makeClient(userInfo.root_info.root_namespace_id);
+  }
+  return {
+    client,
+    userInfo,
+  };
+}
 const getOauthClient = async () =>
-  (await got).extend({
+  (await gotPromise).extend({
     prefixUrl: "https://api.dropboxapi.com/oauth2",
   });
-async function list({ directory, query, token }) {
-  const client = await getClient({ token });
+async function list({ client, directory, query }) {
   if (query.cursor) {
     return client.post("files/list_folder/continue", { json: { cursor: query.cursor }, responseType: "json" }).json();
   }
@@ -44,9 +68,6 @@ async function list({ directory, query, token }) {
     responseType: "json",
   }).json();
 }
-async function userInfo({ token }) {
-  return (await getClient({ token })).post("users/get_current_account", { responseType: "json" }).json();
-}
 /**
  * Adapter for API https://www.dropbox.com/developers/documentation/http/documentation
  */
@@ -66,18 +87,15 @@ class DropBox extends Provider {
    */
   async list(options) {
     return this.#withErrorHandling("provider.dropbox.list.error", async () => {
-      const responses = await Promise.all([
-        list(options),
-        userInfo(options),
-      ]);
-      // @ts-ignore
-      const [stats, { email }] = responses;
+      const { client, userInfo } = await getClient({ token: options.token, namespaced: true });
+      const stats = await list({ ...options, client });
+      const { email } = userInfo;
       return adaptData(stats, email, options.companion.buildURL);
     });
   }
   async download({ id, token }) {
     return this.#withErrorHandling("provider.dropbox.download.error", async () => {
-      const stream = (await getClient({ token })).stream.post("files/download", {
+      const stream = (await getClient({ token, namespaced: true })).client.stream.post("files/download", {
         prefixUrl: "https://content.dropboxapi.com/2",
         headers: {
           "Dropbox-API-Arg": httpHeaderSafeJson({ path: String(id) }),
@@ -92,7 +110,7 @@ class DropBox extends Provider {
   }
   async thumbnail({ id, token }) {
     return this.#withErrorHandling("provider.dropbox.thumbnail.error", async () => {
-      const stream = (await getClient({ token })).stream.post("files/get_thumbnail_v2", {
+      const stream = (await getClient({ token, namespaced: true })).client.stream.post("files/get_thumbnail_v2", {
         prefixUrl: "https://content.dropboxapi.com/2",
         headers: {
           "Dropbox-API-Arg": httpHeaderSafeJson({
@@ -110,7 +128,7 @@ class DropBox extends Provider {
   }
   async size({ id, token }) {
     return this.#withErrorHandling("provider.dropbox.size.error", async () => {
-      const { size } = await (await getClient({ token })).post("files/get_metadata", {
+      const { size } = await (await getClient({ token, namespaced: true })).client.post("files/get_metadata", {
         json: { path: id },
         responseType: "json",
       }).json();
@@ -119,7 +137,7 @@ class DropBox extends Provider {
   }
   async logout({ token }) {
     return this.#withErrorHandling("provider.dropbox.logout.error", async () => {
-      await (await getClient({ token })).post("auth/token/revoke", { responseType: "json" });
+      await (await getClient({ token, namespaced: false })).client.post("auth/token/revoke", { responseType: "json" });
       return { revoked: true };
     });
   }
diff --git a/packages/@uppy/companion/lib/server/provider/index.js b/packages/@uppy/companion/lib/server/provider/index.js
index d7060a2..1418a9a 100644
--- a/packages/@uppy/companion/lib/server/provider/index.js
+++ b/packages/@uppy/companion/lib/server/provider/index.js
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
 const dropbox = require("./dropbox");
 const box = require("./box");
 const { Drive } = require("./google/drive");
-const googlephotos = require("./google/googlephotos");
 const instagram = require("./instagram/graph");
 const facebook = require("./facebook");
 const onedrive = require("./onedrive");
@@ -66,7 +65,7 @@ module.exports.getProviderMiddleware = (providers, grantConfig) => {
  * @returns {Record<string, typeof Provider>}
  */
 module.exports.getDefaultProviders = () => {
-  const providers = { dropbox, box, drive: Drive, googlephotos, facebook, onedrive, zoom, instagram, unsplash, webdav };
+  const providers = { dropbox, box, drive: Drive, facebook, onedrive, zoom, instagram, unsplash, webdav };
   return providers;
 };
 /**
diff --git a/packages/@uppy/companion/lib/standalone/helper.js b/packages/@uppy/companion/lib/standalone/helper.js
index 1181d8e..cdc80a0 100644
--- a/packages/@uppy/companion/lib/standalone/helper.js
+++ b/packages/@uppy/companion/lib/standalone/helper.js
@@ -81,11 +81,6 @@ const getConfigFromEnv = () => {
         secret: getSecret("COMPANION_GOOGLE_SECRET"),
         credentialsURL: process.env.COMPANION_GOOGLE_KEYS_ENDPOINT,
       },
-      googlephotos: {
-        key: process.env.COMPANION_GOOGLE_KEY,
-        secret: getSecret("COMPANION_GOOGLE_SECRET"),
-        credentialsURL: process.env.COMPANION_GOOGLE_KEYS_ENDPOINT,
-      },
       dropbox: {
         key: process.env.COMPANION_DROPBOX_KEY,
         secret: getSecret("COMPANION_DROPBOX_SECRET"),
diff --git a/packages/@uppy/core/lib/Uppy.js b/packages/@uppy/core/lib/Uppy.js
index 1ba8ade..e4bf6e8 100644
--- a/packages/@uppy/core/lib/Uppy.js
+++ b/packages/@uppy/core/lib/Uppy.js
@@ -19,7 +19,7 @@ import { debugLogger, justErrorsLogger } from "./loggers.js";
 import { defaultOptions as defaultRestrictionOptions, Restricter, RestrictionError } from "./Restricter.js";
 import supportsUploadProgress from "./supportsUploadProgress.js";
 const packageJson = {
-  "version": "4.4.2",
+  "version": "4.4.4",
 };
 import locale from "./locale.js";
 const defaultUploadState = {
@@ -42,6 +42,8 @@ var _assertNewUploadAllowed = _classPrivateFieldLooseKey("assertNewUploadAllowed
 var _transformFile = _classPrivateFieldLooseKey("transformFile");
 var _startIfAutoProceed = _classPrivateFieldLooseKey("startIfAutoProceed");
 var _checkAndUpdateFileState = _classPrivateFieldLooseKey("checkAndUpdateFileState");
+var _getFilesToRetry = _classPrivateFieldLooseKey("getFilesToRetry");
+var _doRetryAll = _classPrivateFieldLooseKey("doRetryAll");
 var _handleUploadProgress = _classPrivateFieldLooseKey("handleUploadProgress");
 var _updateTotalProgress = _classPrivateFieldLooseKey("updateTotalProgress");
 var _updateTotalProgressThrottled = _classPrivateFieldLooseKey("updateTotalProgressThrottled");
@@ -76,6 +78,12 @@ export class Uppy {
     Object.defineProperty(this, _updateTotalProgress, {
       value: _updateTotalProgress2,
     });
+    Object.defineProperty(this, _doRetryAll, {
+      value: _doRetryAll2,
+    });
+    Object.defineProperty(this, _getFilesToRetry, {
+      value: _getFilesToRetry2,
+    });
     Object.defineProperty(this, _checkAndUpdateFileState, {
       value: _checkAndUpdateFileState2,
     });
@@ -729,36 +737,10 @@ export class Uppy {
     });
     this.emit("resume-all");
   }
-  retryAll() {
-    const updatedFiles = {
-      ...this.getState().files,
-    };
-    const filesToRetry = Object.keys(updatedFiles).filter(file => {
-      return updatedFiles[file].error;
-    });
-    filesToRetry.forEach(file => {
-      const updatedFile = {
-        ...updatedFiles[file],
-        isPaused: false,
-        error: null,
-      };
-      updatedFiles[file] = updatedFile;
-    });
-    this.setState({
-      files: updatedFiles,
-      error: null,
-    });
-    this.emit("retry-all", Object.values(updatedFiles));
-    if (filesToRetry.length === 0) {
-      return Promise.resolve({
-        successful: [],
-        failed: [],
-      });
-    }
-    const uploadID = _classPrivateFieldLooseBase(this, _createUpload)[_createUpload](filesToRetry, {
-      forceAllowNewUpload: true,
-    });
-    return _classPrivateFieldLooseBase(this, _runUpload)[_runUpload](uploadID);
+  async retryAll() {
+    const result = await _classPrivateFieldLooseBase(this, _doRetryAll)[_doRetryAll]();
+    this.emit("complete", result);
+    return result;
   }
   cancelAll() {
     this.emit("cancel-all");
@@ -983,7 +965,7 @@ export class Uppy {
       },
     });
   }
-  upload() {
+  async upload() {
     var _classPrivateFieldLoo;
     if (
       !((_classPrivateFieldLoo = _classPrivateFieldLooseBase(this, _plugins)[_plugins]["uploader"]) != null
@@ -994,6 +976,19 @@ export class Uppy {
     let {
       files,
     } = this.getState();
+    const filesToRetry = _classPrivateFieldLooseBase(this, _getFilesToRetry)[_getFilesToRetry]();
+    if (filesToRetry.length > 0) {
+      const retryResult = await _classPrivateFieldLooseBase(this, _doRetryAll)[_doRetryAll]();
+      const hasNewFiles = this.getFiles().filter(file => file.progress.uploadStarted == null).length > 0;
+      if (!hasNewFiles) {
+        this.emit("complete", retryResult);
+        return retryResult;
+      }
+
+      ({
+        files,
+      } = this.getState());
+    }
     const onBeforeUploadResult = this.opts.onBeforeUpload(files);
     if (onBeforeUploadResult === false) {
       return Promise.reject(new Error("Not starting the upload because onBeforeUpload returned false"));
@@ -1015,7 +1010,7 @@ export class Uppy {
       }
     }).catch(err => {
       throw err;
-    }).then(() => {
+    }).then(async () => {
       const {
         currentUploads,
       } = this.getState();
@@ -1028,7 +1023,9 @@ export class Uppy {
         }
       });
       const uploadID = _classPrivateFieldLooseBase(this, _createUpload)[_createUpload](waitingFileIDs);
-      return _classPrivateFieldLooseBase(this, _runUpload)[_runUpload](uploadID);
+      const result = await _classPrivateFieldLooseBase(this, _runUpload)[_runUpload](uploadID);
+      this.emit("complete", result);
+      return result;
     }).catch(err => {
       this.emit("error", err);
       this.log(err, "error");
@@ -1232,6 +1229,42 @@ function _checkAndUpdateFileState2(filesToAdd) {
     errors,
   };
 }
+function _getFilesToRetry2() {
+  const {
+    files,
+  } = this.getState();
+  return Object.keys(files).filter(file => {
+    return files[file].error;
+  });
+}
+async function _doRetryAll2() {
+  const filesToRetry = _classPrivateFieldLooseBase(this, _getFilesToRetry)[_getFilesToRetry]();
+  const updatedFiles = {
+    ...this.getState().files,
+  };
+  filesToRetry.forEach(fileID => {
+    updatedFiles[fileID] = {
+      ...updatedFiles[fileID],
+      isPaused: false,
+      error: null,
+    };
+  });
+  this.setState({
+    files: updatedFiles,
+    error: null,
+  });
+  this.emit("retry-all", this.getFilesByIds(filesToRetry));
+  if (filesToRetry.length === 0) {
+    return {
+      successful: [],
+      failed: [],
+    };
+  }
+  const uploadID = _classPrivateFieldLooseBase(this, _createUpload)[_createUpload](filesToRetry, {
+    forceAllowNewUpload: true,
+  });
+  return _classPrivateFieldLooseBase(this, _runUpload)[_runUpload](uploadID);
+}
 function _updateTotalProgress2() {
   var _totalProgressPercent, _totalProgressPercent2;
   const totalProgress = _classPrivateFieldLooseBase(this, _calculateTotalProgress)[_calculateTotalProgress]();
@@ -1561,7 +1594,6 @@ async function _runUpload2(uploadID) {
   let result;
   if (currentUpload) {
     result = currentUpload.result;
-    this.emit("complete", result);
     _classPrivateFieldLooseBase(this, _removeUpload)[_removeUpload](uploadID);
   }
   if (result == null) {
diff --git a/packages/@uppy/dashboard/lib/Dashboard.js b/packages/@uppy/dashboard/lib/Dashboard.js
index 37dfe5c..f753ac8 100644
--- a/packages/@uppy/dashboard/lib/Dashboard.js
+++ b/packages/@uppy/dashboard/lib/Dashboard.js
@@ -20,7 +20,7 @@ import DashboardUI from "./components/Dashboard.js";
 import createSuperFocus from "./utils/createSuperFocus.js";
 import * as trapFocus from "./utils/trapFocus.js";
 const packageJson = {
-  "version": "4.3.2",
+  "version": "4.3.3",
 };
 import locale from "./locale.js";
 const memoize = memoizeOne.default || memoizeOne;
diff --git a/packages/@uppy/drag-drop/lib/DragDrop.js b/packages/@uppy/drag-drop/lib/DragDrop.js
index 42e3931..022c378 100644
--- a/packages/@uppy/drag-drop/lib/DragDrop.js
+++ b/packages/@uppy/drag-drop/lib/DragDrop.js
@@ -4,7 +4,7 @@ import isDragDropSupported from "@uppy/utils/lib/isDragDropSupported";
 import toArray from "@uppy/utils/lib/toArray";
 import { h } from "preact";
 const packageJson = {
-  "version": "4.1.1",
+  "version": "4.1.2",
 };
 import locale from "./locale.js";
 const defaultOptions = {
diff --git a/packages/@uppy/dropbox/lib/Dropbox.js b/packages/@uppy/dropbox/lib/Dropbox.js
index 7ead5a7..1b20fe3 100644
--- a/packages/@uppy/dropbox/lib/Dropbox.js
+++ b/packages/@uppy/dropbox/lib/Dropbox.js
@@ -4,7 +4,7 @@ import { ProviderViews } from "@uppy/provider-views";
 import { h } from "preact";
 import locale from "./locale.js";
 const packageJson = {
-  "version": "4.2.1",
+  "version": "4.2.2",
 };
 export default class Dropbox extends UIPlugin {
   constructor(uppy, opts) {
diff --git a/packages/@uppy/facebook/lib/Facebook.js b/packages/@uppy/facebook/lib/Facebook.js
index 160b65d..eb4209f 100644
--- a/packages/@uppy/facebook/lib/Facebook.js
+++ b/packages/@uppy/facebook/lib/Facebook.js
@@ -4,7 +4,7 @@ import { ProviderViews } from "@uppy/provider-views";
 import { h } from "preact";
 import locale from "./locale.js";
 const packageJson = {
-  "version": "4.2.1",
+  "version": "4.2.2",
 };
 export default class Facebook extends UIPlugin {
   constructor(uppy, opts) {
diff --git a/packages/@uppy/file-input/lib/FileInput.js b/packages/@uppy/file-input/lib/FileInput.js
index 5015298..710a048 100644
--- a/packages/@uppy/file-input/lib/FileInput.js
+++ b/packages/@uppy/file-input/lib/FileInput.js
@@ -2,7 +2,7 @@ import { UIPlugin } from "@uppy/core";
 import toArray from "@uppy/utils/lib/toArray";
 import { h } from "preact";
 const packageJson = {
-  "version": "4.1.1",
+  "version": "4.1.2",
 };
 import locale from "./locale.js";
 const defaultOptions = {
diff --git a/packages/@uppy/google-drive-picker/lib/GoogleDrivePicker.js b/packages/@uppy/google-drive-picker/lib/GoogleDrivePicker.js
index 8d3054a..4b7aca7 100644
--- a/packages/@uppy/google-drive-picker/lib/GoogleDrivePicker.js
+++ b/packages/@uppy/google-drive-picker/lib/GoogleDrivePicker.js
@@ -5,7 +5,7 @@ import { GooglePickerView } from "@uppy/provider-views";
 import { GoogleDriveIcon } from "@uppy/provider-views/lib/GooglePicker/icons.js";
 import { h } from "preact";
 const packageJson = {
-  "version": "0.3.3",
+  "version": "0.3.4",
 };
 import locale from "./locale.js";
 export default class GoogleDrivePicker extends UIPlugin {
diff --git a/packages/@uppy/google-drive/lib/GoogleDrive.js b/packages/@uppy/google-drive/lib/GoogleDrive.js
index 42d5d9c..bcc6410 100644
--- a/packages/@uppy/google-drive/lib/GoogleDrive.js
+++ b/packages/@uppy/google-drive/lib/GoogleDrive.js
@@ -4,7 +4,7 @@ import { h } from "preact";
 import DriveProviderViews from "./DriveProviderViews.js";
 import locale from "./locale.js";
 const packageJson = {
-  "version": "4.3.1",
+  "version": "4.3.2",
 };
 export default class GoogleDrive extends UIPlugin {
   constructor(uppy, opts) {
diff --git a/packages/@uppy/google-photos-picker/lib/GooglePhotosPicker.js b/packages/@uppy/google-photos-picker/lib/GooglePhotosPicker.js
index 373f97a..20b6f76 100644
--- a/packages/@uppy/google-photos-picker/lib/GooglePhotosPicker.js
+++ b/packages/@uppy/google-photos-picker/lib/GooglePhotosPicker.js
@@ -5,7 +5,7 @@ import { GooglePickerView } from "@uppy/provider-views";
 import { GooglePhotosIcon } from "@uppy/provider-views/lib/GooglePicker/icons.js";
 import { h } from "preact";
 const packageJson = {
-  "version": "0.3.3",
+  "version": "0.3.4",
 };
 import locale from "./locale.js";
 export default class GooglePhotosPicker extends UIPlugin {
diff --git a/packages/@uppy/image-editor/lib/ImageEditor.js b/packages/@uppy/image-editor/lib/ImageEditor.js
index cc76b78..e13b020 100644
--- a/packages/@uppy/image-editor/lib/ImageEditor.js
+++ b/packages/@uppy/image-editor/lib/ImageEditor.js
@@ -2,7 +2,7 @@ import { UIPlugin } from "@uppy/core";
 import { h } from "preact";
 import Editor from "./Editor.js";
 const packageJson = {
-  "version": "3.3.1",
+  "version": "3.3.2",
 };
 import locale from "./locale.js";
 const defaultCropperOptions = {
diff --git a/packages/@uppy/instagram/lib/Instagram.js b/packages/@uppy/instagram/lib/Instagram.js
index ca03638..efb1724 100644
--- a/packages/@uppy/instagram/lib/Instagram.js
+++ b/packages/@uppy/instagram/lib/Instagram.js
@@ -4,7 +4,7 @@ import { ProviderViews } from "@uppy/provider-views";
 import { h } from "preact";
 import locale from "./locale.js";
 const packageJson = {
-  "version": "4.2.1",
+  "version": "4.2.2",
 };
 export default class Instagram extends UIPlugin {
   constructor(uppy, opts) {
diff --git a/packages/@uppy/locales/lib/cs_CZ.js b/packages/@uppy/locales/lib/cs_CZ.js
index 4298db3..bfd51a4 100644
--- a/packages/@uppy/locales/lib/cs_CZ.js
+++ b/packages/@uppy/locales/lib/cs_CZ.js
@@ -75,6 +75,7 @@ cs_CZ.strings = {
   loading: "Nahrávání...",
   logOut: "Odhlásit",
   myDevice: "Moje zařízení",
+  noDuplicates: "Nelze znovu přidat stejný soubor '%{fileName}'",
   noFilesFound: "Nenalezeny žádné soubory ani adresáře",
   noInternetConnection: "Nepřipojeno k internetu",
   openFolderNamed: "Otevřít adresář %{name}",
diff --git a/packages/@uppy/locales/lib/en_US.js b/packages/@uppy/locales/lib/en_US.js
index 52e717d..0f84bfd 100644
--- a/packages/@uppy/locales/lib/en_US.js
+++ b/packages/@uppy/locales/lib/en_US.js
@@ -128,7 +128,6 @@ en_US.strings = {
   pluginNameDropbox: "Dropbox",
   pluginNameFacebook: "Facebook",
   pluginNameGoogleDrive: "Google Drive",
-  pluginNameGooglePhotos: "Google Photos",
   pluginNameGoogleDrivePicker: "Google Drive",
   pluginNameGooglePhotosPicker: "Google Photos",
   pluginNameInstagram: "Instagram",
diff --git a/packages/@uppy/locales/lib/ms_MY.js b/packages/@uppy/locales/lib/ms_MY.js
index ea072fa..dd36e0c 100644
--- a/packages/@uppy/locales/lib/ms_MY.js
+++ b/packages/@uppy/locales/lib/ms_MY.js
@@ -122,7 +122,6 @@ ms_MY.strings = {
   pluginNameDropbox: "Dropbox",
   pluginNameFacebook: "Facebook",
   pluginNameGoogleDrive: "Google Drive",
-  pluginNameGooglePhotos: "Google Photos",
   pluginNameInstagram: "Instagram",
   pluginNameOneDrive: "OneDrive",
   pluginNameScreenCapture: "Screencast",
diff --git a/packages/@uppy/locales/lib/nb_NO.js b/packages/@uppy/locales/lib/nb_NO.js
index e257ee1..f1ad3a0 100644
--- a/packages/@uppy/locales/lib/nb_NO.js
+++ b/packages/@uppy/locales/lib/nb_NO.js
@@ -51,9 +51,9 @@ nb_NO.strings = {
   dropPasteBoth: "Dra filer hit, %{browseFiles} eller %{browseFolders}",
   dropPasteFiles: "Dra filer hit eller %{browseFiles}",
   dropPasteFolders: "Dra filer hit eller %{browseFolders}",
-  dropPasteImportBoth: "Dra filer hit %{browseFiles}, %{browseFolders} eller importer fra:",
-  dropPasteImportFiles: "Dra filer hit %{browseFiles} eller importer fra:",
-  dropPasteImportFolders: "Dra filer hit %{browseFolders} eller importer fra:",
+  dropPasteImportBoth: "Dra filer hit, %{browseFiles}, %{browseFolders} eller importer fra:",
+  dropPasteImportFiles: "Dra filer hit, %{browseFiles} eller importer fra:",
+  dropPasteImportFolders: "Dra filer hit, %{browseFolders} eller importer fra:",
   editFile: "Rediger fil",
   editImage: "Rediger bilde",
   editing: "Redigerer %{file}",
diff --git a/packages/@uppy/onedrive/lib/OneDrive.js b/packages/@uppy/onedrive/lib/OneDrive.js
index 12f0030..eeb65f1 100644
--- a/packages/@uppy/onedrive/lib/OneDrive.js
+++ b/packages/@uppy/onedrive/lib/OneDrive.js
@@ -4,7 +4,7 @@ import { ProviderViews } from "@uppy/provider-views";
 import { h } from "preact";
 import locale from "./locale.js";
 const packageJson = {
-  "version": "4.2.2",
+  "version": "4.2.3",
 };
 export default class OneDrive extends UIPlugin {
   constructor(uppy, opts) {
diff --git a/packages/@uppy/react/lib/useUppyState.js b/packages/@uppy/react/lib/useUppyState.js
index 69d7a11..5d631a1 100644
--- a/packages/@uppy/react/lib/useUppyState.js
+++ b/packages/@uppy/react/lib/useUppyState.js
@@ -3,5 +3,5 @@ import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-s
 export default function useUppyState(uppy, selector) {
   const subscribe = useMemo(() => uppy.store.subscribe.bind(uppy.store), [uppy.store]);
   const getSnapshot = useCallback(() => uppy.store.getState(), [uppy.store]);
-  return useSyncExternalStoreWithSelector(subscribe, getSnapshot, null, selector);
+  return useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, selector);
 }
diff --git a/packages/@uppy/remote-sources/lib/index.js b/packages/@uppy/remote-sources/lib/index.js
index 4ca5f10..8a203b6 100644
--- a/packages/@uppy/remote-sources/lib/index.js
+++ b/packages/@uppy/remote-sources/lib/index.js
@@ -11,14 +11,13 @@ import { BasePlugin } from "@uppy/core";
 import Dropbox from "@uppy/dropbox";
 import Facebook from "@uppy/facebook";
 import GoogleDrive from "@uppy/google-drive";
-import GooglePhotos from "@uppy/google-photos";
 import Instagram from "@uppy/instagram";
 import OneDrive from "@uppy/onedrive";
 import Unsplash from "@uppy/unsplash";
 import Url from "@uppy/url";
 import Zoom from "@uppy/zoom";
 const packageJson = {
-  "version": "2.3.1",
+  "version": "2.3.2",
 };
 const availablePlugins = {
   __proto__: null,
@@ -26,7 +25,6 @@ const availablePlugins = {
   Dropbox,
   Facebook,
   GoogleDrive,
-  GooglePhotos,
   Instagram,
   OneDrive,
   Unsplash,
diff --git a/packages/@uppy/screen-capture/lib/ScreenCapture.js b/packages/@uppy/screen-capture/lib/ScreenCapture.js
index 5908d9f..f4bca25 100644
--- a/packages/@uppy/screen-capture/lib/ScreenCapture.js
+++ b/packages/@uppy/screen-capture/lib/ScreenCapture.js
@@ -14,7 +14,7 @@ import { h } from "preact";
 import RecorderScreen from "./RecorderScreen.js";
 import ScreenRecIcon from "./ScreenRecIcon.js";
 const packageJson = {
-  "version": "4.2.1",
+  "version": "4.2.2",
 };
 import locale from "./locale.js";
 function isScreenRecordingSupported() {
diff --git a/packages/@uppy/status-bar/lib/StatusBar.js b/packages/@uppy/status-bar/lib/StatusBar.js
index d9cc643..b87c98d 100644
--- a/packages/@uppy/status-bar/lib/StatusBar.js
+++ b/packages/@uppy/status-bar/lib/StatusBar.js
@@ -12,7 +12,7 @@ import getTextDirection from "@uppy/utils/lib/getTextDirection";
 import statusBarStates from "./StatusBarStates.js";
 import StatusBarUI from "./StatusBarUI.js";
 const packageJson = {
-  "version": "4.1.2",
+  "version": "4.1.3",
 };
 import locale from "./locale.js";
 const speedFilterHalfLife = 2000;
diff --git a/packages/@uppy/transloadit/lib/index.js b/packages/@uppy/transloadit/lib/index.js
index 864333d..ac204e7 100644
--- a/packages/@uppy/transloadit/lib/index.js
+++ b/packages/@uppy/transloadit/lib/index.js
@@ -16,7 +16,7 @@ import AssemblyWatcher from "./AssemblyWatcher.js";
 import Client from "./Client.js";
 import locale from "./locale.js";
 const packageJson = {
-  "version": "4.2.1",
+  "version": "4.2.2",
 };
 const defaultOptions = {
   service: "https://api2.transloadit.com",
@@ -458,7 +458,6 @@ function _getClientVersion2() {
   addPluginVersion("Box", "uppy-box");
   addPluginVersion("Facebook", "uppy-facebook");
   addPluginVersion("GoogleDrive", "uppy-google-drive");
-  addPluginVersion("GooglePhotos", "uppy-google-photos");
   addPluginVersion("GoogleDrivePicker", "uppy-google-drive-picker");
   addPluginVersion("GooglePhotosPicker", "uppy-google-photos-picker");
   addPluginVersion("Instagram", "uppy-instagram");
diff --git a/packages/@uppy/unsplash/lib/Unsplash.js b/packages/@uppy/unsplash/lib/Unsplash.js
index 74f215c..6832e2c 100644
--- a/packages/@uppy/unsplash/lib/Unsplash.js
+++ b/packages/@uppy/unsplash/lib/Unsplash.js
@@ -4,7 +4,7 @@ import { SearchProviderViews } from "@uppy/provider-views";
 import { h } from "preact";
 import locale from "./locale.js";
 const packageJson = {
-  "version": "4.3.2",
+  "version": "4.3.3",
 };
 export default class Unsplash extends UIPlugin {
   constructor(uppy, opts) {
diff --git a/packages/@uppy/url/lib/Url.js b/packages/@uppy/url/lib/Url.js
index ecdcb19..aa99757 100644
--- a/packages/@uppy/url/lib/Url.js
+++ b/packages/@uppy/url/lib/Url.js
@@ -6,7 +6,7 @@ import { h } from "preact";
 import UrlUI from "./UrlUI.js";
 import forEachDroppedOrPastedUrl from "./utils/forEachDroppedOrPastedUrl.js";
 const packageJson = {
-  "version": "4.2.2",
+  "version": "4.2.3",
 };
 import locale from "./locale.js";
 function UrlIcon() {
diff --git a/packages/@uppy/utils/lib/mimeTypes.js b/packages/@uppy/utils/lib/mimeTypes.js
index 09ff76c..adabe58 100644
--- a/packages/@uppy/utils/lib/mimeTypes.js
+++ b/packages/@uppy/utils/lib/mimeTypes.js
@@ -22,6 +22,7 @@ export default {
   mov: "video/quicktime",
   dicom: "application/dicom",
   doc: "application/msword",
+  msg: "application/vnd.ms-outlook",
   docm: "application/vnd.ms-word.document.macroenabled.12",
   docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
   dot: "application/msword",
diff --git a/packages/@uppy/webcam/lib/Webcam.js b/packages/@uppy/webcam/lib/Webcam.js
index a6ebcfe..3eb2af1 100644
--- a/packages/@uppy/webcam/lib/Webcam.js
+++ b/packages/@uppy/webcam/lib/Webcam.js
@@ -27,7 +27,7 @@ import CameraScreen from "./CameraScreen.js";
 import PermissionsScreen from "./PermissionsScreen.js";
 import supportsMediaRecorder from "./supportsMediaRecorder.js";
 const packageJson = {
-  "version": "4.1.1",
+  "version": "4.1.2",
 };
 import locale from "./locale.js";
 function toMimeType(fileType) {
diff --git a/packages/@uppy/webdav/lib/Webdav.js b/packages/@uppy/webdav/lib/Webdav.js
index b11bdd4..3d18c0b 100644
--- a/packages/@uppy/webdav/lib/Webdav.js
+++ b/packages/@uppy/webdav/lib/Webdav.js
@@ -4,7 +4,7 @@ import { ProviderViews, SearchInput } from "@uppy/provider-views";
 import { h } from "preact";
 import { useCallback, useState } from "preact/hooks";
 const packageJson = {
-  "version": "0.3.1",
+  "version": "0.3.2",
 };
 import locale from "./locale.js";
 class WebdavSimpleAuthProvider extends Provider {
diff --git a/packages/@uppy/zoom/lib/Zoom.js b/packages/@uppy/zoom/lib/Zoom.js
index f03c6a6..c01eae7 100644
--- a/packages/@uppy/zoom/lib/Zoom.js
+++ b/packages/@uppy/zoom/lib/Zoom.js
@@ -4,7 +4,7 @@ import { ProviderViews } from "@uppy/provider-views";
 import { h } from "preact";
 import locale from "./locale.js";
 const packageJson = {
-  "version": "3.2.1",
+  "version": "3.2.2",
 };
 export default class Zoom extends UIPlugin {
   constructor(uppy, opts) {

@craig-rueda craig-rueda merged commit b5f445a into release Apr 10, 2025
16 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants