document.addEventListener('DOMContentLoaded', () => { console.log("DOM entièrement chargé et analysé. Initialisation du script."); const uploadForm = document.getElementById('upload-form'); const imageFilesInput = document.getElementById('image-files'); const messageArea = document.getElementById('message-area'); const progressContainer = document.getElementById('progress-container'); const progressBarFill = document.getElementById('progress-bar'); const progressTextElement = document.getElementById('progress-text'); if (!uploadForm || !imageFilesInput || !messageArea || !progressContainer || !progressBarFill || !progressTextElement) { const errorMsg = "Un ou plusieurs éléments d'interface utilisateur sont manquants. L'application ne peut pas fonctionner correctement. Veuillez vérifier les IDs dans les fichiers HTML et JS."; console.error(errorMsg); if (messageArea) { messageArea.textContent = errorMsg; messageArea.className = 'error'; } alert(errorMsg); return; } console.log("Tous les éléments DOM principaux ont été trouvés."); let progressInterval = null; // Pour l'animation de la barre uploadForm.addEventListener('submit', async (event) => { console.log("Événement 'submit' du formulaire capturé."); event.preventDefault(); console.log("event.preventDefault() a été appelé."); // Nettoyer l'intervalle précédent s'il existe if (progressInterval) { clearInterval(progressInterval); progressInterval = null; } try { messageArea.textContent = ''; messageArea.className = ''; const files = imageFilesInput.files; const numFiles = files.length; console.log(`Nombre de fichiers sélectionnés : ${numFiles}`); if (numFiles === 0) { messageArea.textContent = 'Veuillez sélectionner au moins une image.'; messageArea.classList.add('error'); console.warn("Aucun fichier sélectionné, soumission annulée."); return; } console.log("Configuration de la barre de progression..."); progressTextElement.textContent = `Préparation de ${numFiles} image(s)...`; progressBarFill.style.width = '0%'; // Réinitialiser progressBarFill.classList.remove('processing-animation'); // Assurer que l'ancienne classe d'animation est retirée progressBarFill.classList.remove('determinate'); progressBarFill.textContent = ''; progressContainer.style.display = 'block'; // Démarrer une progression visuelle (même si elle n'est pas parfaitement synchronisée) let currentProgress = 0; progressBarFill.style.width = '5%'; // Départ initial progressTextElement.textContent = `Traitement de ${numFiles} image(s) en cours... (Étape 1/3 Préparation)`; // Ajout de la classe pour une animation CSS douce vers 90% // L'animation CSS se chargera d'aller vers la largeur cible setTimeout(() => { progressBarFill.classList.add('processing-animation'); progressBarFill.style.width = '20%'; // Déclencheur pour l'animation CSS qui pourrait aller plus loin progressTextElement.textContent = `Traitement de ${numFiles} image(s) en cours... (Étape 2/3 Envoi et IA)`; }, 100); // Petit délai pour que le 5% initial soit rendu const formData = new FormData(); for (const file of files) { formData.append('files', file); } console.log("FormData construit."); console.log("Début de la requête fetch vers /api/upload-images/..."); const response = await fetch('/api/upload-images/', { method: 'POST', body: formData, }); console.log(`Réponse reçue du serveur : ${response.status} ${response.statusText}`); // Arrêter l'animation de progression "en cours" et préparer pour l'état final progressBarFill.classList.remove('processing-animation'); // Retirer l'animation en cours if (progressInterval) { // Au cas où un intervalle serait utilisé clearInterval(progressInterval); progressInterval = null; } if (response.ok) { console.log("Réponse OK. Traitement du blob ZIP."); progressTextElement.textContent = `Traitement de ${numFiles} image(s) terminé. Préparation du téléchargement... (Étape 3/3)`; progressBarFill.style.width = '95%'; // Presque terminé const blob = await response.blob(); const contentDisposition = response.headers.get('content-disposition'); let filename = "captions_output.zip"; if (contentDisposition) { const filenameMatch = contentDisposition.match(/filename="?(.+)"?/i); if (filenameMatch && filenameMatch.length === 2) filename = filenameMatch[1].replace(/^"|"$/g, ''); // Enlever les guillemets } console.log(`Nom du fichier ZIP à télécharger : ${filename}`); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = filename; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(link.href); console.log("Téléchargement du ZIP initié."); messageArea.textContent = `${numFiles} image(s) traitée(s). Le fichier ZIP '${filename}' est en cours de téléchargement.`; messageArea.classList.add('success'); progressBarFill.style.width = '100%'; progressBarFill.classList.add('determinate'); progressBarFill.textContent = 'Terminé !'; progressTextElement.textContent = "Opération terminée avec succès !"; console.log("Interface utilisateur mise à jour pour le succès."); } else { console.error(`Erreur HTTP : ${response.status} ${response.statusText}`); let errorDetail = `Erreur ${response.status}.`; try { const errorResult = await response.json(); if (errorResult && errorResult.detail) { errorDetail = errorResult.detail; } } catch (e) { const errorText = await response.text().catch(() => "Impossible de lire le corps de l'erreur."); errorDetail += ` ${errorText.substring(0, 300)}`; } messageArea.textContent = `Une erreur est survenue : ${errorDetail}`; console.error(`Détail de l'erreur du serveur : ${errorDetail}`); messageArea.classList.add('error'); if (progressContainer) progressContainer.style.display = 'none'; } } catch (error) { console.error('Erreur globale dans le gestionnaire de soumission :', error); messageArea.textContent = 'Une erreur critique est survenue dans le script client. Vérifiez la console du navigateur.'; messageArea.classList.add('error'); if (progressContainer) progressContainer.style.display = 'none'; if (progressInterval) { clearInterval(progressInterval); progressInterval = null; } progressBarFill.classList.remove('processing-animation'); } }); console.log("Gestionnaire d'événement 'submit' attaché."); });