fix: сброс состояния при F5/закрытии — beforeunload, abort XHR, close EventSource
Deploy drhider / validate (push) Waiting to run
Deploy drhider / validate (push) Waiting to run
This commit is contained in:
+1
-1
@@ -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.22"
|
VERSION = "0.0.23"
|
||||||
|
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
|
|||||||
@@ -139,6 +139,24 @@ const st = document.getElementById('status');
|
|||||||
const db = document.getElementById('dlBtns');
|
const db = document.getElementById('dlBtns');
|
||||||
let sf = [];
|
let sf = [];
|
||||||
let currentSid = '';
|
let currentSid = '';
|
||||||
|
let activeES = null; // активный EventSource
|
||||||
|
let activeXHR = null; // активный XHR
|
||||||
|
|
||||||
|
function resetAll() {
|
||||||
|
if (activeES) { activeES.close(); activeES = null; }
|
||||||
|
if (activeXHR) { activeXHR.abort(); activeXHR = null; }
|
||||||
|
currentSid = '';
|
||||||
|
sf = [];
|
||||||
|
fi.value = '';
|
||||||
|
rr();
|
||||||
|
st.className = '';
|
||||||
|
st.textContent = '';
|
||||||
|
db.classList.remove('show');
|
||||||
|
ub.disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// При F5 / закрытии вкладки — обрубить всё
|
||||||
|
window.addEventListener('beforeunload', () => resetAll());
|
||||||
|
|
||||||
function fs(b) { return b < 1024 ? b + ' B' : b < 1048576 ? (b / 1024).toFixed(1) + ' KB' : (b / 1048576).toFixed(1) + ' MB'; }
|
function fs(b) { return b < 1024 ? b + ' B' : b < 1048576 ? (b / 1024).toFixed(1) + ' KB' : (b / 1048576).toFixed(1) + ' MB'; }
|
||||||
|
|
||||||
@@ -158,6 +176,11 @@ function ss(idx, h) { const e = document.getElementById('st-' + idx); if (e) e.i
|
|||||||
|
|
||||||
async function uploadFiles() {
|
async function uploadFiles() {
|
||||||
if (sf.length === 0) return;
|
if (sf.length === 0) return;
|
||||||
|
// Обрубить всё что могло остаться от предыдущего раза
|
||||||
|
resetAll();
|
||||||
|
ub.disabled = true;
|
||||||
|
sf = Array.from(fi.files); // восстановить список после resetAll
|
||||||
|
rr();
|
||||||
ub.disabled = true;
|
ub.disabled = true;
|
||||||
db.classList.remove('show');
|
db.classList.remove('show');
|
||||||
const total = sf.length;
|
const total = sf.length;
|
||||||
@@ -201,6 +224,7 @@ async function uploadFiles() {
|
|||||||
};
|
};
|
||||||
xhr.onerror = function() { reject(new Error('Сеть')); };
|
xhr.onerror = function() { reject(new Error('Сеть')); };
|
||||||
xhr.ontimeout = function() { reject(new Error('Таймаут 30с')); };
|
xhr.ontimeout = function() { reject(new Error('Таймаут 30с')); };
|
||||||
|
activeXHR = xhr;
|
||||||
xhr.send(fd);
|
xhr.send(fd);
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -226,8 +250,8 @@ async function uploadFiles() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
const es = new EventSource('/api/process_stream/' + currentSid);
|
activeES = new EventSource('/api/process_stream/' + currentSid);
|
||||||
es.addEventListener('start', function(e) {
|
activeES.addEventListener('start', function(e) {
|
||||||
const d = JSON.parse(e.data);
|
const d = JSON.parse(e.data);
|
||||||
fileTimers[d.idx] = performance.now();
|
fileTimers[d.idx] = performance.now();
|
||||||
fileIntervals[d.idx] = setInterval(function() {
|
fileIntervals[d.idx] = setInterval(function() {
|
||||||
@@ -241,8 +265,9 @@ async function uploadFiles() {
|
|||||||
const elapsed = ((performance.now() - (fileTimers[d.idx] || performance.now())) / 1000).toFixed(1);
|
const elapsed = ((performance.now() - (fileTimers[d.idx] || performance.now())) / 1000).toFixed(1);
|
||||||
ss(d.idx, '<span style="color:#22c55e">✓ ' + elapsed + 'с</span>');
|
ss(d.idx, '<span style="color:#22c55e">✓ ' + elapsed + 'с</span>');
|
||||||
});
|
});
|
||||||
es.addEventListener('complete', function(e) {
|
activeES.addEventListener('complete', function(e) {
|
||||||
es.close();
|
activeES.close();
|
||||||
|
activeES = null;
|
||||||
clearInterval(ptimer);
|
clearInterval(ptimer);
|
||||||
const d = JSON.parse(e.data);
|
const d = JSON.parse(e.data);
|
||||||
st.className = 'status done';
|
st.className = 'status done';
|
||||||
@@ -250,8 +275,9 @@ async function uploadFiles() {
|
|||||||
db.classList.add('show');
|
db.classList.add('show');
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
es.onerror = function() {
|
activeES.onerror = function() {
|
||||||
es.close();
|
activeES.close();
|
||||||
|
activeES = null;
|
||||||
clearInterval(ptimer);
|
clearInterval(ptimer);
|
||||||
reject(new Error('SSE connection failed'));
|
reject(new Error('SSE connection failed'));
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user