diff --git a/abstract/CTX.js b/abstract/CTX.js index c534be97e..43963a391 100644 --- a/abstract/CTX.js +++ b/abstract/CTX.js @@ -38,5 +38,6 @@ export const uploaderBlockCtx = (fnCtx) => ({ '*collectionState': null, /** @type {import('@uploadcare/upload-client').UploadcareGroup | null} */ '*groupInfo': null, - '*uploadTrigger': null, + /** @type {Set} */ + '*uploadTrigger': new Set(), }); diff --git a/abstract/UploaderBlock.js b/abstract/UploaderBlock.js index 79b2f488f..64a8b69d8 100644 --- a/abstract/UploaderBlock.js +++ b/abstract/UploaderBlock.js @@ -266,14 +266,15 @@ export class UploaderBlock extends ActivityBlock { return !entry.getValue('isRemoved') && !entry.getValue('isUploading') && !entry.getValue('fileInfo'); }); - this.$['*uploadTrigger'] = itemsToUpload; - - if (itemsToUpload.length > 0) { - this.emit( - EventType.COMMON_UPLOAD_START, - /** @type {import('../types').OutputCollectionState<'uploading'>} */ (this.getOutputCollectionState()), - ); + if (itemsToUpload.length === 0) { + return; } + + this.$['*uploadTrigger'] = new Set(itemsToUpload); + this.emit( + EventType.COMMON_UPLOAD_START, + /** @type {import('../types').OutputCollectionState<'uploading'>} */ (this.getOutputCollectionState()), + ); }; /** @param {{ captureCamera?: boolean }} options */ @@ -596,6 +597,8 @@ export class UploaderBlock extends ActivityBlock { } for (const entry of removed) { + /** @type {Set} */ (this.$['*uploadTrigger']).delete(entry.uid); + entry.getValue('abortController')?.abort(); entry.setMultipleValues({ isRemoved: true, @@ -706,17 +709,20 @@ export class UploaderBlock extends ActivityBlock { /** @private */ _flushCommonUploadProgress = () => { - if (!this.$['*uploadTrigger']) { - return; - } let commonProgress = 0; - /** @type {String[]} */ - const items = this.$['*uploadTrigger'] ?? []; + /** @type {Set} */ + const uploadTrigger = this.$['*uploadTrigger']; + const items = [...uploadTrigger].filter((id) => !!this.uploadCollection.read(id)); items.forEach((id) => { - commonProgress += this.uploadCollection.readProp(id, 'uploadProgress'); + const uploadProgress = this.uploadCollection.readProp(id, 'uploadProgress'); + commonProgress += uploadProgress; }); const progress = items.length ? Math.round(commonProgress / items.length) : 0; + if (this.$['*commonProgress'] === progress) { + return; + } + this.$['*commonProgress'] = progress; this.emit( EventType.COMMON_UPLOAD_PROGRESS, diff --git a/blocks/FileItem/FileItem.js b/blocks/FileItem/FileItem.js index 99cd91bd8..936afb124 100644 --- a/blocks/FileItem/FileItem.js +++ b/blocks/FileItem/FileItem.js @@ -54,8 +54,6 @@ export class FileItem extends UploaderBlock { isFocused: false, isEditable: false, state: FileItemState.IDLE, - '*uploadTrigger': null, - onEdit: () => { this.set$({ '*focusedEntry': this._entry, @@ -261,14 +259,16 @@ export class FileItem extends UploaderBlock { }); }; - this.$['*uploadTrigger'] = null; - - this.sub('*uploadTrigger', (itemsToUpload) => { - if (!itemsToUpload?.includes(this._entry.uid)) { - return; - } - setTimeout(() => this.isConnected && this.upload()); - }); + this.sub( + '*uploadTrigger', + /** @param {Set} itemsToUpload */ + (itemsToUpload) => { + if (!itemsToUpload.has(this._entry.uid)) { + return; + } + setTimeout(() => this.isConnected && this.upload()); + }, + ); FileItem.activeInstances.add(this); }