(item)
| 499 | } |
| 500 | |
| 501 | async function uploadChunked(item) { |
| 502 | const rel = getRelativePathForItem(item.file); |
| 503 | const totalChunks = Math.max(1, Math.ceil(item.file.size / CHUNK_SIZE)); |
| 504 | const uploadId = makeUploadId(); |
| 505 | |
| 506 | for (let index = 1; index <= totalChunks; index++) { |
| 507 | const start = (index - 1) * CHUNK_SIZE; |
| 508 | const end = Math.min(item.file.size, start + CHUNK_SIZE); |
| 509 | const blob = item.file.slice(start, end); |
| 510 | |
| 511 | const formData = new FormData(); |
| 512 | appendCommonFormData(formData); |
| 513 | formData.append('resumableChunkNumber', String(index)); |
| 514 | formData.append('resumableTotalChunks', String(totalChunks)); |
| 515 | formData.append('resumableIdentifier', uploadId); |
| 516 | formData.append('resumableFilename', item.file.name); |
| 517 | formData.append('resumableTotalSize', String(item.file.size)); |
| 518 | formData.append('resumableCurrentChunkSize', String(blob.size)); |
| 519 | if (rel) { |
| 520 | formData.append('resumableRelativePath', rel); |
| 521 | } |
| 522 | formData.append('file', blob, item.file.name + '.part' + index); |
| 523 | |
| 524 | const maxAttempts = 3; |
| 525 | let attempt = 0; |
| 526 | let sent = false; |
| 527 | while (attempt < maxAttempts && !sent) { |
| 528 | attempt += 1; |
| 529 | try { |
| 530 | await xhrJson(uploadUrl, formData, function (evt) { |
| 531 | if (!evt.lengthComputable) return; |
| 532 | const chunkPct = evt.total > 0 ? (evt.loaded / evt.total) : 0; |
| 533 | const base = (index - 1) / totalChunks; |
| 534 | const pct = Math.round((base + (chunkPct / totalChunks)) * 100); |
| 535 | setItemStatus(item, 'uploading', pct); |
| 536 | }); |
| 537 | sent = true; |
| 538 | } catch (err) { |
| 539 | if (attempt >= maxAttempts) { |
| 540 | throw err; |
| 541 | } |
| 542 | } |
| 543 | } |
| 544 | |
| 545 | const donePct = Math.round((index / totalChunks) * 100); |
| 546 | setItemStatus(item, 'uploading', donePct); |
| 547 | } |
| 548 | } |
| 549 | |
| 550 | async function uploadItem(item) { |
| 551 | const validationMsg = validateQueueItem(item); |
no test coverage detected