v0.0.6: прогресс загрузки в строке (XMLHttpRequest onprogress)
Deploy drhider / validate (push) Waiting to run

This commit is contained in:
2026-07-13 10:52:09 +04:00
parent e4975fb37e
commit 46d8ced0dd
2 changed files with 34 additions and 11 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ if _sys_path_root not in sys.path:
sys.path.insert(0, _sys_path_root) sys.path.insert(0, _sys_path_root)
# Версия приложения (меняется при изменениях) # Версия приложения (меняется при изменениях)
VERSION = "0.0.5" VERSION = "0.0.6"
def create_app(): def create_app():
+33 -10
View File
@@ -156,21 +156,44 @@ async function uploadFiles() {
db.classList.remove('show'); db.classList.remove('show');
const total = sf.length; const total = sf.length;
// Фаза 1: загрузка // Фаза 1: загрузка (XMLHttpRequest — прогресс в строке)
for (let i = 0; i < total; i++) { for (let i = 0; i < total; i++) {
const f = sf[i], n = i + 1; const f = sf[i], n = i + 1;
ss(i, '<span style="color:#2563eb">⏳ загрузка</span>');
st.className = 'status progress'; st.className = 'status progress';
st.textContent = 'Загрузка ' + n + '/' + total + ': ' + f.name; st.textContent = 'Загрузка ' + n + '/' + total + ': ' + f.name;
const fd = new FormData();
fd.append('files', f, f.name);
if (currentSid) fd.append('session', currentSid);
try { try {
const resp = await fetch('/api/upload', { method: 'POST', body: fd }); const t0 = performance.now();
const data = await resp.json(); await new Promise((resolve, reject) => {
if (!data.ok) throw new Error(data.error); const xhr = new XMLHttpRequest();
currentSid = data.session; xhr.open('POST', '/api/upload');
ss(i, '<span style="color:#22c55e">✓ загружен</span>'); xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
const pct = Math.round(e.loaded / e.total * 100);
ss(i, '<span style="color:#2563eb">⏳ ' + pct + '%</span>');
}
};
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, '<span style="color:#22c55e">✓ ' + fs(speed) + '/s</span>');
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) { } catch (err) {
ss(i, '<span style="color:#ef4444">✗</span>'); ss(i, '<span style="color:#ef4444">✗</span>');
st.className = 'status error'; st.className = 'status error';