feat: add styled PWA update modal with auto cache purge
This commit is contained in:
+30
-6
@@ -192,7 +192,8 @@ Toutes ces sources sont modifiables dans `includes/config.local.php` (voir <<fr-
|
||||
│ ├── search.js # Cartes cliquables de la recherche
|
||||
│ ├── mastodon-config.php # Configuration JS de la timeline (servie en JS)
|
||||
│ ├── mastodon-timeline.umd.js # mastodon-embed-timeline v4.7.0 (vendored)
|
||||
│ └── pleroma-adapter.js # Adaptateur Pleroma → API Mastodon
|
||||
│ ├── pleroma-adapter.js # Adaptateur Pleroma → API Mastodon
|
||||
│ └── pwa-update.js # Enregistrement SW + modal de mise à jour
|
||||
├── uploads/ # Images d'annonces (non versionné, hors .gitkeep)
|
||||
├── index.php # Page d'accueil (agrégateur)
|
||||
├── video.php # Page de lecture d'une vidéo
|
||||
@@ -806,7 +807,7 @@ WARNING: Le bloc `location ~* \.(php|inc|conf|config|local)$ { deny all; }` de l
|
||||
- 📲 *Installation native* : bouton « Installer » dans le header à la première visite
|
||||
- 🌐 *Mode hors ligne* : cache des pages visitées et des ressources statiques
|
||||
- 📡 *Détection de connexion* : indicateur visuel en cas de perte réseau
|
||||
- 🔄 *Mise à jour* : proposition de rechargement quand une nouvelle version est détectée
|
||||
- 🔄 *Mise à jour sans friction* : quand une nouvelle version est déployée, un modal stylé la propose ; en acceptant, l'utilisateur la reçoit immédiatement — *aucune purge manuelle du cache navigateur nécessaire*
|
||||
|
||||
==== Stratégies de cache du Service Worker (`sw.js`)
|
||||
|
||||
@@ -827,7 +828,18 @@ WARNING: Le bloc `location ~* \.(php|inc|conf|config|local)$ { deny all; }` de l
|
||||
| Jamais de cache ; réponse JSON 503 synthétique hors ligne
|
||||
|===
|
||||
|
||||
TIP: Pour déployer une nouvelle version des assets, changez le suffixe de version des noms de cache dans `sw.js` (format date, ex. `08072026-0720`) : les anciens caches sont supprimés à l'activation.
|
||||
==== Cycle de mise à jour automatique
|
||||
|
||||
Le mécanisme (`js/pwa-update.js` + `sw.js`) garantit que les visiteurs reçoivent les nouvelles versions *sans purger manuellement le cache de leur navigateur* :
|
||||
|
||||
. Au déploiement, *bumpez* le suffixe de version des noms de cache dans `sw.js` (format `JJMMAAAA-HHMM`, ex. `24072026-0612`)
|
||||
. Au chargement d'une page, le navigateur détecte le nouveau `sw.js` et installe le nouveau Service Worker en arrière-plan ; il reste *en attente* (pas de `skipWaiting()` automatique)
|
||||
. Un *modal* propose la mise à jour à l'utilisateur :
|
||||
* *« Mettre à jour »* → le SW en attente reçoit `SKIP_WAITING`, purge les anciens caches à l'activation, prend le contrôle (`controllerchange`) et la page se recharge sur la nouvelle version
|
||||
* *« Plus tard »* → le modal se ferme ; la mise à jour est reproposée au prochain chargement
|
||||
. Une mise à jour déjà installée lors d'une visite précédente mais jamais activée est également signalée
|
||||
|
||||
WARNING: Pour que la détection fonctionne, `sw.js` ne doit *pas* être caché longtemps côté serveur : les configurations fournies (`conf/nginx.conf.sample`, `conf/.htaccess.sample`) le servent en `no-cache` (ainsi que `site.webmanifest`). Si vous utilisez votre propre configuration serveur, reproduisez cette règle.
|
||||
|
||||
==== Installation par les visiteurs
|
||||
|
||||
@@ -1084,7 +1096,8 @@ All of these sources can be changed in `includes/config.local.php` (see <<en-con
|
||||
│ ├── search.js # Clickable search result cards
|
||||
│ ├── mastodon-config.php # Timeline JS config (served as JavaScript)
|
||||
│ ├── mastodon-timeline.umd.js # mastodon-embed-timeline v4.7.0 (vendored)
|
||||
│ └── pleroma-adapter.js # Pleroma → Mastodon API adapter
|
||||
│ ├── pleroma-adapter.js # Pleroma → Mastodon API adapter
|
||||
│ └── pwa-update.js # SW registration + update modal
|
||||
├── uploads/ # Announcement images (not versioned, except .gitkeep)
|
||||
├── index.php # Homepage (aggregator)
|
||||
├── video.php # Video playback page
|
||||
@@ -1698,7 +1711,7 @@ WARNING: The sample's `location ~* \.(php|inc|conf|config|local)$ { deny all; }`
|
||||
- 📲 *Native installation*: an "Install" button in the header on first visit
|
||||
- 🌐 *Offline mode*: visited pages and static assets cached
|
||||
- 📡 *Connection detection*: visual indicator when the network is lost
|
||||
- 🔄 *Updates*: reload prompt when a new version is detected
|
||||
- 🔄 *Frictionless updates*: when a new version is deployed, a styled modal offers it; on accept, the user gets it immediately — *no manual browser-cache purge needed*
|
||||
|
||||
==== Service Worker caching strategies (`sw.js`)
|
||||
|
||||
@@ -1719,7 +1732,18 @@ WARNING: The sample's `location ~* \.(php|inc|conf|config|local)$ { deny all; }`
|
||||
| Never cached; synthetic 503 JSON response when offline
|
||||
|===
|
||||
|
||||
TIP: To deploy a new version of the assets, change the version suffix of the cache names in `sw.js` (date format, e.g. `08072026-0720`): old caches are deleted on activation.
|
||||
==== Automatic update cycle
|
||||
|
||||
This mechanism (`js/pwa-update.js` + `sw.js`) ensures visitors receive new versions *without manually purging their browser cache*:
|
||||
|
||||
. When deploying, *bump* the version suffix of the cache names in `sw.js` (format `DDMMYYYY-HHMM`, e.g. `24072026-0612`)
|
||||
. On page load, the browser detects the new `sw.js` and installs the new Service Worker in the background; it stays *waiting* (no automatic `skipWaiting()`)
|
||||
. A *modal* offers the update to the user:
|
||||
* *"Mettre à jour"* → the waiting SW receives `SKIP_WAITING`, purges old caches on activation, takes control (`controllerchange`) and the page reloads onto the new version
|
||||
* *"Plus tard"* → the modal closes; the update is offered again on the next page load
|
||||
. An update already installed during a previous visit but never activated is also reported
|
||||
|
||||
WARNING: For detection to work, `sw.js` must *not* be cached for long by the server: the provided configurations (`conf/nginx.conf.sample`, `conf/.htaccess.sample`) serve it with `no-cache` (as well as `site.webmanifest`). If you use your own server configuration, reproduce this rule.
|
||||
|
||||
==== Installation by visitors
|
||||
|
||||
|
||||
@@ -168,5 +168,6 @@ if ($categoryId && isset($allCategories[$categoryId])) {
|
||||
|
||||
<script src="js/main.js"></script>
|
||||
<script src="js/categories.js"></script>
|
||||
<script src="js/pwa-update.js?v=<?php echo filemtime('js/pwa-update.js'); ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -55,3 +55,15 @@ RewriteRule ^([^/]+)$ $1.php [L]
|
||||
RewriteCond %{HTTP:X-Forwarded-Proto} !https
|
||||
RewriteCond %{HTTPS} !on
|
||||
RewriteRule ^(.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||
|
||||
# ======================
|
||||
# CACHE
|
||||
# ======================
|
||||
|
||||
# Le Service Worker et le manifest ne doivent pas être cachés longtemps :
|
||||
# le navigateur doit pouvoir détecter les nouvelles versions du site.
|
||||
<FilesMatch "^(sw\.js|site\.webmanifest)$">
|
||||
<IfModule mod_headers.c>
|
||||
Header set Cache-Control "no-cache, must-revalidate"
|
||||
</IfModule>
|
||||
</FilesMatch>
|
||||
|
||||
@@ -75,6 +75,18 @@ server {
|
||||
# OPTIMISATIONS
|
||||
# ======================
|
||||
|
||||
# Le Service Worker et le manifest ne doivent pas être cachés longtemps :
|
||||
# le navigateur doit pouvoir détecter les nouvelles versions du site.
|
||||
# (location exacte = prioritaire sur les regex ci-dessous ; "expires -1"
|
||||
# émet Cache-Control: no-cache sans annuler les add_header de sécurité)
|
||||
location = /sw.js {
|
||||
expires -1;
|
||||
}
|
||||
|
||||
location = /site.webmanifest {
|
||||
expires -1;
|
||||
}
|
||||
|
||||
# Cache des fichiers statiques
|
||||
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
|
||||
@@ -183,5 +183,6 @@ setSecurityHeaders();
|
||||
|
||||
<!-- Scripts -->
|
||||
<script src="js/countdown.js"></script>
|
||||
<script src="js/pwa-update.js?v=<?php echo filemtime('js/pwa-update.js'); ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
+115
-1
@@ -3411,4 +3411,118 @@ i.icon-mastodon,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ==========================================
|
||||
Modal de mise à jour PWA (js/pwa-update.js)
|
||||
========================================== */
|
||||
|
||||
.pwa-update-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background-color: rgba(0, 0, 0, 0.55);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
z-index: 10000;
|
||||
opacity: 0;
|
||||
transition: opacity 0.25s ease;
|
||||
}
|
||||
|
||||
.pwa-update-overlay.pwa-update-visible {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.pwa-update-modal {
|
||||
background-color: var(--card-bg);
|
||||
color: var(--text-color);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.35);
|
||||
max-width: 420px;
|
||||
width: 100%;
|
||||
padding: 28px 24px 24px;
|
||||
text-align: center;
|
||||
transform: translateY(12px) scale(0.97);
|
||||
transition: transform 0.25s ease;
|
||||
}
|
||||
|
||||
.pwa-update-visible .pwa-update-modal {
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
|
||||
.pwa-update-logo {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-radius: 50%;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.pwa-update-title {
|
||||
margin: 0 0 8px;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.pwa-update-text {
|
||||
margin: 0 0 20px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.pwa-update-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.pwa-update-btn {
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
padding: 10px 20px;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease, opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.pwa-update-btn:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: wait;
|
||||
}
|
||||
|
||||
.pwa-update-btn-primary {
|
||||
background-color: var(--primary-red);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.pwa-update-btn-primary:hover:not(:disabled) {
|
||||
filter: brightness(0.9);
|
||||
}
|
||||
|
||||
.pwa-update-btn-secondary {
|
||||
background-color: transparent;
|
||||
color: var(--text-color);
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.pwa-update-btn-secondary:hover:not(:disabled) {
|
||||
background-color: var(--hover-bg);
|
||||
}
|
||||
|
||||
.pwa-update-btn:focus-visible {
|
||||
outline: 2px solid var(--primary-red);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.pwa-update-actions {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.pwa-update-btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,5 +274,6 @@ $liveStream = getLiveStream();
|
||||
<?php include 'includes/footer.php'; ?>
|
||||
<?php include 'includes/mobile-menu.php'; ?>
|
||||
<script src="js/main.js"></script>
|
||||
<script src="js/pwa-update.js?v=<?php echo filemtime('js/pwa-update.js'); ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -291,5 +291,6 @@ $stripeMonthlyLinks = defined('STRIPE_MONTHLY_LINKS') ? STRIPE_MONTHLY_LINKS : [
|
||||
</script>
|
||||
|
||||
<script src="js/main.js"></script>
|
||||
<script src="js/pwa-update.js?v=<?php echo filemtime('js/pwa-update.js'); ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -678,34 +678,11 @@ setSecurityHeaders();
|
||||
<script src="js/mastodon-timeline.umd.js"></script>
|
||||
<script src="js/mastodon-config.php?v=<?php echo md5(MASTODON_INSTANCE_URL . MASTODON_DATE_FORMAT . MASTODON_BTN_SEE_MORE . MASTODON_BTN_RELOAD . MASTODON_MAX_POST_FETCH . MASTODON_MAX_POST_SHOW); ?>"></script>
|
||||
|
||||
<!-- PWA Service Worker -->
|
||||
<!-- PWA : enregistrement du Service Worker + modal de mise à jour -->
|
||||
<script src="js/pwa-update.js?v=<?php echo filemtime('js/pwa-update.js'); ?>"></script>
|
||||
|
||||
<!-- PWA : bouton d'installation -->
|
||||
<script nonce="<?php echo getCspNonce(); ?>">
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', function() {
|
||||
navigator.serviceWorker.register('/sw.js')
|
||||
.then(function(registration) {
|
||||
console.log('Service Worker enregistré avec succès:', registration.scope);
|
||||
|
||||
// Écouter les mises à jour
|
||||
registration.addEventListener('updatefound', function() {
|
||||
const newWorker = registration.installing;
|
||||
newWorker.addEventListener('statechange', function() {
|
||||
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
|
||||
// Nouvelle version disponible
|
||||
console.log('Nouvelle version disponible');
|
||||
if (confirm('Une nouvelle version est disponible. Voulez-vous recharger la page ?')) {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(function(err) {
|
||||
console.log('Échec de l\'enregistrement du Service Worker:', err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Gestion de l'installation PWA
|
||||
let deferredPrompt;
|
||||
const installButton = document.getElementById('install-pwa');
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* Enregistrement du Service Worker et gestion des mises à jour.
|
||||
*
|
||||
* Quand une nouvelle version du site est déployée (sw.js modifié, suffixe de
|
||||
* version des caches bumpé), le nouveau Service Worker s'installe en arrière-
|
||||
* plan et reste en attente. Un modal propose alors la mise à jour :
|
||||
* - « Mettre à jour » : le SW en attente prend le contrôle (SKIP_WAITING),
|
||||
* les anciens caches sont purgés à l'activation, puis la page se recharge
|
||||
* sur la nouvelle version (controllerchange).
|
||||
* - « Plus tard » : le modal se ferme ; la mise à jour sera reproposée au
|
||||
* prochain chargement de page.
|
||||
*
|
||||
* Aucune purge manuelle du cache navigateur n'est nécessaire.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
if (!('serviceWorker' in navigator)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let modalShown = false;
|
||||
let refreshing = false;
|
||||
|
||||
// Recharge la page quand le nouveau Service Worker prend le contrôle
|
||||
navigator.serviceWorker.addEventListener('controllerchange', function () {
|
||||
if (refreshing) {
|
||||
return;
|
||||
}
|
||||
refreshing = true;
|
||||
window.location.reload();
|
||||
});
|
||||
|
||||
/**
|
||||
* Construit et affiche le modal de mise à jour (une seule fois).
|
||||
* @param {ServiceWorker} waitingWorker Le SW en attente d'activation
|
||||
*/
|
||||
function showUpdateModal(waitingWorker) {
|
||||
if (modalShown || !waitingWorker) {
|
||||
return;
|
||||
}
|
||||
modalShown = true;
|
||||
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'pwa-update-overlay';
|
||||
overlay.setAttribute('role', 'dialog');
|
||||
overlay.setAttribute('aria-modal', 'true');
|
||||
overlay.setAttribute('aria-labelledby', 'pwa-update-title');
|
||||
overlay.innerHTML =
|
||||
'<div class="pwa-update-modal">' +
|
||||
'<img class="pwa-update-logo" src="img/logo.png" alt="" aria-hidden="true">' +
|
||||
'<h2 class="pwa-update-title" id="pwa-update-title">Nouvelle version disponible</h2>' +
|
||||
'<p class="pwa-update-text">' +
|
||||
'Une mise à jour du site est prête à être installée. ' +
|
||||
'Elle est rapide et ne supprime aucune de vos données.' +
|
||||
'</p>' +
|
||||
'<div class="pwa-update-actions">' +
|
||||
'<button type="button" class="pwa-update-btn pwa-update-btn-primary">' +
|
||||
'Mettre à jour' +
|
||||
'</button>' +
|
||||
'<button type="button" class="pwa-update-btn pwa-update-btn-secondary">' +
|
||||
'Plus tard' +
|
||||
'</button>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
|
||||
document.body.appendChild(overlay);
|
||||
|
||||
// Force le reflow pour que la transition CSS d'entrée joue
|
||||
void overlay.offsetWidth;
|
||||
overlay.classList.add('pwa-update-visible');
|
||||
|
||||
const primaryBtn = overlay.querySelector('.pwa-update-btn-primary');
|
||||
const secondaryBtn = overlay.querySelector('.pwa-update-btn-secondary');
|
||||
|
||||
function closeModal() {
|
||||
overlay.classList.remove('pwa-update-visible');
|
||||
overlay.addEventListener('transitionend', function () {
|
||||
overlay.remove();
|
||||
}, { once: true });
|
||||
}
|
||||
|
||||
primaryBtn.addEventListener('click', function () {
|
||||
primaryBtn.disabled = true;
|
||||
secondaryBtn.disabled = true;
|
||||
primaryBtn.textContent = 'Mise à jour…';
|
||||
// Le rechargement est déclenché par l'event controllerchange
|
||||
waitingWorker.postMessage({ type: 'SKIP_WAITING' });
|
||||
});
|
||||
|
||||
secondaryBtn.addEventListener('click', closeModal);
|
||||
|
||||
document.addEventListener('keydown', function onEscape(event) {
|
||||
if (event.key === 'Escape' && document.body.contains(overlay)) {
|
||||
closeModal();
|
||||
document.removeEventListener('keydown', onEscape);
|
||||
}
|
||||
});
|
||||
|
||||
// Accessibilité : focus sur l'action principale
|
||||
primaryBtn.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Surveille l'installation d'un nouveau Service Worker.
|
||||
* @param {ServiceWorkerRegistration} registration
|
||||
*/
|
||||
function trackInstalling(registration) {
|
||||
registration.addEventListener('updatefound', function () {
|
||||
const newWorker = registration.installing;
|
||||
if (!newWorker) {
|
||||
return;
|
||||
}
|
||||
newWorker.addEventListener('statechange', function () {
|
||||
// installed + un contrôleur actif = mise à jour en attente
|
||||
// (sans contrôleur, c'est la toute première installation)
|
||||
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
|
||||
showUpdateModal(registration.waiting);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('load', function () {
|
||||
navigator.serviceWorker.register('/sw.js')
|
||||
.then(function (registration) {
|
||||
// Cas où une mise à jour est déjà en attente (installée lors
|
||||
// d'une visite précédente, jamais activée)
|
||||
if (registration.waiting && navigator.serviceWorker.controller) {
|
||||
showUpdateModal(registration.waiting);
|
||||
}
|
||||
trackInstalling(registration);
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.log('Échec de l\'enregistrement du Service Worker:', err);
|
||||
});
|
||||
});
|
||||
})();
|
||||
@@ -243,5 +243,6 @@
|
||||
<?php include 'includes/footer.php'; ?>
|
||||
<?php include 'includes/mobile-menu.php'; ?>
|
||||
<script src="js/main.js"></script>
|
||||
<script src="js/pwa-update.js?v=<?php echo filemtime('js/pwa-update.js'); ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -261,5 +261,6 @@ if ($resultsCount > 0) {
|
||||
|
||||
<script src="js/main.js"></script>
|
||||
<script src="js/search.js"></script>
|
||||
<script src="js/pwa-update.js?v=<?php echo filemtime('js/pwa-update.js'); ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
const CACHE_NAME = 'fediverse-oki-08072026-0720';
|
||||
const STATIC_CACHE_NAME = 'fediverse-oki-static-08072026-0720';
|
||||
const DYNAMIC_CACHE_NAME = 'fediverse-oki-dynamic-08072026-0720';
|
||||
// Version du cache : à bumper à chaque déploiement (format JJMMAAAA-HHMM).
|
||||
// Tout changement de ce fichier déclenche l'installation d'un nouveau
|
||||
// Service Worker chez les visiteurs ; les anciens caches sont purgés à
|
||||
// l'activation (voir l'event 'activate' plus bas).
|
||||
const STATIC_CACHE_NAME = 'annu-kute-ced-static-24072026-0612';
|
||||
const DYNAMIC_CACHE_NAME = 'annu-kute-ced-dynamic-24072026-0612';
|
||||
|
||||
// Ressources à mettre en cache immédiatement
|
||||
const STATIC_ASSETS = [
|
||||
@@ -46,13 +49,15 @@ self.addEventListener('install', event => {
|
||||
console.log('Service Worker: Mise en cache des assets statiques');
|
||||
return cache.addAll(STATIC_ASSETS);
|
||||
})
|
||||
.then(() => {
|
||||
return self.skipWaiting();
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Service Worker: Erreur lors de la mise en cache:', err);
|
||||
})
|
||||
);
|
||||
// Note : pas de skipWaiting() ici. Lors d'une mise à jour, le nouveau SW
|
||||
// reste en attente jusqu'à ce que l'utilisateur accepte la mise à jour
|
||||
// via le modal (message SKIP_WAITING envoyé par js/pwa-update.js).
|
||||
// Lors de la toute première visite (aucun SW actif), l'activation est
|
||||
// immédiate.
|
||||
});
|
||||
|
||||
// Activation du Service Worker
|
||||
@@ -202,20 +207,10 @@ function isApiRequest(url) {
|
||||
url.includes('mastodon-config.php');
|
||||
}
|
||||
|
||||
// Gestion des messages du client
|
||||
// Gestion des messages du client : l'utilisateur a accepté la mise à jour,
|
||||
// le SW en attente prend le contrôle (purge des anciens caches à l'activation).
|
||||
self.addEventListener('message', event => {
|
||||
if (event.data && event.data.type === 'SKIP_WAITING') {
|
||||
self.skipWaiting();
|
||||
}
|
||||
});
|
||||
|
||||
// Notification de mise à jour
|
||||
self.addEventListener('message', event => {
|
||||
if (event.data && event.data.type === 'CHECK_UPDATE') {
|
||||
// Vérifier s'il y a une mise à jour
|
||||
event.ports[0].postMessage({
|
||||
type: 'UPDATE_AVAILABLE',
|
||||
version: CACHE_NAME
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user