diff --git a/src/network/html/FilesPage.html b/src/network/html/FilesPage.html index de01c7c8..884708d6 100644 --- a/src/network/html/FilesPage.html +++ b/src/network/html/FilesPage.html @@ -4851,11 +4851,11 @@ let batchOffset = 0; while (batchOffset < batchBuf.byteLength && ws.readyState === WebSocket.OPEN) { - // Backpressure: yield once when the send buffer is full. - // A single zero-delay yield lets the browser flush the - // WebSocket buffer without the ~4ms minimum of setTimeout. - if (ws.bufferedAmount > WS_CHUNK_SIZE * 4) { - await new Promise(r => setTimeout(r, 0)); + // Backpressure: yield when the send buffer builds up. + // Keeps the ESP32 from being overwhelmed while avoiding + // the ~4ms minimum of higher setTimeout values. + if (ws.bufferedAmount > WS_CHUNK_SIZE * 2) { + await new Promise(r => setTimeout(r, 1)); } if (ws.readyState !== WebSocket.OPEN) { @@ -4870,12 +4870,15 @@ offset = batchEnd; if (onProgress) { - onProgress(offset, totalSize); + // Cap at 99% — 100% is shown only when server confirms DONE + const reported = Math.min(offset, Math.floor(totalSize * 0.99)); + onProgress(reported, totalSize); } } sendingChunks = false; console.log('[WS] All chunks sent, waiting for DONE'); + if (onProgress) onProgress(totalSize, totalSize, 'saving'); } catch (err) { console.error('[WS] Error sending chunks:', err); sendingChunks = false; @@ -5076,20 +5079,24 @@ console.log(`[Upload] ${file.name} via ${uploadMethod}`); let uploadStartTime = 0; - const onProgress = (loaded, total) => { + const onProgress = (loaded, total, state) => { if (!uploadStartTime) uploadStartTime = Date.now(); const uploadPercent = Math.round((loaded / total) * 100); // If conversion succeeded, display goes from 50-100%, otherwise 0-100% const displayPercent = conversionSucceeded ? 50 + Math.round(uploadPercent / 2) : uploadPercent; progressFill.style.width = displayPercent + '%'; - const prefix = conversionSucceeded ? 'Converting & uploading' : 'Uploading'; let speedText = ''; const elapsed = (Date.now() - uploadStartTime) / 1000; if (elapsed > 0.5 && loaded > 0) { const kbps = (loaded / 1024) / elapsed; speedText = kbps >= 1024 ? ` — ${(kbps / 1024).toFixed(1)} MB/s` : ` — ${Math.round(kbps)} KB/s`; } - progressText.textContent = `${prefix} ${file.name} (${currentIndex + 1}/${files.length}) — ${uploadPercent}%${speedText}`; + if (state === 'saving') { + progressText.textContent = `Saving ${file.name} (${currentIndex + 1}/${files.length})...${speedText}`; + } else { + const prefix = conversionSucceeded ? 'Converting & uploading' : 'Uploading'; + progressText.textContent = `${prefix} ${file.name} (${currentIndex + 1}/${files.length}) — ${uploadPercent}%${speedText}`; + } }; const onComplete = () => {