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';