Ludovic
V4
0985ce8
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é.");
});