diff --git a/web/package-lock.json b/web/package-lock.json index 5896ca8c9..d0f920b77 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -19,7 +19,6 @@ "leaflet.markercluster": "^1.5.3", "lodash-es": "^4.17.21", "luxon": "^3.2.1", - "rxjs": "^7.8.0", "socket.io-client": "^4.6.1", "svelte-local-storage-store": "^0.5.0", "svelte-material-icons": "^3.0.5", @@ -10526,14 +10525,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -11447,7 +11438,8 @@ "node_modules/tslib": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "dev": true }, "node_modules/tsutils": { "version": "3.21.0", @@ -19522,14 +19514,6 @@ "queue-microtask": "^1.2.2" } }, - "rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "requires": { - "tslib": "^2.1.0" - } - }, "sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -20184,7 +20168,8 @@ "tslib": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", + "dev": true }, "tsutils": { "version": "3.21.0", diff --git a/web/package.json b/web/package.json index 9fe3fc5b3..805b2d12b 100644 --- a/web/package.json +++ b/web/package.json @@ -70,7 +70,6 @@ "leaflet.markercluster": "^1.5.3", "lodash-es": "^4.17.21", "luxon": "^3.2.1", - "rxjs": "^7.8.0", "socket.io-client": "^4.6.1", "svelte-local-storage-store": "^0.5.0", "svelte-material-icons": "^3.0.5", diff --git a/web/src/lib/utils/file-uploader.ts b/web/src/lib/utils/file-uploader.ts index badfd690c..4f7bc07b5 100644 --- a/web/src/lib/utils/file-uploader.ts +++ b/web/src/lib/utils/file-uploader.ts @@ -1,8 +1,7 @@ import { uploadAssetsStore } from '$lib/stores/upload'; -import { addAssetsToAlbum, getFilenameExtension } from '$lib/utils/asset-utils'; +import { addAssetsToAlbum } from '$lib/utils/asset-utils'; import type { AssetFileUploadResponseDto } from '@api'; import axios from 'axios'; -import { combineLatestAll, filter, firstValueFrom, from, mergeMap, of } from 'rxjs'; import { notificationController, NotificationType } from './../components/shared-components/notification/notification'; const extensions = [ @@ -70,9 +69,9 @@ export const openFileUploadDialog = async ( if (!target.files) { return; } - const files = Array.from(target.files); + const files = Array.from(target.files); - resolve(await fileUploadHandler(files, albumId, sharedKey)); + resolve(fileUploadHandler(files, albumId, sharedKey)); }; fileSelector.click(); @@ -88,16 +87,33 @@ export const fileUploadHandler = async ( albumId: string | undefined = undefined, sharedKey: string | undefined = undefined, ) => { - return firstValueFrom( - from(files).pipe( - filter((file) => extensions.includes('.' + getFilenameExtension(file.name))), - mergeMap(async (file) => of(await fileUploader(file, albumId, sharedKey)), 2), - combineLatestAll(), - ), - ); + const iterable = { + files: files.filter((file) => extensions.some((ext) => file.name.endsWith(ext)))[Symbol.iterator](), + + async *[Symbol.asyncIterator]() { + for (const file of this.files) { + yield fileUploader(file, albumId, sharedKey); + } + }, + }; + + const concurrency = 2; + // TODO: use Array.fromAsync instead when it's available universally. + return Promise.all([...Array(concurrency)].map(() => fromAsync(iterable))).then((res) => res.flat()); }; -//TODO: should probably use the @api SDK +// polyfill for Array.fromAsync. +// +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync +const fromAsync = async function (iterable: AsyncIterable) { + const result = []; + for await (const value of iterable) { + result.push(value); + } + return result; +}; + +// TODO: should probably use the @api SDK async function fileUploader( asset: File, albumId: string | undefined = undefined, @@ -122,7 +138,7 @@ async function fileUploader( progress: 0, }); - const response = await axios.post(`/api/asset/upload`, formData, { + const response = await axios.post('/api/asset/upload', formData, { params: { key: sharedKey, },