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
@@ -13,7 +13,11 @@
|
||||
|
||||
const NOM_BASE = 'mabibli';
|
||||
const MAGASIN = 'instantanes';
|
||||
const VERSION = 1;
|
||||
// Couvertures mises en cache (A5, IDEES.md) : magasin séparé, clé = l'URL OpenLibrary,
|
||||
// valeur = le Blob de l'image. Sert uniquement à la consultation hors-ligne — en ligne,
|
||||
// l'<img> normale reste la voie rapide, ce cache se remplit en tâche de fond à côté.
|
||||
const MAGASIN_COUVERTURES = 'couvertures';
|
||||
const VERSION = 2;
|
||||
|
||||
let promesseBase = null;
|
||||
|
||||
@@ -29,6 +33,7 @@ function ouvrir() {
|
||||
requete.onupgradeneeded = () => {
|
||||
const base = requete.result;
|
||||
if (!base.objectStoreNames.contains(MAGASIN)) base.createObjectStore(MAGASIN);
|
||||
if (!base.objectStoreNames.contains(MAGASIN_COUVERTURES)) base.createObjectStore(MAGASIN_COUVERTURES);
|
||||
};
|
||||
requete.onsuccess = () => resoudre(requete.result);
|
||||
requete.onerror = () => rejeter(requete.error);
|
||||
@@ -84,3 +89,45 @@ export function surveiller(reference) {
|
||||
self.addEventListener('offline', prevenir);
|
||||
return navigator.onLine !== false;
|
||||
}
|
||||
|
||||
// --- Couvertures (A5, IDEES.md) ---
|
||||
//
|
||||
// En ligne, l'<img> normale reste la voie d'affichage : rien ici ne doit la ralentir. Cette
|
||||
// fonction tourne en tâche de fond, appelée sans attendre son résultat (fire-and-forget) après
|
||||
// qu'une couverture s'est affichée avec succès. Le second fetch profite en général du cache HTTP
|
||||
// du navigateur (même URL que l'<img>) : pas de second téléchargement réel dans le cas courant.
|
||||
//
|
||||
// OpenLibrary envoie `Access-Control-Allow-Origin: *` (vérifié) : un fetch cross-origin normal
|
||||
// suffit, pas besoin du contournement `no-cors`/réponse opaque.
|
||||
export async function couvertureMettreEnCache(url) {
|
||||
try {
|
||||
const base = await ouvrir();
|
||||
const tx = base.transaction(MAGASIN_COUVERTURES, 'readonly');
|
||||
const existe = await attendre(tx.objectStore(MAGASIN_COUVERTURES).getKey(url), tx);
|
||||
if (existe !== undefined) return; // Déjà en cache : pas de re-téléchargement.
|
||||
|
||||
const reponse = await fetch(url, { cache: 'force-cache' });
|
||||
if (!reponse.ok) return; // 404/502 intermittent (CLAUDE.md) : rien à ranger.
|
||||
|
||||
const blob = await reponse.blob();
|
||||
const ecriture = base.transaction(MAGASIN_COUVERTURES, 'readwrite');
|
||||
await attendre(ecriture.objectStore(MAGASIN_COUVERTURES).put(blob, url), ecriture);
|
||||
} catch (e) {
|
||||
// Quota dépassé, stockage refusé : une couverture non mise en cache reste un
|
||||
// agrément perdu, jamais une raison de faire échouer l'affichage en ligne.
|
||||
}
|
||||
}
|
||||
|
||||
// Renvoie une URL d'objet (`blob:`) utilisable comme `src`, ou `null` si cette couverture n'a
|
||||
// jamais été mise en cache — c'est alors à l'appelant de retomber sur l'URL réseau (qui échouera
|
||||
// simplement si hors-ligne, exactement comme aujourd'hui).
|
||||
export async function couvertureLire(url) {
|
||||
try {
|
||||
const base = await ouvrir();
|
||||
const tx = base.transaction(MAGASIN_COUVERTURES, 'readonly');
|
||||
const blob = await attendre(tx.objectStore(MAGASIN_COUVERTURES).get(url), tx);
|
||||
return blob ? URL.createObjectURL(blob) : null;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user