fix: AI photo enhance modal stays open with result preview; fix basicsr build
- Modal no longer auto-closes after Real-ESRGAN completes; result loads into canvas so user can review, adjust sliders, and choose to apply or discard - Backend skips swapEntryPhotoFiles until user confirms via Применить - New DELETE /api/entries/:id/photo/enhance-ai/preview for temp file cleanup - photo-ai Dockerfile: patch basicsr via find+sed instead of import (avoids torchvision.functional_tensor import crash)
This commit is contained in:
+34
-4
@@ -426,6 +426,7 @@ let enhanceEngine = 'auto';
|
||||
let enhanceEngineLoaded = false;
|
||||
let photoAiEnabled = false;
|
||||
let photoAiPollTimer = null;
|
||||
let enhanceAiResultPath = null;
|
||||
|
||||
async function loadEnhanceEngine() {
|
||||
if (enhanceEngineLoaded) return;
|
||||
@@ -469,9 +470,23 @@ async function runPhotoAi() {
|
||||
} catch (e) { clearInterval(photoAiPollTimer); reject(e); }
|
||||
}, 2000);
|
||||
});
|
||||
showToast('Фото восстановлено ИИ');
|
||||
closeEnhance();
|
||||
refreshEntryCard(entryId);
|
||||
showToast('ИИ результат готов');
|
||||
enhanceAiResultPath = result.photo_path;
|
||||
const aiImg = new Image();
|
||||
aiImg.onload = () => {
|
||||
enhanceSourceImg = aiImg;
|
||||
['Brightness', 'Contrast', 'Saturate'].forEach(k => {
|
||||
document.getElementById('enhance' + k).value = 100;
|
||||
document.getElementById('enhance' + k + 'Val').textContent = '100%';
|
||||
});
|
||||
document.getElementById('enhanceSharp').value = 0;
|
||||
document.getElementById('enhanceSharpVal').textContent = '0%';
|
||||
document.getElementById('enhanceDenoise').value = 0;
|
||||
document.getElementById('enhanceDenoiseVal').textContent = '0%';
|
||||
renderEnhancePreview();
|
||||
};
|
||||
aiImg.onerror = () => { showToast('Не удалось загрузить результат ИИ'); };
|
||||
aiImg.src = `${API}${result.photo_path}`;
|
||||
} catch (e) {
|
||||
loading.style.display = 'none';
|
||||
canvas.style.display = 'block';
|
||||
@@ -514,6 +529,7 @@ function openEnhance(id) {
|
||||
if (!mp) { showToast('У записи нет фото'); return; }
|
||||
enhanceEntryId = id;
|
||||
enhanceSourceImg = null;
|
||||
enhanceAiResultPath = null;
|
||||
['Brightness', 'Contrast', 'Saturate'].forEach(k => {
|
||||
const el = document.getElementById('enhance' + k);
|
||||
el.value = 100;
|
||||
@@ -545,10 +561,24 @@ function openEnhance(id) {
|
||||
document.getElementById('enhanceModal').classList.add('open');
|
||||
}
|
||||
|
||||
function cleanupAiPreview() {
|
||||
if (!enhanceAiResultPath || !enhanceEntryId) return;
|
||||
const toClean = enhanceAiResultPath;
|
||||
const entryId = enhanceEntryId;
|
||||
fetch(`${API}/api/entries/${entryId}/photo/enhance-ai/preview`, {
|
||||
method: 'DELETE',
|
||||
headers: hdrJson(),
|
||||
body: JSON.stringify({ path: toClean }),
|
||||
}).catch(() => {});
|
||||
enhanceAiResultPath = null;
|
||||
}
|
||||
|
||||
function closeEnhance() {
|
||||
cleanupAiPreview();
|
||||
document.getElementById('enhanceModal').classList.remove('open');
|
||||
enhanceEntryId = null;
|
||||
enhanceSourceImg = null;
|
||||
enhanceAiResultPath = null;
|
||||
}
|
||||
|
||||
function medianFilterPass(ctx, w, h) {
|
||||
@@ -731,7 +761,7 @@ async function saveEnhance() {
|
||||
try {
|
||||
let done = false;
|
||||
let engineLabel = 'клиент';
|
||||
if (enhanceEngine !== 'client') {
|
||||
if (enhanceEngine !== 'client' && !enhanceAiResultPath) {
|
||||
try {
|
||||
const ctrl = new AbortController();
|
||||
const timer = setTimeout(() => ctrl.abort(), 8000);
|
||||
|
||||
Reference in New Issue
Block a user