fix: anti-doublon complet — flag isUploading frontend + traitement duplicate comme succès
- Frontend: flag isUploading empêche les uploads parallèles (double/triple soumission)
- Frontend: réponse 'duplicate' traitée comme un succès (toast info au lieu d'erreur)
- Frontend: message d'erreur réseau plus explicite ('serveur injoignable')
- Frontend: HTTP 409 (conflit concurrent) géré proprement
- Serveur lancé sans watcher (--no-watcher) sur Linux (dossier vide = inutile)
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Changelog — imagod-web v0.2.0+build.23-5a2e12d-dirty</title>
|
||||
<title>Changelog — imagod-web v0.2.0+build.24-0309359-dirty</title>
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🖼️</text></svg>">
|
||||
<style>
|
||||
* { margin:0; padding:0; box-sizing:border-box; }
|
||||
@@ -37,7 +37,7 @@ footer { text-align:center; color:#484f58; font-size:0.8rem; padding:2rem; }
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>📋 imagod-web <span class="version-badge">v0.2.0+build.23-5a2e12d-dirty</span></h1>
|
||||
<h1>📋 imagod-web <span class="version-badge">v0.2.0+build.24-0309359-dirty</span></h1>
|
||||
<nav>
|
||||
<a href="/">🖼️ Galerie</a>
|
||||
<a href="/changelog" class="active">📋 Changelog</a>
|
||||
@@ -107,6 +107,6 @@ footer { text-align:center; color:#484f58; font-size:0.8rem; padding:2rem; }
|
||||
<h2>Légende des tags</h2>
|
||||
|
||||
</main>
|
||||
<footer>imagod-web v0.2.0+build.23-5a2e12d-dirty — <a href="https://git.dracodev.net/Projets/imagod-web">Gitea</a></footer>
|
||||
<footer>imagod-web v0.2.0+build.24-0309359-dirty — <a href="https://git.dracodev.net/Projets/imagod-web">Gitea</a></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Aide & Roadmap — imagod-web v0.2.0+build.23-5a2e12d-dirty</title>
|
||||
<title>Aide & Roadmap — imagod-web v0.2.0+build.24-0309359-dirty</title>
|
||||
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🖼️</text></svg>">
|
||||
<style>
|
||||
* { margin:0; padding:0; box-sizing:border-box; }
|
||||
@@ -37,7 +37,7 @@ footer { text-align:center; color:#484f58; font-size:0.8rem; padding:2rem; }
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>❓ imagod-web <span class="version-badge">v0.2.0+build.23-5a2e12d-dirty</span></h1>
|
||||
<h1>❓ imagod-web <span class="version-badge">v0.2.0+build.24-0309359-dirty</span></h1>
|
||||
<nav>
|
||||
<a href="/">🖼️ Galerie</a>
|
||||
<a href="/changelog">📋 Changelog</a>
|
||||
@@ -169,6 +169,6 @@ footer { text-align:center; color:#484f58; font-size:0.8rem; padding:2rem; }
|
||||
<p>5. <strong>Corriger le backend Imago</strong> (thumbnails, upload, stockage)</p>
|
||||
|
||||
</main>
|
||||
<footer>imagod-web v0.2.0+build.23-5a2e12d-dirty — <a href="https://git.dracodev.net/Projets/imagod-web">Gitea</a></footer>
|
||||
<footer>imagod-web v0.2.0+build.24-0309359-dirty — <a href="https://git.dracodev.net/Projets/imagod-web">Gitea</a></footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+28
-4
@@ -465,7 +465,7 @@
|
||||
<button class="btn" id="clear-btn" style="display:none">✕</button>
|
||||
</div>
|
||||
<button class="btn accent" id="header-upload-btn" onclick="document.getElementById('drop-zone').scrollIntoView({behavior:'smooth'}); document.getElementById('file-input').click()">📤 Upload</button>
|
||||
<span class="version-badge" id="version-badge">v0.2.0+build.23-5a2e12d-dirty</span>
|
||||
<span class="version-badge" id="version-badge">v0.2.0+build.24-0309359-dirty</span>
|
||||
</div>
|
||||
|
||||
<!-- ─── Navigation ─── -->
|
||||
@@ -911,8 +911,15 @@ function addTagInput(event, imgId) {
|
||||
}
|
||||
|
||||
// ─── Upload ───
|
||||
let isUploading = false; // Empêche les uploads parallèles
|
||||
|
||||
async function uploadFiles(files) {
|
||||
if (!files || files.length === 0) return;
|
||||
if (isUploading) {
|
||||
showToast('Upload déjà en cours, veuillez patienter...', 'warning');
|
||||
return;
|
||||
}
|
||||
isUploading = true;
|
||||
|
||||
const zone = document.getElementById('drop-zone');
|
||||
let successCount = 0, errorCount = 0;
|
||||
@@ -935,18 +942,35 @@ async function uploadFiles(files) {
|
||||
const data = await r.json();
|
||||
|
||||
if (r.ok) {
|
||||
successCount++;
|
||||
showToast(`${file.name} uploadé !`, 'success', 3000);
|
||||
// duplicate = l'image existe déjà → c'est un succès
|
||||
if (data.status === 'duplicate') {
|
||||
successCount++;
|
||||
showToast(`${file.name} déjà existante (dédoublonnée) ✓`, 'info', 3000);
|
||||
} else {
|
||||
successCount++;
|
||||
showToast(`${file.name} uploadée !`, 'success', 3000);
|
||||
}
|
||||
} else if (r.status === 409) {
|
||||
// Conflit = upload concurrent → on attend un peu et on informe
|
||||
showToast(`${file.name} : upload concurrent détecté, réessayez`, 'warning');
|
||||
errorCount++;
|
||||
} else {
|
||||
errorCount++;
|
||||
showToast(`${file.name} : ${data.error || 'Échec'}`, 'error');
|
||||
}
|
||||
} catch(e) {
|
||||
errorCount++;
|
||||
showToast(`${file.name} : ${e.message}`, 'error');
|
||||
// Distinguer les types d'erreurs réseau
|
||||
const msg = e.message || 'Erreur inconnue';
|
||||
if (msg.includes('Failed to fetch') || msg.includes('NetworkError')) {
|
||||
showToast(`${file.name} : serveur injoignable — vérifiez la connexion`, 'error');
|
||||
} else {
|
||||
showToast(`${file.name} : ${msg}`, 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isUploading = false;
|
||||
zone.classList.remove('uploading');
|
||||
zone.querySelector('.drop-zone-text').textContent = 'Glissez-déposez des images ici';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user