uppy icon indicating copy to clipboard operation
uppy copied to clipboard

Google photos

Open mifi opened this issue 10 months ago • 7 comments

closes #2163

remaining tasks:

  • [x] allow using the same oauth provider (google) for drive and photos, must handle callback differently than currently
  • should we share auth token between google drive and google photos? store accessToken/refreshToken outside providerUserSession, keyed on authProvider?
    • agreed to not share the auth session for now as the easiest implementation.
  • [x] must dynamically set scope based on user requested provider
  • [x] fix tests
  • improve UI (support tiles/grid a.la instagram for album list)
    • [x] support tiles/grid a.la instagram for each album's photo list
    • [ ] support tiles/grid a.la instagram for album list - turns out to be harder because we don't seem to have any UI that supports grid tiles for folders/albums.
  • [x] test expired access token / refresh as well as other error codes
  • [x] document at Uppy.io https://github.com/transloadit/uppy.io/pull/223
  • [ ] deploy to Transloadit and enable Google Photos API
  • [ ] show more metadata about photos in the UI? currently the photo name is the file name (XYZ.JPG) which is not very relevant. avilable info is things like: description, date/time, width/height, camera hardware info
  • [ ] get more info about images? (batch) https://developers.google.com/photos/library/guides/access-media-items#get-multiple-media-item

Partner program

  • [x] sign up for partner program https://developers.google.com/photos/partner-program/overview

Potential problems

  • we have custom buttons that kind of violate the UX guidelines https://developers.google.com/photos/library/guides/ux-guidelines
  • we don't show the logged in user's email/name because there's no endpoint for that, like there is for google drive

links:

  • https://developers.google.com/photos/library/guides/overview

mifi avatar Apr 08 '24 11:04 mifi

Diff output files
diff --git a/packages/@uppy/box/lib/Box.js b/packages/@uppy/box/lib/Box.js
index e45f972..1122bd4 100644
--- a/packages/@uppy/box/lib/Box.js
+++ b/packages/@uppy/box/lib/Box.js
@@ -58,6 +58,7 @@ export default class Box extends UIPlugin {
     this.view = new ProviderViews(this, {
       provider: this.provider,
       loadAllFiles: true,
+      virtualList: true,
     });
     const {
       target,
diff --git a/packages/@uppy/companion/lib/config/grant.d.ts b/packages/@uppy/companion/lib/config/grant.d.ts
index f7df73c..97c46b1 100644
--- a/packages/@uppy/companion/lib/config/grant.d.ts
+++ b/packages/@uppy/companion/lib/config/grant.d.ts
@@ -1,12 +1,29 @@
 declare function _exports(): {
-    google: {
-        transport: string;
+    googledrive: {
+        callback: string;
         scope: string[];
+        transport: string;
+        custom_params: {
+            access_type: string;
+            prompt: string;
+        };
+        authorize_url: string;
+        access_url: string;
+        oauth: number;
+        scope_delimiter: string;
+    };
+    googlephotos: {
         callback: string;
+        scope: string[];
+        transport: string;
         custom_params: {
             access_type: string;
             prompt: string;
         };
+        authorize_url: string;
+        access_url: string;
+        oauth: number;
+        scope_delimiter: string;
     };
     dropbox: {
         transport: string;
diff --git a/packages/@uppy/companion/lib/config/grant.js b/packages/@uppy/companion/lib/config/grant.js
index 861adf7..6f113e3 100644
--- a/packages/@uppy/companion/lib/config/grant.js
+++ b/packages/@uppy/companion/lib/config/grant.js
@@ -1,21 +1,36 @@
 "use strict";
 Object.defineProperty(exports, "__esModule", { value: true });
+const google = {
+  transport: "session",
+  // 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": " ",
+};
 // oauth configuration for provider services that are used.
 module.exports = () => {
   return {
-    // for drive
-    google: {
-      transport: "session",
-      scope: [
-        "https://www.googleapis.com/auth/drive.readonly",
-      ],
+    // we need separate auth providers because scopes are different,
+    // and because it would be a too big rewrite to allow reuse of the same provider.
+    googledrive: {
+      ...google,
       callback: "/drive/callback",
-      // 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" },
+      scope: ["https://www.googleapis.com/auth/drive.readonly"],
+    },
+    googlephotos: {
+      ...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: {
       transport: "session",
diff --git a/packages/@uppy/companion/lib/server/controllers/get.js b/packages/@uppy/companion/lib/server/controllers/get.js
index c3b5129..44c2d07 100644
--- a/packages/@uppy/companion/lib/server/controllers/get.js
+++ b/packages/@uppy/companion/lib/server/controllers/get.js
@@ -10,10 +10,7 @@ async function get(req, res) {
   async function getSize() {
     return provider.size({ id, token: accessToken, query: req.query });
   }
-  async function download() {
-    const { stream } = await provider.download({ id, token: accessToken, providerUserSession, query: req.query });
-    return stream;
-  }
+  const download = () => provider.download({ id, token: accessToken, providerUserSession, query: req.query });
   try {
     await startDownUpload({ req, res, getSize, download });
   } catch (err) {
diff --git a/packages/@uppy/companion/lib/server/controllers/url.js b/packages/@uppy/companion/lib/server/controllers/url.js
index 4ab5695..9c36bd4 100644
--- a/packages/@uppy/companion/lib/server/controllers/url.js
+++ b/packages/@uppy/companion/lib/server/controllers/url.js
@@ -26,8 +26,8 @@ const downloadURL = async (url, blockLocalIPs, traceId) => {
   try {
     const protectedGot = getProtectedGot({ blockLocalIPs });
     const stream = protectedGot.stream.get(url, { responseType: "json" });
-    await prepareStream(stream);
-    return stream;
+    const { size } = await prepareStream(stream);
+    return { stream, size };
   } catch (err) {
     logger.error(err, "controller.url.download.error", traceId);
     throw err;
@@ -73,9 +73,7 @@ const get = async (req, res) => {
     const { size } = await getURLMeta(req.body.url, !allowLocalUrls);
     return size;
   }
-  async function download() {
-    return downloadURL(req.body.url, !allowLocalUrls, req.id);
-  }
+  const download = () => downloadURL(req.body.url, !allowLocalUrls, req.id);
   try {
     await startDownUpload({ req, res, getSize, download });
   } catch (err) {
diff --git a/packages/@uppy/companion/lib/server/helpers/oauth-state.d.ts b/packages/@uppy/companion/lib/server/helpers/oauth-state.d.ts
index f1c2709..f2b204d 100644
--- a/packages/@uppy/companion/lib/server/helpers/oauth-state.d.ts
+++ b/packages/@uppy/companion/lib/server/helpers/oauth-state.d.ts
@@ -1,4 +1,5 @@
 export function encodeState(state: any, secret: any): string;
+export function decodeState(state: any, secret: any): any;
 export function generateState(): {
     id: string;
 };
diff --git a/packages/@uppy/companion/lib/server/helpers/oauth-state.js b/packages/@uppy/companion/lib/server/helpers/oauth-state.js
index ccdc572..9421cec 100644
--- a/packages/@uppy/companion/lib/server/helpers/oauth-state.js
+++ b/packages/@uppy/companion/lib/server/helpers/oauth-state.js
@@ -7,7 +7,7 @@ module.exports.encodeState = (state, secret) => {
   const encodedState = Buffer.from(JSON.stringify(state)).toString("base64");
   return encrypt(encodedState, secret);
 };
-const decodeState = (state, secret) => {
+module.exports.decodeState = (state, secret) => {
   const encodedState = decrypt(state, secret);
   return JSON.parse(atob(encodedState));
 };
@@ -17,7 +17,7 @@ module.exports.generateState = () => {
   };
 };
 module.exports.getFromState = (state, name, secret) => {
-  return decodeState(state, secret)[name];
+  return module.exports.decodeState(state, secret)[name];
 };
 module.exports.getGrantDynamicFromRequest = (req) => {
   var _a, _b;
diff --git a/packages/@uppy/companion/lib/server/helpers/upload.js b/packages/@uppy/companion/lib/server/helpers/upload.js
index 923af2a..948e8b4 100644
--- a/packages/@uppy/companion/lib/server/helpers/upload.js
+++ b/packages/@uppy/companion/lib/server/helpers/upload.js
@@ -5,12 +5,20 @@ const logger = require("../logger");
 const { respondWithError } = require("../provider/error");
 async function startDownUpload({ req, res, getSize, download }) {
   try {
-    const size = await getSize();
+    logger.debug("Starting download stream.", null, req.id);
+    const { stream, size: maybeSize } = await download();
+    let size;
+    // if the provider already knows the size, we can use that
+    if (typeof maybeSize === "number" && !Number.isNaN(maybeSize) && maybeSize > 0) {
+      size = maybeSize;
+    }
+    // if not we need to get the size
+    if (size == null) {
+      size = await getSize();
+    }
     const { clientSocketConnectTimeout } = req.companion.options;
     logger.debug("Instantiating uploader.", null, req.id);
     const uploader = new Uploader(Uploader.reqToOptions(req, size));
-    logger.debug("Starting download stream.", null, req.id);
-    const stream = await download();
     (async () => {
       // wait till the client has connected to the socket, before starting
       // the download, so that the client can receive all download/upload progress.
diff --git a/packages/@uppy/companion/lib/server/helpers/utils.js b/packages/@uppy/companion/lib/server/helpers/utils.js
index 5b2a4a7..b7b58e4 100644
--- a/packages/@uppy/companion/lib/server/helpers/utils.js
+++ b/packages/@uppy/companion/lib/server/helpers/utils.js
@@ -140,11 +140,14 @@ module.exports.StreamHttpJsonError = StreamHttpJsonError;
 module.exports.prepareStream = async (stream) =>
   new Promise((resolve, reject) => {
     stream
-      .on("response", () => {
+      .on("response", (response) => {
+        const contentLengthStr = response.headers["content-length"];
+        const contentLength = parseInt(contentLengthStr, 10);
+        const size = !Number.isNaN(contentLength) && contentLength >= 0 ? contentLength : undefined;
         // Don't allow any more data to flow yet.
         // https://github.com/request/request/issues/1990#issuecomment-184712275
         stream.pause();
-        resolve();
+        resolve({ size });
       })
       .on("error", (err) => {
         var _a, _b;
diff --git a/packages/@uppy/companion/lib/server/provider/index.js b/packages/@uppy/companion/lib/server/provider/index.js
index de030b5..3c7caea 100644
--- a/packages/@uppy/companion/lib/server/provider/index.js
+++ b/packages/@uppy/companion/lib/server/provider/index.js
@@ -5,7 +5,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
  */
 const dropbox = require("./dropbox");
 const box = require("./box");
-const drive = require("./drive");
+const drive = require("./google/drive");
+const googlephotos = require("./google/googlephotos");
 const instagram = require("./instagram/graph");
 const facebook = require("./facebook");
 const onedrive = require("./onedrive");
@@ -63,7 +64,7 @@ module.exports.getProviderMiddleware = (providers, grantConfig) => {
  * @returns {Record<string, typeof Provider>}
  */
 module.exports.getDefaultProviders = () => {
-  const providers = { dropbox, box, drive, facebook, onedrive, zoom, instagram, unsplash };
+  const providers = { dropbox, box, drive, googlephotos, facebook, onedrive, zoom, instagram, unsplash };
   return providers;
 };
 /**
diff --git a/packages/@uppy/companion/lib/server/provider/providerErrors.d.ts b/packages/@uppy/companion/lib/server/provider/providerErrors.d.ts
index c8b3753..9e37f86 100644
--- a/packages/@uppy/companion/lib/server/provider/providerErrors.d.ts
+++ b/packages/@uppy/companion/lib/server/provider/providerErrors.d.ts
@@ -24,3 +24,4 @@ export function withProviderErrorHandling({ fn, tag, providerName, isAuthError,
     }) => boolean;
     getJsonErrorMessage: (a: object) => string;
 }): Promise<any>;
+export function withGoogleErrorHandling(providerName: any, tag: any, fn: any): Promise<any>;
diff --git a/packages/@uppy/companion/lib/server/provider/providerErrors.js b/packages/@uppy/companion/lib/server/provider/providerErrors.js
index 1595560..9196c01 100644
--- a/packages/@uppy/companion/lib/server/provider/providerErrors.js
+++ b/packages/@uppy/companion/lib/server/provider/providerErrors.js
@@ -57,4 +57,25 @@ async function withProviderErrorHandling(
     throw err;
   }
 }
-module.exports = { withProviderErrorHandling };
+async function withGoogleErrorHandling(providerName, tag, fn) {
+  return withProviderErrorHandling({
+    fn,
+    tag,
+    providerName,
+    isAuthError: (response) => {
+      var _a;
+      return (
+        response.statusCode === 401
+        || (response.statusCode === 400
+          && ((_a = response.body) === null || _a === void 0 ? void 0 : _a.error) === "invalid_grant") // Refresh token has expired or been revoked
+      );
+    },
+    getJsonErrorMessage: (body) => {
+      var _a;
+      return (_a = body === null || body === void 0 ? void 0 : body.error) === null || _a === void 0
+        ? void 0
+        : _a.message;
+    },
+  });
+}
+module.exports = { withProviderErrorHandling, withGoogleErrorHandling };
diff --git a/packages/@uppy/companion/lib/standalone/helper.js b/packages/@uppy/companion/lib/standalone/helper.js
index 9c21b17..6a83a86 100644
--- a/packages/@uppy/companion/lib/standalone/helper.js
+++ b/packages/@uppy/companion/lib/standalone/helper.js
@@ -72,6 +72,11 @@ 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/locale.js b/packages/@uppy/core/lib/locale.js
index cdb4f7c..7311693 100644
--- a/packages/@uppy/core/lib/locale.js
+++ b/packages/@uppy/core/lib/locale.js
@@ -55,5 +55,6 @@ export default {
       1: "Added %{smart_count} files from %{folder}",
     },
     additionalRestrictionsFailed: "%{count} additional restrictions were not fulfilled",
+    unnamed: "Unnamed",
   },
 };
diff --git a/packages/@uppy/dashboard/lib/utils/copyToClipboard.js b/packages/@uppy/dashboard/lib/utils/copyToClipboard.js
index ed94e73..05bf18e 100644
--- a/packages/@uppy/dashboard/lib/utils/copyToClipboard.js
+++ b/packages/@uppy/dashboard/lib/utils/copyToClipboard.js
@@ -19,7 +19,7 @@ export default function copyToClipboard(textToCopy, fallbackString) {
     textArea.value = textToCopy;
     document.body.appendChild(textArea);
     textArea.select();
-    const magicCopyFailed = cause => {
+    const magicCopyFailed = () => {
       document.body.removeChild(textArea);
       window.prompt(fallbackString, textToCopy);
       resolve();
@@ -27,13 +27,13 @@ export default function copyToClipboard(textToCopy, fallbackString) {
     try {
       const successful = document.execCommand("copy");
       if (!successful) {
-        return magicCopyFailed("copy command unavailable");
+        return magicCopyFailed();
       }
       document.body.removeChild(textArea);
       return resolve();
     } catch (err) {
       document.body.removeChild(textArea);
-      return magicCopyFailed(err);
+      return magicCopyFailed();
     }
   });
 }
diff --git a/packages/@uppy/dropbox/lib/Dropbox.js b/packages/@uppy/dropbox/lib/Dropbox.js
index 3a5bae8..76d0e03 100644
--- a/packages/@uppy/dropbox/lib/Dropbox.js
+++ b/packages/@uppy/dropbox/lib/Dropbox.js
@@ -50,6 +50,7 @@ export default class Dropbox extends UIPlugin {
     this.view = new ProviderViews(this, {
       provider: this.provider,
       loadAllFiles: true,
+      virtualList: true,
     });
     const {
       target,
diff --git a/packages/@uppy/google-drive/lib/GoogleDrive.js b/packages/@uppy/google-drive/lib/GoogleDrive.js
index 1269a20..14c8f7e 100644
--- a/packages/@uppy/google-drive/lib/GoogleDrive.js
+++ b/packages/@uppy/google-drive/lib/GoogleDrive.js
@@ -75,6 +75,7 @@ export default class GoogleDrive extends UIPlugin {
     this.view = new DriveProviderViews(this, {
       provider: this.provider,
       loadAllFiles: true,
+      virtualList: true,
     });
     const {
       target,
diff --git a/packages/@uppy/onedrive/lib/OneDrive.js b/packages/@uppy/onedrive/lib/OneDrive.js
index edec3e4..86c3896 100644
--- a/packages/@uppy/onedrive/lib/OneDrive.js
+++ b/packages/@uppy/onedrive/lib/OneDrive.js
@@ -67,6 +67,7 @@ export default class OneDrive extends UIPlugin {
     this.view = new ProviderViews(this, {
       provider: this.provider,
       loadAllFiles: true,
+      virtualList: true,
     });
     const {
       target,
diff --git a/packages/@uppy/provider-views/lib/Browser.js b/packages/@uppy/provider-views/lib/Browser.js
index 60ad2f8..06876c0 100644
--- a/packages/@uppy/provider-views/lib/Browser.js
+++ b/packages/@uppy/provider-views/lib/Browser.js
@@ -43,7 +43,7 @@ function ListItem(props) {
     id: f.id,
     title: f.name,
     author: f.author,
-    getItemIcon: () => f.icon,
+    getItemIcon: () => viewType === "grid" && f.thumbnail ? f.thumbnail : f.icon,
     isChecked: isChecked(f),
     toggleCheckbox: event => toggleCheckbox(event, f),
     isCheckboxDisabled: false,
@@ -84,7 +84,7 @@ function Browser(props) {
     cancel,
     done,
     noResultsLabel,
-    loadAllFiles,
+    virtualList,
   } = props;
   const selected = currentSelection.length;
   const rows = useMemo(() => [...folders, ...files], [folders, files]);
@@ -131,7 +131,7 @@ function Browser(props) {
           className: "uppy-Provider-empty",
         }, noResultsLabel);
       }
-      if (loadAllFiles) {
+      if (virtualList) {
         return h(
           "div",
           {
diff --git a/packages/@uppy/provider-views/lib/Item/components/ListLi.js b/packages/@uppy/provider-views/lib/Item/components/ListLi.js
index 8784707..7e79d2c 100644
--- a/packages/@uppy/provider-views/lib/Item/components/ListLi.js
+++ b/packages/@uppy/provider-views/lib/Item/components/ListLi.js
@@ -66,7 +66,7 @@ export default function ListItem(props) {
         h("div", {
           className: "uppy-ProviderBrowserItem-iconWrap",
         }, itemIconEl),
-        showTitles && h("span", null, title),
+        showTitles && title ? h("span", null, title) : i18n("unnamed"),
       ),
   );
 }
diff --git a/packages/@uppy/provider-views/lib/ProviderView/ProviderView.js b/packages/@uppy/provider-views/lib/ProviderView/ProviderView.js
index 33f6b85..19d6936 100644
--- a/packages/@uppy/provider-views/lib/ProviderView/ProviderView.js
+++ b/packages/@uppy/provider-views/lib/ProviderView/ProviderView.js
@@ -47,6 +47,7 @@ const defaultOptions = {
   showFilter: true,
   showBreadcrumbs: true,
   loadAllFiles: false,
+  virtualList: false,
 };
 var _abortController = _classPrivateFieldLooseKey("abortController");
 var _withAbort = _classPrivateFieldLooseKey("withAbort");
@@ -386,6 +387,7 @@ export default class ProviderView extends View {
       getNextFolder: this.getNextFolder,
       getFolder: this.getFolder,
       loadAllFiles: this.opts.loadAllFiles,
+      virtualList: this.opts.virtualList,
       showSearchFilter: targetViewOptions.showFilter,
       search: this.filterQuery,
       clearSearch: this.clearFilter,
diff --git a/packages/@uppy/provider-views/lib/View.js b/packages/@uppy/provider-views/lib/View.js
index 69cd639..0886ac5 100644
--- a/packages/@uppy/provider-views/lib/View.js
+++ b/packages/@uppy/provider-views/lib/View.js
@@ -1,5 +1,3 @@
-import getFileType from "@uppy/utils/lib/getFileType";
-import isPreviewSupported from "@uppy/utils/lib/isPreviewSupported";
 import remoteFileObjToLocal from "@uppy/utils/lib/remoteFileObjToLocal";
 export default class View {
   constructor(plugin, opts) {
@@ -104,8 +102,7 @@ export default class View {
         requestClientId: this.requestClientId,
       },
     };
-    const fileType = getFileType(tagFile);
-    if (fileType && isPreviewSupported(fileType)) {
+    if (file.thumbnail) {
       tagFile.preview = file.thumbnail;
     }
     if (file.author) {
diff --git a/packages/@uppy/remote-sources/lib/index.js b/packages/@uppy/remote-sources/lib/index.js
index a8af254..17d3e0b 100644
--- a/packages/@uppy/remote-sources/lib/index.js
+++ b/packages/@uppy/remote-sources/lib/index.js
@@ -13,6 +13,7 @@ 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";
@@ -27,6 +28,7 @@ const availablePlugins = {
   Dropbox,
   Facebook,
   GoogleDrive,
+  GooglePhotos,
   Instagram,
   OneDrive,
   Unsplash,
diff --git a/packages/@uppy/transloadit/lib/index.js b/packages/@uppy/transloadit/lib/index.js
index 529121d..2683802 100644
--- a/packages/@uppy/transloadit/lib/index.js
+++ b/packages/@uppy/transloadit/lib/index.js
@@ -533,6 +533,7 @@ function _getClientVersion2() {
   addPluginVersion("Box", "uppy-box");
   addPluginVersion("Facebook", "uppy-facebook");
   addPluginVersion("GoogleDrive", "uppy-google-drive");
+  addPluginVersion("GooglePhotos", "uppy-google-photos");
   addPluginVersion("Instagram", "uppy-instagram");
   addPluginVersion("OneDrive", "uppy-onedrive");
   addPluginVersion("Zoom", "uppy-zoom");

github-actions[bot] avatar Apr 08 '24 11:04 github-actions[bot]

I think this is now ready for MVP

mifi avatar Apr 12 '24 16:04 mifi

New and removed dependencies detected. Learn more about Socket for GitHub ↗︎

Package New capabilities Transitives Size Publisher
npm/@sideway/[email protected] None 0 16.9 kB marsup
npm/@sinclair/[email protected] None 0 442 kB sinclair
npm/@types/[email protected] None 0 2.88 kB types
npm/@types/[email protected] None 0 7.65 kB types
npm/@uppy-dev/[email protected] None 0 0 B
npm/@yarnpkg/[email protected] environment, eval, filesystem 0 280 kB arcanis
npm/[email protected] None 0 10.4 kB jeffcarp
npm/[email protected] None 0 4.78 kB isaacs
npm/[email protected] None 0 24.4 kB rreverser
npm/[email protected] None 0 1.21 MB marijn
npm/[email protected] eval +1 949 kB esp
npm/[email protected] None 0 9.37 kB sindresorhus
npm/[email protected] environment 0 11.4 kB pfmooney
npm/[email protected] None 0 9.62 kB feross
npm/[email protected] environment, eval, unsafe 0 632 kB esailija
npm/[email protected] None +1 65.6 kB doowb
npm/[email protected] None 0 5.05 kB linusu
npm/[email protected] None 0 82.5 kB feross
npm/[email protected] None 0 11.7 kB sindresorhus
npm/[email protected] environment, filesystem +3 119 kB paulmillr
npm/[email protected] None 0 114 kB omgovich
npm/[email protected] None 0 17 kB jorgebucaran
npm/[email protected] filesystem, shell 0 93.2 kB abetomo
npm/[email protected] None 0 3.94 kB natevw
npm/[email protected] None 0 23.1 kB dougwilson
npm/[email protected] None 0 66 kB feedic
npm/[email protected] environment 0 42.4 kB qix
npm/[email protected] None 0 283 kB mikemcl
npm/[email protected] None 0 4.85 kB dmnd
npm/[email protected] None 0 8.11 kB thlorenz
npm/[email protected] environment, eval 0 30.5 kB dougwilson
npm/[email protected] None 0 14.2 kB lukeed
npm/[email protected] filesystem 0 9.02 kB dougwilson
npm/[email protected] None 0 46 kB simenb
npm/[email protected] None 0 11.4 kB feedic
npm/[email protected] None 0 44.6 kB feedic
npm/[email protected] None 0 5.47 kB raynos
npm/[email protected] None 0 6.26 kB dougwilson
npm/[email protected] None 0 413 kB feedic
npm/[email protected] None 0 3.66 kB dougwilson
npm/[email protected] None 0 2.69 kB jbnicolai
npm/[email protected] None 0 9.54 kB levibuzolic
npm/[email protected] None 0 314 kB ariya
npm/[email protected] None 0 37.1 kB michaelficarra
npm/[email protected] None 0 17.6 kB rich_harris
npm/[email protected] None 0 38 kB lpinca
npm/[email protected] None 0 82.8 kB goto-bus-stop
npm/[email protected] None 0 23.5 kB ljharb
npm/[email protected] None 0 13 kB esp
npm/[email protected] None 0 17 kB esp
npm/[email protected] None 0 9.44 kB hiddentao
npm/[email protected] Transitive: filesystem +1 15.7 kB sindresorhus
npm/[email protected] network 0 29.4 kB rubenverborgh
npm/[email protected] None 0 156 kB pipobscure
npm/[email protected] None 0 4.72 kB stefanpenner
npm/[email protected] None 0 8.68 kB keithamus
npm/[email protected] None 0 12.2 kB sindresorhus
npm/[email protected] None 0 12.1 kB phated
npm/[email protected] filesystem +4 39.3 kB sindresorhus
npm/[email protected] None 0 12.8 kB ljharb
npm/[email protected] None 0 20.6 kB ljharb
npm/[email protected] None 0 35.9 kB kornel
npm/[email protected] None 0 349 kB ashtuchkin
npm/[email protected] None 0 10 kB evilebottnawi
npm/[email protected] None 0 6.8 kB feross
npm/[email protected] Transitive: filesystem, unsafe +3 19.8 kB sindresorhus
npm/[email protected] None 0 3.96 kB isaacs
npm/[email protected] None 0 28.9 kB ljharb
npm/[email protected] filesystem 0 3.01 kB sindresorhus
npm/[email protected] None 0 5.09 kB jonschlinkert
npm/[email protected] None +1 19.8 kB phated
npm/[email protected] None 0 4.12 kB sindresorhus
npm/[email protected] None 0 6.23 kB sindresorhus
npm/[email protected] None 0 6.93 kB doowb
npm/[email protected] None 0 29.3 kB oss-bot
npm/[email protected] None 0 3.79 kB simenb
npm/[email protected] None 0 15.1 kB lydell
npm/[email protected] Transitive: environment, filesystem +1 576 kB vitaly
npm/[email protected] None 0 10.4 kB isaacs
npm/[email protected] None 0 12.7 kB isaacs
npm/[email protected] None 0 235 kB jordanbtucker
npm/[email protected] None 0 22.8 kB doowb
npm/[email protected] None 0 20.3 kB lukeed
npm/[email protected] None 0 20.1 kB jdalton
npm/[email protected] None 0 1.41 MB bnjmnt4n
npm/[email protected] None 0 9.49 kB sindresorhus
npm/[email protected] None 0 8.9 kB zensh
npm/[email protected] network 0 5.29 kB dougwilson
npm/[email protected] None 0 55.9 kB jonschlinkert
npm/[email protected] None 0 206 kB dougwilson
npm/[email protected] environment, filesystem 0 51.7 kB broofa
npm/[email protected] None 0 2.97 kB thejameskyle
npm/[email protected] None 0 1.55 kB cwmma
npm/[email protected] environment, filesystem 0 19.1 kB isaacs
npm/[email protected] None 0 6.84 kB styfle
npm/[email protected] None 0 27.4 kB dougwilson
npm/[email protected] None 0 298 kB suguru03
npm/[email protected] None 0 9.22 kB jonschlinkert
npm/[email protected] None 0 5.49 kB sindresorhus
npm/[email protected] None 0 26.5 kB ljharb
npm/[email protected] None 0 19.1 kB indutny
npm/[email protected] None 0 3.06 kB sindresorhus
npm/[email protected] None +1 13.8 kB sindresorhus
npm/[email protected] None 0 702 kB feedic
npm/[email protected] None 0 10.3 kB dougwilson
npm/[email protected] None 0 4.55 kB sindresorhus
npm/[email protected] None 0 90 kB mrmlnc
npm/[email protected] None 0 7.23 kB sindresorhus
npm/[email protected] unsafe 0 13.5 kB danez
npm/[email protected] None 0 27.2 kB evilebottnawi
npm/[email protected] environment, filesystem +1 202 kB ai
npm/[email protected] environment, filesystem, unsafe 0 8.39 MB prettier-bot
npm/[email protected] None 0 11.5 kB sindresorhus
npm/[email protected] environment +1 118 kB ljharb
npm/[email protected] None 0 8.46 kB dougwilson
npm/[email protected] None 0 27.9 kB benjamn
npm/[email protected] None 0 302 kB mysticatea
npm/[email protected] None 0 31.7 kB feross
npm/[email protected] None 0 42.3 kB chalker
npm/[email protected] None 0 9.96 kB isaacs
npm/[email protected] None 0 805 kB tromey
npm/[email protected] None 0 12.1 kB dougwilson
npm/[email protected] None +1 9.64 kB sindresorhus
npm/[email protected] None 0 6.96 kB sindresorhus
npm/[email protected] environment +1 9.76 kB sindresorhus
npm/[email protected] None 0 46.9 kB sokra
npm/[email protected] None 0 11 kB substack
npm/[email protected] None 0 12.5 kB dominictarr
npm/[email protected] shell 0 7.82 kB wmhilton
npm/[email protected] None 0 42.1 kB chaijs
npm/[email protected] None 0 111 kB sindresorhus
npm/[email protected] None 0 4.31 kB dougwilson
npm/[email protected] None 0 5.48 kB tootallnate
npm/[email protected] None 0 116 kB ctavan
npm/[email protected] None 0 8.75 kB dougwilson
npm/[email protected] None 0 91.3 kB sokra
npm/[email protected] environment Transitive: filesystem +1 20.9 kB isaacs
npm/[email protected] None 0 6.46 kB raynos
npm/[email protected] None 0 14.8 kB isaacs
npm/[email protected] environment 0 448 kB eemeli
npm/[email protected] environment, filesystem 0 124 kB oss-bot

🚮 Removed packages: npm/@angular-devkit/[email protected], npm/@angular-devkit/[email protected], npm/@angular-devkit/[email protected], npm/@angular-eslint/[email protected], npm/@angular-eslint/[email protected], npm/@angular-eslint/[email protected], npm/@angular-eslint/[email protected], npm/@angular-eslint/[email protected], npm/@angular-eslint/[email protected], npm/@angular/[email protected], npm/@angular/[email protected], npm/@angular/[email protected], npm/@angular/[email protected], npm/@angular/[email protected], npm/@angular/[email protected], npm/@angular/[email protected], npm/@angular/[email protected], npm/@angular/[email protected], npm/@angular/[email protected], npm/@aws-crypto/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@aws-sdk/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@babel/[email protected], npm/@cnakazawa/[email protected], npm/@cypress/[email protected], npm/@cypress/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@esbuild/[email protected], npm/@eslint-community/[email protected], npm/@expo/[email protected], npm/@expo/[email protected], npm/@expo/[email protected], npm/@expo/[email protected], npm/@expo/[email protected], npm/@expo/[email protected], npm/@expo/[email protected], npm/@expo/[email protected], npm/@jest/[email protected], npm/@jest/[email protected], npm/@jest/[email protected], npm/@jridgewell/[email protected], npm/@jridgewell/[email protected], npm/@jridgewell/[email protected], npm/@jridgewell/[email protected], npm/@jridgewell/[email protected], npm/@lezer/[email protected], npm/@lezer/[email protected], npm/@lmdb/[email protected], npm/@lmdb/[email protected], npm/@lmdb/[email protected], npm/@lmdb/[email protected], npm/@lmdb/[email protected], npm/@lmdb/[email protected], npm/@mischnic/[email protected], npm/@msgpackr-extract/[email protected], npm/@msgpackr-extract/[email protected], npm/@msgpackr-extract/[email protected], npm/@msgpackr-extract/[email protected], npm/@msgpackr-extract/[email protected], npm/@msgpackr-extract/[email protected], npm/@nicolo-ribaudo/[email protected], npm/@npmcli/[email protected], npm/@parcel/[email protected], npm/@parcel/[email protected], npm/@parcel/[email protected], npm/@parcel/[email protected], npm/@parcel/[email protected], npm/@parcel/[email protected], npm/@parcel/[email protected], npm/@polka/[email protected], npm/@react-native-async-storage/[email protected], npm/@react-native-community/[email protected], npm/@types/[email protected], npm/[email protected], npm/[email protected], npm/[email protected], npm/[email protected], npm/[email protected], npm/[email protected], npm/[email protected], npm/[email protected], npm/[email protected], npm/[email protected], npm/[email protected], npm/[email protected], npm/[email protected]

View full report↗︎

socket-security[bot] avatar Apr 22 '24 19:04 socket-security[bot]

hmm i ran yarn format however it doesn't seem that it worked

mifi avatar Apr 22 '24 19:04 mifi

.env.example should be updated too

not needed afaik because it uses the same env variable as for google drive

mifi avatar May 09 '24 16:05 mifi

ok i finally managed to get ts building too

mifi avatar May 09 '24 18:05 mifi

Actually I forgot I still need to test this locally to see the user experience. I will do that next week.

Murderlon avatar May 16 '24 09:05 Murderlon

any updates?:) would be nice to get it out on uppy.io so people can start testing

mifi avatar May 27 '24 12:05 mifi

Screenshot 2024-05-27 at 16 24 40

For me the album names don't show up. They are not in the response, not sure why. I don't think it's possible to have an unnamed album so probably a bug?

I also think it's better to have icons for folders, because this makes it seems like I'm about to click photos instead of folders.

Murderlon avatar May 27 '24 14:05 Murderlon

They are not in the response, not sure why

you mean you see empty strings in the network tools json response? do you have any way of reproducing this?

I also think it's better to have icons for folders, because this makes it seems like I'm about to click photos instead of folders.

you mean show a folder icon for all albums (no photo thumbnail)?

mifi avatar May 29 '24 20:05 mifi

you mean you see empty strings in the network tools json response? do you have any way of reproducing this?

Here is the network response.

{
	"username": "[email protected]",
	"items": [
		{
			"isFolder": true,
			"icon": "https://lh3.googleusercontent.com/lr/AAJ1LKeAAPyYUFtLUYMCgwFpktAWGYMaruVbOA3RLj0e-gy7rhY-RkoM3rKwmlGxrS6ZF4ORfhbpbDiZ_A_E1a3lc15tkN27Ox1YkuV-G1ykXi91See7oFZbAHs2uO9X36lTU3-hmnUGyQV58It_OiaA9LCPuveMf2l_FGrfg8zsfuu7qEOIs3hHprqSAa90gpM-5inGIW9trBLI2oEjO3_QHRSsanYISC_R9O124n8WZkLC_SfyVCj-MrN_1UgmNWTW52L7rcOvtw1EAT6qrhK1QSZ63dgdhHwcKS0_ogqkmoCOJTHyYtoedh0wiPG_boU7zNHkvk0PbmV2OOGqzCVcoHkDiRz2RoRXVRYj-MNSQSzYFh_t0ELHO_qtJVe_AuOV5kZcGJT40HCCQw5Rnt8SL8OMX02ub5Z5gMFCcN_WePzKe_fWFIS-c00INJOvexesBzyF6Au-MlZFP6jtJrXGZv03LLDzPpAkktDo5641gFmakJm_fOSvS3NgqygAMP1ycdUvXGMqMUUCkZayj6t0Fz0MyDuGu19QgeGVRBmtwdW3vGEZ_ntSHHa6D4qtovXknVCAM-E2Iwny9KbCz4kGxEHuJV0aERCmC9tHDwOwACMSpyicY0H4ooH4x50j7V5IMC_UHlojdL0A6kx58BQBKL5-WW64MD880_d1YDb5kNlcYhpnUNlrBDn6Z6DS_6F9TFekRhdUa4vZxeSBDAx10ML5FNcg3gdhA0JnG1dDgJtiyXdlJAVlg8jHZf5dFbwA3Z_KY8VXkl-yQ2F6wX3bKBtuvoeERP-UPXUr1HcSI6W7U_o1cLdnJYyUXmtUgl1tC0WrOkHmxfRS8S8RfUfF80YR7-EeeuKPX1cg4afKzy1MlSCujYVUlr_rr7_bgKwTkyJA61YysZV687PYB_KCHvdzjZpS8JWRTO7Z_J4nQclky90nS9dW-gFDYa45dryvFTc2VD8C0TuMP0rIpYNorDr19XYZ4e-HB3jNCw=w64-h64-c",
			"thumbnail": "https://lh3.googleusercontent.com/lr/AAJ1LKeAAPyYUFtLUYMCgwFpktAWGYMaruVbOA3RLj0e-gy7rhY-RkoM3rKwmlGxrS6ZF4ORfhbpbDiZ_A_E1a3lc15tkN27Ox1YkuV-G1ykXi91See7oFZbAHs2uO9X36lTU3-hmnUGyQV58It_OiaA9LCPuveMf2l_FGrfg8zsfuu7qEOIs3hHprqSAa90gpM-5inGIW9trBLI2oEjO3_QHRSsanYISC_R9O124n8WZkLC_SfyVCj-MrN_1UgmNWTW52L7rcOvtw1EAT6qrhK1QSZ63dgdhHwcKS0_ogqkmoCOJTHyYtoedh0wiPG_boU7zNHkvk0PbmV2OOGqzCVcoHkDiRz2RoRXVRYj-MNSQSzYFh_t0ELHO_qtJVe_AuOV5kZcGJT40HCCQw5Rnt8SL8OMX02ub5Z5gMFCcN_WePzKe_fWFIS-c00INJOvexesBzyF6Au-MlZFP6jtJrXGZv03LLDzPpAkktDo5641gFmakJm_fOSvS3NgqygAMP1ycdUvXGMqMUUCkZayj6t0Fz0MyDuGu19QgeGVRBmtwdW3vGEZ_ntSHHa6D4qtovXknVCAM-E2Iwny9KbCz4kGxEHuJV0aERCmC9tHDwOwACMSpyicY0H4ooH4x50j7V5IMC_UHlojdL0A6kx58BQBKL5-WW64MD880_d1YDb5kNlcYhpnUNlrBDn6Z6DS_6F9TFekRhdUa4vZxeSBDAx10ML5FNcg3gdhA0JnG1dDgJtiyXdlJAVlg8jHZf5dFbwA3Z_KY8VXkl-yQ2F6wX3bKBtuvoeERP-UPXUr1HcSI6W7U_o1cLdnJYyUXmtUgl1tC0WrOkHmxfRS8S8RfUfF80YR7-EeeuKPX1cg4afKzy1MlSCujYVUlr_rr7_bgKwTkyJA61YysZV687PYB_KCHvdzjZpS8JWRTO7Z_J4nQclky90nS9dW-gFDYa45dryvFTc2VD8C0TuMP0rIpYNorDr19XYZ4e-HB3jNCw=w300-h300-c",
			"name": "Fen",
			"id": "ABlQyLyVT73CwpjSmLSrFjZcbeksmvOsPusxfKEYsxKnQ55zPec1ykSk2fVdxsTN-J0Uw3LjZxt-",
			"requestPath": "ABlQyLyVT73CwpjSmLSrFjZcbeksmvOsPusxfKEYsxKnQ55zPec1ykSk2fVdxsTN-J0Uw3LjZxt-"
		},
		{
			"isFolder": true,
			"icon": "https://lh3.googleusercontent.com/lr/AAJ1LKeQlMlh8_iaFrzN1yCLbafP9AkStDG83hCOdaYYht7MwwXqkWrUrNgcJ2AHfMPNo0zfdqg9zdhaLS1CTJhor0dXES7yE6U1wahFRZFt96GlX_mD2x_HpF66t0ujXgO_6-wGjbUk0iX-ckNDxV84oXu_2Cot_ywEYORxk9VF5NFavYevvlaBm6gnZnNyaT0vnicA4KcaYk_Od46IIrRMnG6Ubh2ChcEn0rOjLwquw33obr9QVDuV3vc2iHCajO9vkRLEvQEMatbO_713nSPTPm7HLTd-D3dPHBiVMZUefkJD1lH_WPwtL83N95krnrBpwg-xP6_9R2EmDgRka4rLOU-Om7cvNnrgjDzri1PQSJIqO8dAjUnMr83XfS8yLYgrESIk0v_gbgQww7GqkGBra98tgVrF-vgtH_4Hiv5QW89QcsOLSsYpOuuXikFq6iv8VNz25QA6iByEjsu2r75PPoGjalqmfr-HMLb0uT6vvYdLYHbeIJgJrUsQGHkXE66kOC3XRD6BFG9KOcDupEaYm-nmP22hhZqIODXkSMR85ZrRUxN3aF3JBz6jL3Z_Y2igfzcoc8JBhhrK61_R7-lwrkBwx8O1OxlkkGYfRY77ysRfzNGZUq9Eyc-7Kc0SMsv6BDpHANvJEpYJE1wWZcsoVxiJaoOIqBrT1Lze_nmQZHpm_vf1LyKqZV6pJmSNsMfXYnA4wrlRvt02Tujj5Q42J_M4PXywaRf35rCpO1s0VuFsfRs3gNiJurhjvUjB85ze9-Wcf4cPKXEFfLS0Dz7DVKKhXUAHn0H82FOquER8XX3aIcprl3nvEaPqhzaU7bX1Pq5p7kP5Se5S9WqSsMp7Ey50XKTooTi54P4uVFDSqUP19do_LvxmfmiULzBa8If8yzRt9pe0MdscOepgGMDDjhh-DuSibEKO9WQ_7tdmskJZv7PaM-ww2c3ofWt3QIQhLOjmxNIYvcokc6Cx0kJr7resFWxSbX0fYWF0mQ=w64-h64-c",
			"thumbnail": "https://lh3.googleusercontent.com/lr/AAJ1LKeQlMlh8_iaFrzN1yCLbafP9AkStDG83hCOdaYYht7MwwXqkWrUrNgcJ2AHfMPNo0zfdqg9zdhaLS1CTJhor0dXES7yE6U1wahFRZFt96GlX_mD2x_HpF66t0ujXgO_6-wGjbUk0iX-ckNDxV84oXu_2Cot_ywEYORxk9VF5NFavYevvlaBm6gnZnNyaT0vnicA4KcaYk_Od46IIrRMnG6Ubh2ChcEn0rOjLwquw33obr9QVDuV3vc2iHCajO9vkRLEvQEMatbO_713nSPTPm7HLTd-D3dPHBiVMZUefkJD1lH_WPwtL83N95krnrBpwg-xP6_9R2EmDgRka4rLOU-Om7cvNnrgjDzri1PQSJIqO8dAjUnMr83XfS8yLYgrESIk0v_gbgQww7GqkGBra98tgVrF-vgtH_4Hiv5QW89QcsOLSsYpOuuXikFq6iv8VNz25QA6iByEjsu2r75PPoGjalqmfr-HMLb0uT6vvYdLYHbeIJgJrUsQGHkXE66kOC3XRD6BFG9KOcDupEaYm-nmP22hhZqIODXkSMR85ZrRUxN3aF3JBz6jL3Z_Y2igfzcoc8JBhhrK61_R7-lwrkBwx8O1OxlkkGYfRY77ysRfzNGZUq9Eyc-7Kc0SMsv6BDpHANvJEpYJE1wWZcsoVxiJaoOIqBrT1Lze_nmQZHpm_vf1LyKqZV6pJmSNsMfXYnA4wrlRvt02Tujj5Q42J_M4PXywaRf35rCpO1s0VuFsfRs3gNiJurhjvUjB85ze9-Wcf4cPKXEFfLS0Dz7DVKKhXUAHn0H82FOquER8XX3aIcprl3nvEaPqhzaU7bX1Pq5p7kP5Se5S9WqSsMp7Ey50XKTooTi54P4uVFDSqUP19do_LvxmfmiULzBa8If8yzRt9pe0MdscOepgGMDDjhh-DuSibEKO9WQ_7tdmskJZv7PaM-ww2c3ofWt3QIQhLOjmxNIYvcokc6Cx0kJr7resFWxSbX0fYWF0mQ=w300-h300-c",
			"id": "ABlQyLyns2Vr5CcPO1btRTXxf911QauEdSzuBLOZ7HYCJUpVFF6cQojQWSqg6BQLrNqEqKdLvweA",
			"requestPath": "ABlQyLyns2Vr5CcPO1btRTXxf911QauEdSzuBLOZ7HYCJUpVFF6cQojQWSqg6BQLrNqEqKdLvweA"
		},
		{
			"isFolder": true,
			"icon": "https://lh3.googleusercontent.com/lr/AAJ1LKcmaO0eq_PNl-Qh_dIReRLFKXMJlXjU2C86rrkAvqu76xFlDEV10-0qIqZRou1FLl6LouznwXnmeYOELDSAc_8bYHnJpPY6ZBcS_Z-h2O4iaSGmIRxlaTrHhuYwuqlN5dJeEPzktUq0-OD10IA8RdKqKnCYYSlOCDbKOzgSimDTUhyepZAHUZ2UHVNLAed7JPyJSTkSv_ldMSDmjSdP1Rm7aEHGDSAvLHLSUAKvjBZTTP0a6UN5xDQfZVd0jJSXReXQRh5WZZgNNkOw_Ur_6OTiixqqHmUnBbC89yLKkw4shLaNpVC8lOCzORLFzvmwdESD0Kl_XWL3Q-H3sdqmtZw42oEe7XRi1n4q70HOqBV2rhg-32XRZU2ZZYxyKP9hVG95Afw8JJD8Ap32K9C14sfL87nob24VYmaGAnfH8erIb703IL9Sad2yZtvZFm-T1oopqwtw4aXjkEVWChsSZ0UW2qytav4zveKpSZSdethStqJZMq57_u97El6Jpk3hY9pPkQ5qgtzEKDQJK3i3DPl-QuvMDo1UZNacC67lOHFBWDSmKHWoLtvfZpdRQlaAnvoPPWTYnrLLVsWzkYEjLQxNHSf_cZFtS5vZ8sDLmQ4EdikrunTvGYmN_-E2ZgiLQhguuMhN38iGa9UBYNvHc2qWJAel6EDUgNqAZuKHYKDEnYPFYlZ0UxJn4eiM6bLhRUGzcIcnKrM2XKg0ZkvwWnXs5oWZ7QtPmIBHOkYvlmB7piZkgJL_nm6d9U2vf_KsGMi8R9FmlV8zqecwuZeo4MsI8hC6QcR1R1Kp-ZI99nUQFxx3bERf6kEFJdelK3qpFXOeI_B1cnifIUEtSRcP3P_VoR_VglmYGHt_k_w-xWTUjYruB9bWMuyuv4TgQ2eMBnN7GmpSsWRsbaYHmy-uuiThRXEmHAcPuenp48pbCf9F00i3qs55KDdqz9utFEKFHQkrGIHHwvZ5TDypIPLw1HVNQQn1tqFiZJAvEgY=w64-h64-c",
			"thumbnail": "https://lh3.googleusercontent.com/lr/AAJ1LKcmaO0eq_PNl-Qh_dIReRLFKXMJlXjU2C86rrkAvqu76xFlDEV10-0qIqZRou1FLl6LouznwXnmeYOELDSAc_8bYHnJpPY6ZBcS_Z-h2O4iaSGmIRxlaTrHhuYwuqlN5dJeEPzktUq0-OD10IA8RdKqKnCYYSlOCDbKOzgSimDTUhyepZAHUZ2UHVNLAed7JPyJSTkSv_ldMSDmjSdP1Rm7aEHGDSAvLHLSUAKvjBZTTP0a6UN5xDQfZVd0jJSXReXQRh5WZZgNNkOw_Ur_6OTiixqqHmUnBbC89yLKkw4shLaNpVC8lOCzORLFzvmwdESD0Kl_XWL3Q-H3sdqmtZw42oEe7XRi1n4q70HOqBV2rhg-32XRZU2ZZYxyKP9hVG95Afw8JJD8Ap32K9C14sfL87nob24VYmaGAnfH8erIb703IL9Sad2yZtvZFm-T1oopqwtw4aXjkEVWChsSZ0UW2qytav4zveKpSZSdethStqJZMq57_u97El6Jpk3hY9pPkQ5qgtzEKDQJK3i3DPl-QuvMDo1UZNacC67lOHFBWDSmKHWoLtvfZpdRQlaAnvoPPWTYnrLLVsWzkYEjLQxNHSf_cZFtS5vZ8sDLmQ4EdikrunTvGYmN_-E2ZgiLQhguuMhN38iGa9UBYNvHc2qWJAel6EDUgNqAZuKHYKDEnYPFYlZ0UxJn4eiM6bLhRUGzcIcnKrM2XKg0ZkvwWnXs5oWZ7QtPmIBHOkYvlmB7piZkgJL_nm6d9U2vf_KsGMi8R9FmlV8zqecwuZeo4MsI8hC6QcR1R1Kp-ZI99nUQFxx3bERf6kEFJdelK3qpFXOeI_B1cnifIUEtSRcP3P_VoR_VglmYGHt_k_w-xWTUjYruB9bWMuyuv4TgQ2eMBnN7GmpSsWRsbaYHmy-uuiThRXEmHAcPuenp48pbCf9F00i3qs55KDdqz9utFEKFHQkrGIHHwvZ5TDypIPLw1HVNQQn1tqFiZJAvEgY=w300-h300-c",
			"id": "ABlQyLy4ph0jPO0yC50yRPxaYHaFdzMR82O5y5SkbFdUeb1UPtp266rcibJsI8PZ1xmR_0iWrbCo",
			"requestPath": "ABlQyLy4ph0jPO0yC50yRPxaYHaFdzMR82O5y5SkbFdUeb1UPtp266rcibJsI8PZ1xmR_0iWrbCo"
		},
		{
			"isFolder": true,
			"icon": "https://lh3.googleusercontent.com/lr/AAJ1LKeRK4usIAiFOw-Ji2B41UYN8Jw5_QZoXOSRE1LA3MZBiUBuMIrbggQXe_dLJ8dIPxPtZrvXNu3l8fyrl-qLV-65SSrUJlI_6HvFuWtnHaBBTQgX4tZ_rRbM8DLKIrqvjkjstW8okeXE6CehBMg8RxZ7Irvu4DjYvrYReatW6hWNnu1UirPdn8Oaxd8df8pHwjkv0CFpn9Codm0RLlt5qYr6TjJ4rl9e1kATD5Rw5EVLEyIEaai1zQhfLptQXyyWIUf-iK4rSUWm_X4FMx9BroeP_JwVtuMS21F_cegfD7suvawvLWgpCCcBI7sXyO02M9Qu7VYpnNqYpcffa3coirLbqIVxxjwIPmJ4WK25ivvgaehKTAZEtXK4AOZ65LhRX9I3-5ZgHuIdx-4iiF_ootFtdyZaVk6Zhbi1tSRs1lEv7zhdDF1tFqM9VS_glCTdOM9cERGUQkmEULvRyantppAi62q5FxIwATIvL2LWHwNbDIMfZl6W8SYKMxAzZ7Pk6Vz7Vyjy8yRMidO650c64QG1eKeTnalCctHIEd33ihDBXzKAteUtUESke6oP8KDMZ5vgD4b5O5rmVpnv6dO6X5VGDNDPD2gv6WjKJMfjy1Ns-5AtZmSPDL7U8r8aQgoCUQXuc8ohPnlkDfR9026nGuqs056mhARd9vrcV3fspyZamKmQ4BtdWCAhYsHgkd7DonmMCkBBQl9zSMDhjQ42votyi6sVHOXmik5LtibCy-ilTT26qg4FuWOfyCJtfN27RGQ00YRmhtWBc6CCSQdYk7ycAxBmC0MvC_3jX8Wbma2FAtNKVDGBiHw0PFEKqlHtyQTVXwbQZKs6rvYQwrEFO2NwixB68hpCBp3aETyDwE_xCMCl7Z7gj6z0z67TgaikxQ_jZUPKXKygYsHxihFQuwt474lmmcZkYq_TPb0zVDo6G5T-F5orDcRsAvH1rybazzIYvbii9GFlwIiaIK3LfWkpttEvFFUmSY52qQ=w64-h64-c",
			"thumbnail": "https://lh3.googleusercontent.com/lr/AAJ1LKeRK4usIAiFOw-Ji2B41UYN8Jw5_QZoXOSRE1LA3MZBiUBuMIrbggQXe_dLJ8dIPxPtZrvXNu3l8fyrl-qLV-65SSrUJlI_6HvFuWtnHaBBTQgX4tZ_rRbM8DLKIrqvjkjstW8okeXE6CehBMg8RxZ7Irvu4DjYvrYReatW6hWNnu1UirPdn8Oaxd8df8pHwjkv0CFpn9Codm0RLlt5qYr6TjJ4rl9e1kATD5Rw5EVLEyIEaai1zQhfLptQXyyWIUf-iK4rSUWm_X4FMx9BroeP_JwVtuMS21F_cegfD7suvawvLWgpCCcBI7sXyO02M9Qu7VYpnNqYpcffa3coirLbqIVxxjwIPmJ4WK25ivvgaehKTAZEtXK4AOZ65LhRX9I3-5ZgHuIdx-4iiF_ootFtdyZaVk6Zhbi1tSRs1lEv7zhdDF1tFqM9VS_glCTdOM9cERGUQkmEULvRyantppAi62q5FxIwATIvL2LWHwNbDIMfZl6W8SYKMxAzZ7Pk6Vz7Vyjy8yRMidO650c64QG1eKeTnalCctHIEd33ihDBXzKAteUtUESke6oP8KDMZ5vgD4b5O5rmVpnv6dO6X5VGDNDPD2gv6WjKJMfjy1Ns-5AtZmSPDL7U8r8aQgoCUQXuc8ohPnlkDfR9026nGuqs056mhARd9vrcV3fspyZamKmQ4BtdWCAhYsHgkd7DonmMCkBBQl9zSMDhjQ42votyi6sVHOXmik5LtibCy-ilTT26qg4FuWOfyCJtfN27RGQ00YRmhtWBc6CCSQdYk7ycAxBmC0MvC_3jX8Wbma2FAtNKVDGBiHw0PFEKqlHtyQTVXwbQZKs6rvYQwrEFO2NwixB68hpCBp3aETyDwE_xCMCl7Z7gj6z0z67TgaikxQ_jZUPKXKygYsHxihFQuwt474lmmcZkYq_TPb0zVDo6G5T-F5orDcRsAvH1rybazzIYvbii9GFlwIiaIK3LfWkpttEvFFUmSY52qQ=w300-h300-c",
			"id": "ABlQyLxqVv8em1iki29QEpG5yE8V0ucryQgnFHGoArHHTwv4GOxtjZly7cyfcx5curEYSoNoV6BH",
			"requestPath": "ABlQyLxqVv8em1iki29QEpG5yE8V0ucryQgnFHGoArHHTwv4GOxtjZly7cyfcx5curEYSoNoV6BH"
		}
	],
	"nextPagePath": null
}

you mean show a folder icon for all albums (no photo thumbnail)?

Yes I think that would be better. Maybe check with @nqst if you need an SVG.

Murderlon avatar May 30 '24 07:05 Murderlon

What is interesting is that I only have one album in Google Photos, which is the one with a name. I have no idea where the others came from. We could also not render albums without a name?

Murderlon avatar May 30 '24 07:05 Murderlon

show a folder icon for all albums (no photo thumbnail)?

I agree it's better to show a folder icon in this view mode (when the icons are small and we don't show the amount of items in albums).

How about reusing the same icon that we use in Google Drive for consistency? We currently use this one but I suggest using the 32x32 version (and scaling it down via width="16" height="16") for better appearance on HiDPI displays.

Screenshot 2024-05-30 at 12 46 34@2x

nqst avatar May 30 '24 10:05 nqst

have now merged main and updated the folder icon. as for the missing folder name, let's just leave it as is because we don't know how to reproduce it?

mifi avatar Jun 12 '24 21:06 mifi

have now merged main and updated the folder icon. as for the missing folder name, let's just leave it as is because we don't know how to reproduce it?

Shall we just add Unnamed as a fallback? Makes it a bit less mysterious than nothing. Then we're good to go I think

Murderlon avatar Jun 13 '24 09:06 Murderlon

👍 Dependency issues cleared. Learn more about Socket for GitHub ↗︎

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report↗︎

socket-security[bot] avatar Jun 13 '24 11:06 socket-security[bot]

done!

mifi avatar Jun 13 '24 11:06 mifi

Testing this PR from within 4.x, found multiple issues that have to do with Google Photos api responses for some folder structures.


When the folder only has other folders inside of it (so - no video/photo files) - mediaItems is undefined, leading to companion errors:

image image

Similar issue happens when we do not have any files at all:

image image

Another issue is that when I click on the Unnamed folder, there is nothing in the breadcrumbs.

image

lakesare avatar Jun 20 '24 00:06 lakesare

that's odd, according to google's documentation mediaItems will not be undefined , however when I test it I also get undefined, so there's clearly something wrong.

anyways I can reproduce the problems and will account for undefined values.

Another issue is that when I click on the Untitled folder, there is nothing in the breadcrumbs.

I don't know how to reproduce an unnamed folder in google photos, but I can reporduce the problem if I manually comment out the name property in companion. will fix it too!

mifi avatar Jun 25 '24 11:06 mifi