From e68949baeb0ed6ed4794cb4cbcc48791a3a3c77a Mon Sep 17 00:00:00 2001 From: Manus Date: Fri, 30 Jan 2026 09:37:18 -0500 Subject: [PATCH] =?UTF-8?q?Checkpoint:=20R=C3=A9solution=20du=20probl?= =?UTF-8?q?=C3=A8me=20de=20latence=20d'affichage=20avec=20double=20request?= =?UTF-8?q?AnimationFrame=20:=20cette=20technique=20garantit=20que=20le=20?= =?UTF-8?q?navigateur=20peint=20l'animation=20=C3=A0=20l'=C3=A9cran=20avan?= =?UTF-8?q?t=20de=20bloquer=20sur=20le=20fetch.=20Le=20premier=20requestAn?= =?UTF-8?q?imationFrame=20permet=20=C3=A0=20React=20de=20mettre=20=C3=A0?= =?UTF-8?q?=20jour=20l'=C3=A9tat,=20le=20second=20force=20le=20navigateur?= =?UTF-8?q?=20=C3=A0=20afficher=20visuellement=20l'animation=20avant=20de?= =?UTF-8?q?=20d=C3=A9marrer=20l'upload.=20D=C3=A9ploy=C3=A9=20sur=20le=20V?= =?UTF-8?q?PS=20de=20production.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/pages/AdminGestionAttestations.tsx | 83 ++++++++++--------- todo.md | 2 + 2 files changed, 44 insertions(+), 41 deletions(-) diff --git a/client/src/pages/AdminGestionAttestations.tsx b/client/src/pages/AdminGestionAttestations.tsx index af0eb83..647ea94 100644 --- a/client/src/pages/AdminGestionAttestations.tsx +++ b/client/src/pages/AdminGestionAttestations.tsx @@ -196,53 +196,54 @@ function UploadAttestationDialog({ return; } - // Forcer le rendu synchrone de l'interface AVANT de démarrer l'upload - flushSync(() => { - setUploading(true); - setUploadProgress(0); - }); + // Afficher immédiatement l'état de chargement + setUploading(true); + setUploadProgress(0); - // Démarrer l'upload de manière asynchrone - (async () => { - try { - const formData = new FormData(); - formData.append('file', file); + // Utiliser requestAnimationFrame pour garantir que le navigateur + // affiche l'animation AVANT de bloquer sur le fetch + requestAnimationFrame(() => { + requestAnimationFrame(async () => { + try { + const formData = new FormData(); + formData.append('file', file); - const progressInterval = setInterval(() => { - setUploadProgress(prev => { - if (prev >= 90) return prev; - return prev + 10; - }); - }, 200); + const progressInterval = setInterval(() => { + setUploadProgress(prev => { + if (prev >= 90) return prev; + return prev + 10; + }); + }, 200); - const response = await fetch('/api/upload-file', { - method: 'POST', - body: formData, - }); + const response = await fetch('/api/upload-file', { + method: 'POST', + body: formData, + }); - clearInterval(progressInterval); - setUploadProgress(100); + clearInterval(progressInterval); + setUploadProgress(100); - if (!response.ok) { - throw new Error('Erreur lors de l\'upload'); - } + if (!response.ok) { + throw new Error('Erreur lors de l\'upload'); + } - const data = await response.json(); - setFileData({ - nomFichier: file.name, - urlFichier: data.url, - s3Key: data.key, - typeFichier: file.type, - tailleFichier: file.size, - }); - toast.success('Fichier uploadé avec succès'); - } catch (error) { - toast.error('Erreur lors de l\'upload du fichier'); - setUploadProgress(0); - } finally { - setUploading(false); - } - })(); // Fermer et exécuter la fonction async + const data = await response.json(); + setFileData({ + nomFichier: file.name, + urlFichier: data.url, + s3Key: data.key, + typeFichier: file.type, + tailleFichier: file.size, + }); + toast.success('Fichier uploadé avec succès'); + } catch (error) { + toast.error('Erreur lors de l\'upload du fichier'); + setUploadProgress(0); + } finally { + setUploading(false); + } + }); // Fermer requestAnimationFrame interne + }); // Fermer requestAnimationFrame externe }} /> diff --git a/todo.md b/todo.md index 7be0528..fd297f4 100644 --- a/todo.md +++ b/todo.md @@ -1476,3 +1476,5 @@ - [x] Corriger la latence d'affichage du message d'upload (forcer le rendu avant traitement) - [x] Restructurer le flux d'upload avec useEffect pour affichage immédiat + +- [x] Corriger la latence avec requestAnimationFrame pour affichage avant fetch bloquant