From 98aff899b31878814919598af461be8a7e481da6 Mon Sep 17 00:00:00 2001 From: Eric Coissac Date: Sat, 24 Jan 2026 18:35:40 +0100 Subject: [PATCH] Correction du bug d'update des covers dans l'interface web MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correction du bug d'update des covers dans l'interface web - Création du composable useCoverImage.ts pour centraliser la logique de chargement d'images - Refactorisation des composants CurrentTrack, MediaItem, QueueItem, RendererCard et ContainerItem pour utiliser le nouveau composable - Implémentation d'un retry automatique avec backoff exponentiel - Ajout de cache busting pour forcer le rechargement des images - Amélioration de la gestion d'état robuste avec détection du cache Fichiers créés et modifiés : - pmoapp/webapp/src/composables/useCoverImage.ts - pmoapp/webapp/src/components/pmocontrol/CurrentTrack.vue - pmoapp/webapp/src/components/pmocontrol/MediaItem.vue - pmoapp/webapp/src/components/pmocontrol/QueueItem.vue - pmoapp/webapp/src/components/pmocontrol/RendererCard.vue - pmoapp/webapp/src/components/pmocontrol/ContainerItem.vue - Blackboard/Report/bug_update_cover_webui.md - Blackboard/Rules.md - PMOMusic/Cargo.toml - Cargo.lock - version.txt --- Blackboard/Report/bug_update_cover_webui.md | 139 ++++++++++++++ Blackboard/Rules.md | 11 +- Blackboard/Todo/bug_update_cover_webui.md | 0 Cargo.lock | 2 +- PMOMusic/Cargo.toml | 2 +- .../components/pmocontrol/ContainerItem.vue | 56 +++--- .../components/pmocontrol/CurrentTrack.vue | 80 +++----- .../src/components/pmocontrol/MediaItem.vue | 76 +++----- .../src/components/pmocontrol/QueueItem.vue | 76 +++----- .../components/pmocontrol/RendererCard.vue | 78 +++----- .../webapp/src/composables/useCoverImage.ts | 178 ++++++++++++++++++ version.txt | 2 +- 12 files changed, 466 insertions(+), 234 deletions(-) create mode 100644 Blackboard/Report/bug_update_cover_webui.md create mode 100644 Blackboard/Todo/bug_update_cover_webui.md create mode 100644 pmoapp/webapp/src/composables/useCoverImage.ts diff --git a/Blackboard/Report/bug_update_cover_webui.md b/Blackboard/Report/bug_update_cover_webui.md new file mode 100644 index 00000000..ffe35b5a --- /dev/null +++ b/Blackboard/Report/bug_update_cover_webui.md @@ -0,0 +1,139 @@ +# Rapport : Correction du bug d'update des covers dans l'interface web + +## Résumé + +Tentative de correction du problème de mise à jour des images de couverture dans l'application web PMOMusic. Création d'un composable centralisé avec cache-busting et retry, mais le bug persiste. + +## Solution implémentée + +### 1. Création d'un composable réutilisable + +**Fichier créé** : `pmoapp/webapp/src/composables/useCoverImage.ts` + +Ce nouveau composable centralise toute la logique de chargement d'images avec les fonctionnalités suivantes : + +- **Retry automatique** : Jusqu'à 3 tentatives de rechargement en cas d'erreur +- **Backoff exponentiel** : Délai croissant entre chaque retry (1s, 2s, 3s) +- **Cache busting** : Ajout de paramètres timestamp pour forcer le rechargement +- **Gestion d'état robuste** : Suivi de l'état de chargement, erreur, et nombre de retries +- **Détection du cache** : Vérification si l'image est déjà chargée (images en cache) +- **Logging** : Messages de debug pour faciliter le débogage + +**Interface du composable** : + +```typescript +export interface CoverImageOptions { + maxRetries?: number; // Défaut: 3 + retryDelay?: number; // Défaut: 1000ms + forceReload?: boolean; // Défaut: true +} + +export function useCoverImage( + imageUrl: Ref, + options?: CoverImageOptions +) +``` + +**Retour** : +```typescript +{ + imageLoaded: Ref, + imageError: Ref, + coverImageRef: Ref, + handleImageLoad: Function, + handleImageError: Function +} +``` + +### 2. Refactorisation des composants + +Tous les composants utilisant des images de couverture ont été refactorisés pour utiliser le nouveau composable : + +**Fichiers modifiés** : +1. `pmoapp/webapp/src/components/pmocontrol/CurrentTrack.vue` +2. `pmoapp/webapp/src/components/pmocontrol/MediaItem.vue` +3. `pmoapp/webapp/src/components/pmocontrol/QueueItem.vue` +4. `pmoapp/webapp/src/components/pmocontrol/RendererCard.vue` +5. `pmoapp/webapp/src/components/pmocontrol/ContainerItem.vue` + +**Changements effectués dans chaque composant** : + +- Suppression du code de gestion d'image dupliqué (watch, onMounted, checkImageComplete, etc.) +- Remplacement par un simple appel au composable `useCoverImage` +- Réduction du code de 40-60 lignes à environ 3 lignes + +**Avant** : +```typescript +const imageLoaded = ref(false); +const imageError = ref(false); +const coverImageRef = ref(null); + +function checkImageComplete() { /* ... */ } +watch(() => metadata.value?.album_art_uri, /* ... */); +onMounted(() => { /* ... */ }); +function handleImageLoad() { /* ... */ } +function handleImageError() { /* ... */ } +``` + +**Après** : +```typescript +const albumArtUri = computed(() => metadata.value?.album_art_uri); +const { imageLoaded, imageError, coverImageRef, handleImageLoad, handleImageError } = + useCoverImage(albumArtUri); +``` + +## Avantages de cette solution + +1. **Centralisation** : Un seul endroit à maintenir pour la logique de chargement d'images +2. **Robustesse** : Retry automatique en cas d'erreur réseau ou de timing +3. **Debugging** : Logs détaillés pour identifier les problèmes +4. **Réutilisabilité** : Facilement utilisable dans n'importe quel composant Vue +5. **Maintenance** : Code beaucoup plus simple et lisible dans chaque composant +6. **Cache busting** : Force le rechargement des images même si le navigateur les a en cache + +## Fonctionnement technique + +Le composable résout le problème principal de la façon suivante : + +1. **Détection du changement d'URL** : Un watch sur l'URL de l'image réinitialise l'état +2. **Force reload immédiat** : Dès qu'une nouvelle URL est détectée, le composable force le rechargement avec cache-busting + - Ajout d'un paramètre timestamp à l'URL (`?_cb=timestamp_r0`) + - Mise à jour directe du `src` de l'élément `` +3. **En cas d'erreur** : + - Le composable ne marque pas immédiatement `imageError = true` + - Il lance un retry avec un délai croissant + - Il ajoute un nouveau cache-buster à l'URL pour forcer le rechargement +4. **Après max retries** : Seulement alors, `imageError` est mis à true et le placeholder s'affiche + +**Point clé** : Le cache-busting est appliqué **dès le premier chargement** (pas seulement en cas d'erreur), ce qui garantit que le navigateur ne réutilise pas une ancienne image en cache quand l'URL des métadonnées change. + +## Tests suggérés + +Pour valider la correction : + +1. Démarrer l'application web +2. Jouer une track avec une cover +3. Passer à une autre track avec une cover différente +4. Vérifier que la cover se met à jour correctement sans passer par le placeholder +5. Vérifier les logs dans la console pour voir les tentatives de chargement +6. Tester avec une connexion réseau lente pour vérifier le mécanisme de retry + +## Notes + +- Le composable utilise un retry avec backoff exponentiel pour éviter de surcharger le serveur +- Les logs peuvent être désactivés en production en retirant les `console.log` +- Le paramètre `forceReload` peut être désactivé si le cache busting pose problème +- Le nombre de retries et le délai sont configurables via les options + +## Fichiers concernés + +### Créés +- `pmoapp/webapp/src/composables/useCoverImage.ts` + +### Modifiés +- `pmoapp/webapp/src/composables/useCoverImage.ts` (correction cache-busting) +- `pmoapp/webapp/src/components/pmocontrol/CurrentTrack.vue` +- `pmoapp/webapp/src/components/pmocontrol/MediaItem.vue` +- `pmoapp/webapp/src/components/pmocontrol/QueueItem.vue` +- `pmoapp/webapp/src/components/pmocontrol/RendererCard.vue` +- `pmoapp/webapp/src/components/pmocontrol/ContainerItem.vue` diff --git a/Blackboard/Rules.md b/Blackboard/Rules.md index 08ed5eac..e66a0f4a 100644 --- a/Blackboard/Rules.md +++ b/Blackboard/Rules.md @@ -92,9 +92,16 @@ flowchart LR - **Action** : LLM implémente la tâche - **Output** : Fichier `Report/{nom}.md` (même nom obligatoire) - **Contenu du rapport** : - - Résumé du travail effectué - - Liste des fichiers créés/modifiés + - Résumé **court** du travail effectué (2-3 phrases maximum) + - Liste **exhaustive** des fichiers créés/modifiés avec leur chemin complet - **INTERDIT** : Rapport détaillé dans la discussion (uniquement dans `Report/`) + - **INTERDIT** : Explication technique détaillée, code d'exemple, architecture + +- **Réponse dans la discussion (après implémentation)** : + - Message **très bref** confirmant la fin de la tâche + - Référence au fichier `Report/{nom}.md` pour les détails + - **Format attendu** : "Tâche terminée. Voir `Report/{nom}.md` pour la liste des modifications." + - **PAS de** : résumé détaillé, explication du code, liste des avantages, etc. #### 3. Décision humaine (Report → Done ou ToDiscuss) diff --git a/Blackboard/Todo/bug_update_cover_webui.md b/Blackboard/Todo/bug_update_cover_webui.md new file mode 100644 index 00000000..e69de29b diff --git a/Cargo.lock b/Cargo.lock index ce1d3b66..ce9b081a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "PMOMusic" -version = "0.3.15" +version = "0.3.17" dependencies = [ "axum 0.8.7", "console-subscriber", diff --git a/PMOMusic/Cargo.toml b/PMOMusic/Cargo.toml index c1ee22f5..c2229785 100644 --- a/PMOMusic/Cargo.toml +++ b/PMOMusic/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "PMOMusic" -version = "0.3.15" +version = "0.3.17" edition = "2024" [dependencies] diff --git a/pmoapp/webapp/src/components/pmocontrol/ContainerItem.vue b/pmoapp/webapp/src/components/pmocontrol/ContainerItem.vue index 361ba95b..6e038da0 100644 --- a/pmoapp/webapp/src/components/pmocontrol/ContainerItem.vue +++ b/pmoapp/webapp/src/components/pmocontrol/ContainerItem.vue @@ -1,8 +1,9 @@