diff --git a/site/static/files.js b/site/static/files.js index 1f44a12..f30891c 100644 --- a/site/static/files.js +++ b/site/static/files.js @@ -30,7 +30,7 @@ function statusToHTML(st) { if (!st || !st.kind) return ''; switch (st.kind) { - case 'uploading': return '⏳ загрузка...'; + case 'uploading': return '↑ ' + (st.pct || 0) + '%'; case 'uploaded': return ''; case 'unzipping': return '⏳ распаковка...'; case 'parsing': return '⏳ парсинг...'; @@ -223,12 +223,20 @@ function uploadFile(file, onProgress, zipSource) { fd.append('batch_id', state.batchId); if (zipSource) fd.append('zip_source', zipSource); + // Имитация прогресса (fetch не даёт реальный upload progress) + var pct = 0; + var timer = setInterval(function() { + pct = Math.min(pct + 5, 90); // до 90% ползём, остальное — по факту + if (onProgress) onProgress(pct); + }, 200); + return fetch(UPLOAD_URL + '?_=' + Date.now(), { method: 'POST', body: fd }) .then(function(r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); }) .then(function(data) { + clearInterval(timer); if (data.ok) { if (onProgress) onProgress(100); return data; @@ -236,6 +244,7 @@ function uploadFile(file, onProgress, zipSource) { throw new Error(data.error || 'Неизвестная ошибка'); }) .catch(function(e) { + clearInterval(timer); if (e.message === 'Failed to fetch' || e.name === 'TypeError') { throw new Error('Сеть'); } @@ -400,7 +409,7 @@ async function addZipFile(file) { */ async function addRegularFile(file, zipSource) { // Создать запись с начальным статусом - var entry = { name: file.name, lastModified: file.lastModified, size: file.size, file: file, status: { kind: 'uploading' }, zip_source: zipSource || null }; + var entry = { name: file.name, lastModified: file.lastModified, size: file.size, file: file, status: { kind: 'uploading', pct: 0 }, zip_source: zipSource || null }; // ДЕДУПЛИКАЦИЯ: ключ = (zip_source, name), чтобы одноимённые файлы из разных ZIP не затирались var dupKey = (zipSource || '') + '/' + file.name; @@ -424,8 +433,9 @@ async function addRegularFile(file, zipSource) { render(state); try { - // fetch-загрузка (v2.0.1: XHR заменён на fetch — drhider v0.0.29) - var resp = await uploadFile(file, function() { + // fetch-загрузка с имитацией прогресса (XHR → fetch из-за RST) + var resp = await uploadFile(file, function(pct) { + state.files[rowIdx].status = { kind: 'uploading', pct: pct }; render(state); }, zipSource); // Бэкенд возвращает doc_id и contract_id (нижний регистр — Python keys)