diff --git a/client/components/cards/ItemUploadCard.vue b/client/components/cards/ItemUploadCard.vue index 40836b8e4..adbf3adbe 100644 --- a/client/components/cards/ItemUploadCard.vue +++ b/client/components/cards/ItemUploadCard.vue @@ -62,7 +62,24 @@
- + +
+ + {{ nonInteractionLabel }} + +
+ +
+
+ + {{ uploadProgressText }} + +
+
+
+
+
+
@@ -91,7 +108,11 @@ export default { isUploading: false, uploadFailed: false, uploadSuccess: false, - isFetchingMetadata: false + isFetchingMetadata: false, + uploadProgress: { + loaded: 0, + total: 0 + } } }, computed: { @@ -116,6 +137,15 @@ export default { } else if (this.isFetchingMetadata) { return this.$strings.LabelFetchingMetadata } + }, + uploadProgressPercent() { + if (this.uploadProgress.total === 0) return 0 + return Math.min(100, Math.round((this.uploadProgress.loaded / this.uploadProgress.total) * 100)) + }, + uploadProgressText() { + const loaded = this.$bytesPretty(this.uploadProgress.loaded) + const total = this.$bytesPretty(this.uploadProgress.total) + return `${this.uploadProgressPercent}% (${loaded} / ${total})` } }, methods: { @@ -123,6 +153,21 @@ export default { this.isUploading = status === 'uploading' this.uploadFailed = status === 'failed' this.uploadSuccess = status === 'success' + + if (status !== 'uploading') { + this.uploadProgress = { + loaded: 0, + total: 0 + } + } + }, + setUploadProgress(progress) { + if (this.isUploading && progress) { + this.uploadProgress = { + loaded: progress.loaded || 0, + total: progress.total || 0 + } + } }, titleUpdated() { this.error = '' diff --git a/client/components/ui/LoadingIndicator.vue b/client/components/ui/LoadingIndicator.vue index d984bf35e..3b4b6e049 100644 --- a/client/components/ui/LoadingIndicator.vue +++ b/client/components/ui/LoadingIndicator.vue @@ -1,5 +1,5 @@ @@ -23,6 +25,9 @@ export default { computed: { message() { return this.text || this.$strings.MessagePleaseWait + }, + hasSlotContent() { + return this.$slots.default && this.$slots.default.length > 0 } } } diff --git a/client/pages/upload/index.vue b/client/pages/upload/index.vue index 73ebef9c6..adc21ff90 100644 --- a/client/pages/upload/index.vue +++ b/client/pages/upload/index.vue @@ -297,6 +297,15 @@ export default { ref.setUploadStatus(status) } }, + updateItemCardProgress(index, progress) { + var ref = this.$refs[`itemCard-${index}`] + if (ref && ref.length) ref = ref[0] + if (!ref) { + console.error('Book card ref not found', index, this.$refs) + } else { + ref.setUploadProgress(progress) + } + }, async uploadItem(item) { var form = new FormData() form.set('title', item.title) @@ -312,8 +321,20 @@ export default { form.set(`${index++}`, file) }) + const config = { + onUploadProgress: (progressEvent) => { + if (progressEvent.lengthComputable) { + const progress = { + loaded: progressEvent.loaded, + total: progressEvent.total + } + this.updateItemCardProgress(item.index, progress) + } + } + } + return this.$axios - .$post('/api/upload', form) + .$post('/api/upload', form, config) .then(() => true) .catch((error) => { console.error('Failed to upload item', error)