diff --git a/site/app.py b/site/app.py index 8ed38c9..cef2906 100644 --- a/site/app.py +++ b/site/app.py @@ -20,7 +20,7 @@ if _sys_path_root not in sys.path: sys.path.insert(0, _sys_path_root) # Версия приложения (меняется при изменениях) -VERSION = "0.0.5" +VERSION = "0.0.6" def create_app(): diff --git a/site/templates/index.html b/site/templates/index.html index 929c465..41bad6f 100644 --- a/site/templates/index.html +++ b/site/templates/index.html @@ -156,21 +156,44 @@ async function uploadFiles() { db.classList.remove('show'); const total = sf.length; - // Фаза 1: загрузка + // Фаза 1: загрузка (XMLHttpRequest — прогресс в строке) for (let i = 0; i < total; i++) { const f = sf[i], n = i + 1; - ss(i, '⏳ загрузка'); st.className = 'status progress'; st.textContent = 'Загрузка ' + n + '/' + total + ': ' + f.name; - const fd = new FormData(); - fd.append('files', f, f.name); - if (currentSid) fd.append('session', currentSid); try { - const resp = await fetch('/api/upload', { method: 'POST', body: fd }); - const data = await resp.json(); - if (!data.ok) throw new Error(data.error); - currentSid = data.session; - ss(i, '✓ загружен'); + const t0 = performance.now(); + await new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('POST', '/api/upload'); + xhr.upload.onprogress = function(e) { + if (e.lengthComputable) { + const pct = Math.round(e.loaded / e.total * 100); + ss(i, '⏳ ' + pct + '%'); + } + }; + xhr.onload = function() { + if (xhr.status === 200) { + const data = JSON.parse(xhr.responseText); + if (data.ok) { + const elapsed = (performance.now() - t0) / 1000; + const speed = f.size / elapsed; + ss(i, '✓ ' + fs(speed) + '/s'); + currentSid = data.session; + resolve(); + } else { + reject(new Error(data.error)); + } + } else { + reject(new Error('HTTP ' + xhr.status)); + } + }; + xhr.onerror = function() { reject(new Error('Сеть')); }; + const fd = new FormData(); + fd.append('files', f, f.name); + if (currentSid) fd.append('session', currentSid); + xhr.send(fd); + }); } catch (err) { ss(i, ''); st.className = 'status error';