From 2d52aea1706cb62c810d614f2ea478cd5cfdb5b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80?= <78488229+viktor138irk@users.noreply.github.com> Date: Thu, 7 May 2026 20:42:08 +0900 Subject: [PATCH] =?UTF-8?q?=D0=97=D0=B0=D1=89=D0=B8=D1=82=D0=B0=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D0=B8=20=D0=BE=D0=B1=D1=80?= =?UTF-8?q?=D0=B0=D0=B7=D0=BE=D0=B2=20=D0=B4=D0=B8=D1=81=D0=BA=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=BE=D1=82=20=D1=81=D0=BB=D1=83=D1=87=D0=B0=D0=B9=D0=BD?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=20=D0=BF=D0=B5=D1=80=D0=B5=D1=85=D0=BE=D0=B4?= =?UTF-8?q?=D0=B0=20=D0=B1=D1=8B=D0=BB=D0=B0=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/templates/disk_images.html | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/web/templates/disk_images.html b/web/templates/disk_images.html index da73fac..220c269 100644 --- a/web/templates/disk_images.html +++ b/web/templates/disk_images.html @@ -146,6 +146,8 @@ function setUploadMode(active) { uploadActive = active; + window.VirtualityUploadActive = active; + document.body.classList.toggle('upload-active', active); if (active) { button.disabled = false; button.type = 'button'; @@ -172,11 +174,27 @@ speedLine.textContent = 'ожидание…'; } + window.addEventListener('beforeunload', function (event) { + if (!uploadActive) return; + event.preventDefault(); + event.returnValue = 'Идёт загрузка образа. Если уйти со страницы, загрузка будет прервана.'; + }); + + document.addEventListener('click', function (event) { + if (!uploadActive) return; + const navTarget = event.target.closest('a, form button[type="submit"], form button:not([type])'); + if (!navTarget || navTarget === button) return; + event.preventDefault(); + event.stopPropagation(); + statusLine.textContent = 'Сначала заверши или отмени текущую загрузку.'; + }, true); + async function pollConvert(operationId) { - setUploadMode(false); fileInput.disabled = true; button.disabled = true; button.textContent = 'Идёт конвертация…'; + button.classList.remove('danger'); + button.classList.add('primary'); resetProgress('Конвертация образа в qcow2…', '0%'); while (true) { const response = await fetch('/api/operations/' + operationId, {cache: 'no-store'}); @@ -193,17 +211,13 @@ bar.style.width = '100%'; percent.textContent = '100%'; statusLine.textContent = 'Конвертация завершена. Обновляем список образов…'; + setUploadMode(false); setTimeout(() => { window.location.href = '/disk-images'; }, 650); return; } if (op.status === 'error') { statusLine.textContent = 'Ошибка конвертации: ' + (op.message || 'см. журнал операций'); - button.disabled = false; - button.type = 'submit'; - button.textContent = 'Загрузить образ диска'; - button.classList.add('primary'); - button.classList.remove('danger'); - fileInput.disabled = false; + setUploadMode(false); return; } await new Promise(resolve => setTimeout(resolve, 1000)); @@ -282,6 +296,7 @@ bar.style.width = '100%'; percent.textContent = '100%'; statusLine.textContent = 'Готово. Обновляем список образов…'; + setUploadMode(false); window.location.href = '/disk-images'; } else { statusLine.textContent = 'Ошибка загрузки: HTTP ' + xhr.status;