$(function () {
// ------------------------- CONFIGURATION DES ENDPOINTS (à adapter avec vos vraies routes Symfony) -------------------------
// ------------------------- VARIABLES GLOBALES -------------------------
let videoEntries = []; // liste des vidéos
let entryIdCounter = 0;
let isProcessing = false; // file d'attente active ?
let isLoggedIn = false; // état connexion simulé (pour démo)
// Mise à jour affichage connexion
function updateAuthUI() {
const authDiv = $('#authToggle');
if (isLoggedIn) {
authDiv.addClass('connected');
$('#authStatusText').text('Connecté');
} else {
authDiv.removeClass('connected');
$('#authStatusText').text('Non connecté');
}
}
// Récupération des infos vidéo (nom + taille Mo)
function fetchVideoInfo(url, format) {
return new Promise((resolve, reject) => {
// Simulation d'appel AJAX vers app_frontend_size_movie
$.post(ENDPOINTS.getInfo, { url: url }, function (data) {
console.log(data);
resolve({ name: data.filename, sizeMB: data.size });
}).fail(function (response) {
reject(new Error("Erreur serveur lors de la récupération des infos"));
return;
});
});
}
// Téléchargement direct avec progression (streamed)
// Téléchargement direct via SSE avec progression réelle
function startStreamedDownload(entry, onProgress) {
return new Promise((resolve, reject) => {
const encodedVideoUrl = encodeURIComponent(entry.url);
const finalUrl = `${ENDPOINTS.streamDownload}?url=${encodedVideoUrl}&format=${entry.format}`;
const eventSource = new EventSource(finalUrl);
let isResolved = false;
// ✅ Fonction de nettoyage centralisée
function cleanup(timeoutId) {
clearTimeout(timeoutId);
eventSource.close();
}
const timeout = setTimeout(() => {
if (!isResolved) {
isResolved = true;
cleanup(null); // timeout déjà déclenché
reject(new Error('Délai d\'attente dépassé'));
}
}, 300000);
eventSource.onmessage = function (event) {
try {
const data = JSON.parse(event.data);
if (data.progress !== undefined) {
onProgress(data.progress);
}
// ✅ Gérer l'erreur serveur
if (data.error === true) {
if (!isResolved) {
isResolved = true;
cleanup(timeout);
reject(new Error(data.message || 'Erreur serveur pendant le téléchargement'));
}
}
if (data.done === true) {
if (!isResolved) {
isResolved = true;
cleanup(timeout); // ✅ nettoyer le timeout avant resolve
updateEntry(entry.id, { pathDownload: data.pathDownload });
resolve({ success: true });
}
}
} catch (err) {
console.error('[SSE] Erreur parsing JSON:', err);
}
};
eventSource.onerror = function () {
// ✅ Ne rejeter QUE si pas encore résolu (évite faux reject après done)
if (!isResolved) {
isResolved = true;
cleanup(timeout);
reject(new Error('Erreur de connexion SSE'));
}
};
});
}
// Téléchargement en tâche de fond (barre infinie)
function startBackgroundDownload(entry) {
return new Promise((resolve, reject) => {
console.log(`[BACKGROUND] Lancement tâche de fond pour : ${entry.name}`);
// Appel POST vers app_background_download
$.post(ENDPOINTS.backgroundDownload, { url: entry.url, format: entry.format }, function (data) {
resolve({ success: true, jobId: "bg_" + entry.id });
}).fail(function (response) {
reject(new Error("Échec du téléchargement en arrière-plan"));
});
});
}
// Rendu de la liste avec les différents statuts
function renderVideoList() {
const container = $('#videoListContainer');
container.empty();
videoEntries.forEach(entry => {
let progressHtml = '';
let statusHtml = '';
let actionHtml = '';
const status = entry.status;
// Gestion de la barre de progression
if (status === 'downloading') {
const pct = entry.progress || 0;
progressHtml = `
`;
statusHtml = ` Téléchargement : ${pct}%`;
}
else if (status === 'background_downloading') {
// 🔄 Affiche la barre indéterminée avec la classe 'indeterminate'
progressHtml = `
`;
statusHtml = ` Tâche de fond a été créer. une fois le traitement terminé, vous recevrez un e-mail.`;
}
else if (status === 'initializing') {
progressHtml = `