Traiter le lot A d'IDEES.md : CSS onglets, pastilles, identité visuelle, couverture cassée, cache couvertures
- A1 : forcer la revalidation HTTP (Cache-Control: no-cache) sur les fichiers statiques, pour empêcher un navigateur de garder indéfiniment un CSS/JS périmé quand le service worker ne s'active pas. - A2 : le filtre du catalogue (statut, type de document) reprend les mêmes pastilles colorées que les cartes (Libelles.ClasseStatut / nouvelle Libelles.ClasseTypeDocument). - A3 : remplacement du logo par défaut de Blazor par un pictogramme de livre ouvert (favicon, icônes PWA, logo du bandeau, logo mabibli_ynh). - A4 : une couverture cassée désactive aussi son bouton d'agrandissement. - A5 : cache IndexedDB des couvertures pour la consultation hors-ligne, sans ralentir l'affichage en ligne (mise en cache en tâche de fond). L'allègement (redimensionnement, WebP) reste hors scope, à mesurer avant de s'y engager. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
Copilot
parent
ce58294fd1
commit
5d45eb492e
@@ -1684,6 +1684,88 @@ extérieur ou par Échap. Le calque est focalisé à l'ouverture (`FocusAsync`)
|
||||
**Le substitut à initiale n'est jamais cliquable** : le bouton déclencheur n'est rendu que
|
||||
lorsqu'une URL de couverture existe. Sans couverture, il n'y a rien à agrandir.
|
||||
|
||||
## Habillage — retours d'usage du 2026-08-19 traités (2026-08-20)
|
||||
|
||||
Lot A d'IDEES.md (4ᵉ série). Quatre items traités ; le cinquième (allègement des couvertures,
|
||||
WebP) reste volontairement hors scope, voir plus bas.
|
||||
|
||||
### A1 : ce n'était pas un bug de style, mais l'absence de revalidation HTTP
|
||||
|
||||
Les six onglets s'affichaient parfois en liens bruts, sans aucune règle de
|
||||
`MainLayout.razor.css`. Cause retenue : `UseStaticFiles()` ne posait **aucun** en-tête
|
||||
`Cache-Control` — un navigateur peut donc garder `MaBibli.Client.styles.css` en cache
|
||||
heuristique, **indépendamment du service worker**. Le service worker revalide bien via
|
||||
`cache: 'no-cache'`, mais seulement quand il parvient à s'activer, ce qui n'est pas garanti
|
||||
(voir « Le service worker ne s'enregistre pas… »).
|
||||
|
||||
**Correction** : `Program.cs` pose désormais `Cache-Control: no-cache, must-revalidate` sur tous
|
||||
les fichiers statiques (`StaticFileOptions.OnPrepareResponse`). Les empreintes WASM étant
|
||||
désactivées (noms de fichiers stables, voir plus haut), c'est cette revalidation forcée qui
|
||||
empêche un navigateur de servir indéfiniment une version périmée — le service worker reste une
|
||||
seconde ligne de défense, pas la seule.
|
||||
|
||||
⚠️ `no-cache` ne veut pas dire « ne jamais mettre en cache » : ETag et Last-Modified, déjà posés
|
||||
par défaut par `StaticFileMiddleware`, permettent une revalidation conditionnelle (304) sans
|
||||
retélécharger un fichier inchangé.
|
||||
|
||||
### A2 : le filtre reprend les pastilles de couleur des cartes
|
||||
|
||||
Le filtre du catalogue (statut de lecture, type de document) affichait des segments neutres,
|
||||
alors que `ChoixStatut` (statut personnel sur la fiche) colorait déjà ses segments avec
|
||||
`Libelles.ClasseStatut`. Les segments et l'étiquette de la carte reprennent maintenant la même
|
||||
classe — le filtre statut réutilise `ClasseStatut`, et une nouvelle méthode
|
||||
`Libelles.ClasseTypeDocument` (bleu pour Roman, magenta pour BD, aucune couleur pour
|
||||
« Non précisé », qui n'est pas une valeur choisie) est appliquée aux deux endroits : le segment
|
||||
du filtre et l'étiquette `etiquette-type` de la carte. Le formulaire de saisie reprend la même
|
||||
classe, pour ne pas diverger une troisième fois.
|
||||
|
||||
### A3 : une identité visuelle, encore le logo par défaut de Blazor
|
||||
|
||||
`favicon.png` / `icon-192.png` / `icon-512.png` étaient encore le logo « @ » violet du template
|
||||
`dotnet new blazorwasm`. Remplacés par un pictogramme de livre ouvert (deux pages en V, tranche
|
||||
centrale blanche), dans le bleu d'accent existant (`#1b3a5c`) — généré par script (Pillow), pas
|
||||
par un outil de génération d'images IA, pour rester un simple dessin géométrique. Un petit
|
||||
`logo-bandeau.svg` (blanc, net à toute résolution) accompagne « MaBibli » dans le bandeau.
|
||||
`mabibli_ynh/logo.png` (256×256, fond transparent — convention du catalogue d'applications
|
||||
YunoHost) reprend le même dessin.
|
||||
|
||||
### A4 : une couverture cassée ne doit plus rien pouvoir agrandir
|
||||
|
||||
Le `onerror` masquait déjà l'image (`image-cassee`), mais le bouton `.couverture-declencheur`
|
||||
qui l'enveloppe restait cliquable : cliquer une vignette cassée ouvrait quand même le calque
|
||||
d'agrandissement, avec la même image cassée dedans. Le `onerror` désactive maintenant aussi ce
|
||||
bouton (`this.closest('.couverture-declencheur').disabled = true`), et `:disabled` porte un
|
||||
curseur neutre plutôt que `zoom-in`.
|
||||
|
||||
### A5 : les couvertures se mettent en cache pour la consultation hors-ligne
|
||||
|
||||
Nouveau magasin IndexedDB `couvertures` (clé = URL OpenLibrary, valeur = `Blob`), à côté du
|
||||
magasin `instantanes` existant — `cache-hors-ligne.js` passe en version 2.
|
||||
|
||||
⚠️ **En ligne, l'affichage ne change pas** : `<img src>` pointe directement sur l'URL réseau,
|
||||
aussi vite qu'avant. La mise en cache (`Cache.MettreEnCacheCouvertureAsync`) est un
|
||||
fire-and-forget déclenché en parallèle, jamais attendu — elle ne doit rien à la rapidité
|
||||
d'affichage. Le fetch qu'elle déclenche profite en général du cache HTTP du navigateur (même URL
|
||||
que l'`<img>` déjà chargée), donc pas de second téléchargement réel dans le cas courant.
|
||||
|
||||
**Hors ligne**, `Couverture.razor` tente d'abord `Cache.LireCouvertureCacheeAsync` (URL `blob:`
|
||||
via `URL.createObjectURL`) et ne retombe sur l'URL réseau — qui échouera simplement, comme avant
|
||||
cette fonctionnalité — que si rien n'a été mis en cache.
|
||||
|
||||
⚠️ **Le jeton de résolution compare `(Url, EnLigne)`, pas seulement `Url`** : passer en ligne →
|
||||
hors ligne sans que l'URL change (le cas le plus courant, puisqu'on ne change pas de livre en
|
||||
perdant le réseau) est précisément le cas qui aurait été raté avec une mémoïsation sur la seule
|
||||
URL — la couverture serait restée invisible hors-ligne malgré un cache rempli.
|
||||
|
||||
**Vérifié** : OpenLibrary envoie `Access-Control-Allow-Origin: *` (mesuré via `curl -I`), donc un
|
||||
`fetch()` cross-origin ordinaire suffit pour lire les octets — pas besoin d'un contournement en
|
||||
réponse opaque (`mode: 'no-cors'`).
|
||||
|
||||
**Ce qui n'est délibérément pas fait** : l'allègement (redimensionner à la taille réellement
|
||||
affichée, convertir en WebP). IDEES.md posait la question à mesurer avant de s'y engager, même
|
||||
règle que pour l'AOT WASM — non fait tant que la taille du cache image n'a pas montré de
|
||||
problème réel en usage.
|
||||
|
||||
## Installation YunoHost — éprouvée en production le 2026-08-18
|
||||
|
||||
Le paquet vit dans le dépôt `mabibli_ynh` (voir « Deux dépôts distincts »). Installé,
|
||||
|
||||
Reference in New Issue
Block a user