From c7fc9a1480f899150369dba4f788a05054c1ba86 Mon Sep 17 00:00:00 2001 From: James Collins Date: Tue, 29 Aug 2023 14:51:30 +1000 Subject: [PATCH] support chunk uploading --- .../js/components/dialogs/SMDialogUpload.vue | 99 ++++++++++++------- 1 file changed, 66 insertions(+), 33 deletions(-) diff --git a/resources/js/components/dialogs/SMDialogUpload.vue b/resources/js/components/dialogs/SMDialogUpload.vue index 257a052..ada34eb 100644 --- a/resources/js/components/dialogs/SMDialogUpload.vue +++ b/resources/js/components/dialogs/SMDialogUpload.vue @@ -156,43 +156,76 @@ const handleChangeSelectFile = async () => { ) { const file = fileList[uploadFileNum.value]; - let submitFormData = new FormData(); - submitFormData.append("file", file); - submitFormData.append("title", convertFileNameToTitle(file.name)); - submitFormData.append("description", ""); - try { - uploadFileName.value = file.name; - uploadFileProgress.value = 0; + const chunkSize = 50 * 1024 * 1024; + let chunk = 0; + let chunkCount = 1; + let resultMedia = null; - let result = await api.post({ - url: "/media", - body: submitFormData, - headers: { - "Content-Type": "multipart/form-data", - }, - progress: (progressEvent) => { - uploadFileProgress.value = Math.floor( - (progressEvent.loaded / progressEvent.total) * 100, - ); - }, - }); - if (result.data) { - const data = result.data as MediaResponse; - processingItems.value.push(data.medium); - } - } catch (error) { - let errorString = "A server error occurred"; + if (file.size > chunkSize) { + chunkCount = Math.ceil(file.size / chunkSize); + } - if (error.status == 413) { - errorString = `The file is larger than ${max_upload_size.value}`; + uploadFileName.value = file.name; + uploadFileProgress.value = 0; + + while (chunk < chunkCount) { + let submitFormData = new FormData(); + if (chunkCount == 1) { + submitFormData.append("file", file); + } else { + const offset = chunk * chunkSize; + const fileChunk = file.slice(offset, offset + chunkSize); + submitFormData.append("file", fileChunk); + submitFormData.append("chunk", (chunk + 1).toString()); + submitFormData.append("chunk_count", chunkCount.toString()); } - useToastStore().addToast({ - title: "Upload failed", - type: "danger", - content: errorString, - }); - } finally { + submitFormData.append( + "title", + convertFileNameToTitle(file.name), + ); + submitFormData.append("description", ""); + + try { + let result = await api.post({ + url: "/media", + body: submitFormData, + headers: { + "Content-Type": "multipart/form-data", + }, + progress: (progressEvent) => { + uploadFileProgress.value = Math.floor( + ((chunk * chunkSize + progressEvent.loaded) / + file.size) * + 100, + ); + }, + }); + if (result.data) { + resultMedia = (result.data as MediaResponse).medium; + } + } catch (error) { + let errorString = "A server error occurred"; + + if (error.status == 413) { + errorString = `The file is larger than ${max_upload_size.value}`; + } + + useToastStore().addToast({ + title: "Upload failed", + type: "danger", + content: errorString, + }); + + resultMedia = null; + break; + } + + chunk++; + } + + if (resultMedia != null) { + processingItems.value.push(resultMedia); processFiles(); } }