test
This commit is contained in:
@@ -1,132 +1,245 @@
|
||||
// Enregistrement du Service Worker
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', function() {
|
||||
// S'assurer que nous sommes sur HTTPS en production
|
||||
if (location.protocol === 'https:' || location.hostname === 'localhost') {
|
||||
navigator.serviceWorker.register('/service-worker.js')
|
||||
.then(function(registration) {
|
||||
console.log('[Service Worker] Enregistré avec succès:', registration.scope);
|
||||
// Enregistrement du Service Worker amélioré
|
||||
(function() {
|
||||
// Vérifier si le Service Worker est supporté
|
||||
if (!('serviceWorker' in navigator)) {
|
||||
console.warn('[App] Service Worker non supporté');
|
||||
return;
|
||||
}
|
||||
|
||||
// Vérifier si nous sommes en HTTPS ou localhost
|
||||
if (window.location.protocol !== 'https:' && window.location.hostname !== 'localhost') {
|
||||
console.warn('[App] Service Worker nécessite HTTPS en production');
|
||||
return;
|
||||
}
|
||||
|
||||
// Fonction principale d'enregistrement
|
||||
function registerServiceWorker() {
|
||||
const swUrl = '/service-worker.js?v=1.1';
|
||||
|
||||
navigator.serviceWorker.register(swUrl)
|
||||
.then(function(registration) {
|
||||
console.log('[Service Worker] Enregistré avec succès:', registration.scope);
|
||||
|
||||
// Vérifier si une mise à jour est disponible
|
||||
registration.addEventListener('updatefound', function() {
|
||||
const installingWorker = registration.installing;
|
||||
console.log('[Service Worker] Mise à jour trouvée:', installingWorker.state);
|
||||
|
||||
// Vérifier les mises à jour
|
||||
registration.addEventListener('updatefound', () => {
|
||||
const newWorker = registration.installing;
|
||||
console.log('[Service Worker] Mise à jour trouvée:', newWorker.state);
|
||||
installingWorker.addEventListener('statechange', function() {
|
||||
console.log('[Service Worker] Nouvel état:', this.state);
|
||||
|
||||
newWorker.addEventListener('statechange', () => {
|
||||
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
|
||||
// Nouvelle version disponible
|
||||
console.log('[Service Worker] Nouvelle version disponible');
|
||||
this.showUpdateNotification();
|
||||
}
|
||||
});
|
||||
if (this.state === 'installed' && navigator.serviceWorker.controller) {
|
||||
// Nouvelle version disponible
|
||||
showUpdateNotification();
|
||||
}
|
||||
|
||||
if (this.state === 'activated') {
|
||||
console.log('[Service Worker] Nouveau Service Worker activé');
|
||||
// Notifier tous les clients
|
||||
sendMessageToSW({ type: 'NEW_VERSION_ACTIVATED' });
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.error('[Service Worker] Échec de l\'enregistrement:', error);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Gestion hors ligne
|
||||
window.addEventListener('online', () => {
|
||||
document.documentElement.classList.remove('offline');
|
||||
console.log('[App] Connexion rétablie');
|
||||
this.showOnlineNotification();
|
||||
});
|
||||
|
||||
window.addEventListener('offline', () => {
|
||||
document.documentElement.classList.add('offline');
|
||||
console.log('[App] Mode hors ligne');
|
||||
this.showOfflineNotification();
|
||||
});
|
||||
}
|
||||
|
||||
// Notification de mise à jour
|
||||
function showUpdateNotification() {
|
||||
if (window.appConfig?.isAnglophone) {
|
||||
if (confirm('A new version is available. Reload the page?')) {
|
||||
window.location.reload();
|
||||
}
|
||||
} else {
|
||||
if (confirm('Une nouvelle version est disponible. Recharger la page?')) {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Notification en ligne
|
||||
function showOnlineNotification() {
|
||||
// Créer une notification toast
|
||||
const toast = document.createElement('div');
|
||||
toast.className = 'position-fixed top-0 end-0 p-3';
|
||||
toast.style.zIndex = '9999';
|
||||
|
||||
toast.innerHTML = `
|
||||
<div class="toast show" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header bg-success text-white">
|
||||
<i class="bi bi-wifi me-2"></i>
|
||||
<strong class="me-auto">${window.appConfig?.isAnglophone ? 'Online' : 'En ligne'}</strong>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
${window.appConfig?.isAnglophone
|
||||
? 'Connection restored. Synchronization in progress...'
|
||||
: 'Connexion rétablie. Synchronisation en cours...'}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.appendChild(toast);
|
||||
|
||||
// Supprimer après 3 secondes
|
||||
setTimeout(() => {
|
||||
toast.remove();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
// Notification hors ligne
|
||||
function showOfflineNotification() {
|
||||
// Créer une notification toast
|
||||
const toast = document.createElement('div');
|
||||
toast.className = 'position-fixed top-0 end-0 p-3';
|
||||
toast.style.zIndex = '9999';
|
||||
|
||||
toast.innerHTML = `
|
||||
<div class="toast show" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header bg-warning text-dark">
|
||||
<i class="bi bi-wifi-off me-2"></i>
|
||||
<strong class="me-auto">${window.appConfig?.isAnglophone ? 'Offline' : 'Hors ligne'}</strong>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
${window.appConfig?.isAnglophone
|
||||
? 'No internet connection. Working in offline mode.'
|
||||
: 'Pas de connexion Internet. Mode hors ligne actif.'}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.appendChild(toast);
|
||||
|
||||
// Supprimer après 5 secondes
|
||||
setTimeout(() => {
|
||||
toast.remove();
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
// Fonction pour forcer la mise à jour du Service Worker
|
||||
function updateServiceWorker() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.update().then(() => {
|
||||
console.log('[Service Worker] Mise à jour forcée');
|
||||
|
||||
// Vérifier l'état du Service Worker périodiquement
|
||||
setInterval(() => {
|
||||
registration.update().catch(err => {
|
||||
console.debug('[SW] Pas de mise à jour disponible:', err);
|
||||
});
|
||||
}, 60 * 60 * 1000); // Toutes les heures
|
||||
|
||||
return registration;
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.error('[Service Worker] Erreur d\'enregistrement:', error);
|
||||
|
||||
// Tentative de récupération
|
||||
if (error.name === 'SecurityError') {
|
||||
console.warn('[SW] Erreur de sécurité - Vérifiez HTTPS');
|
||||
} else if (error.name === 'TypeError') {
|
||||
console.warn('[SW] Erreur de type - Vérifiez le chemin du SW');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Exporter pour une utilisation externe
|
||||
window.serviceWorker = {
|
||||
update: updateServiceWorker,
|
||||
isSupported: 'serviceWorker' in navigator
|
||||
};
|
||||
|
||||
// Gestion de l'état de connexion
|
||||
function setupConnectionHandlers() {
|
||||
window.addEventListener('online', function() {
|
||||
console.log('[App] Connexion rétablie');
|
||||
document.documentElement.classList.remove('offline');
|
||||
showOnlineNotification();
|
||||
|
||||
// Synchroniser les données
|
||||
if (navigator.serviceWorker.controller) {
|
||||
sendMessageToSW({ type: 'SYNC_DATA' });
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('offline', function() {
|
||||
console.log('[App] Mode hors ligne');
|
||||
document.documentElement.classList.add('offline');
|
||||
showOfflineNotification();
|
||||
});
|
||||
|
||||
// Vérifier l'état initial
|
||||
if (!navigator.onLine) {
|
||||
document.documentElement.classList.add('offline');
|
||||
}
|
||||
}
|
||||
|
||||
// Notification de mise à jour
|
||||
function showUpdateNotification() {
|
||||
const isAnglophone = window.appConfig?.isAnglophone || false;
|
||||
|
||||
// Utiliser SweetAlert2 si disponible
|
||||
if (typeof Swal !== 'undefined') {
|
||||
Swal.fire({
|
||||
title: isAnglophone ? 'Update Available' : 'Mise à jour disponible',
|
||||
text: isAnglophone
|
||||
? 'A new version is available. Reload to update?'
|
||||
: 'Une nouvelle version est disponible. Recharger pour mettre à jour ?',
|
||||
icon: 'info',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: isAnglophone ? 'Reload' : 'Recharger',
|
||||
cancelButtonText: isAnglophone ? 'Later' : 'Plus tard',
|
||||
allowOutsideClick: false
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Fallback simple
|
||||
if (confirm(isAnglophone
|
||||
? 'New version available. Reload?'
|
||||
: 'Nouvelle version disponible. Recharger ?')) {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Notification en ligne
|
||||
function showOnlineNotification() {
|
||||
// Créer un toast temporaire
|
||||
const toast = document.createElement('div');
|
||||
toast.className = 'position-fixed top-0 end-0 p-3';
|
||||
toast.style.zIndex = '9999';
|
||||
|
||||
const isAnglophone = window.appConfig?.isAnglophone || false;
|
||||
|
||||
toast.innerHTML = `
|
||||
<div class="toast show" role="alert" aria-live="polite" aria-atomic="true">
|
||||
<div class="toast-header bg-success text-white">
|
||||
<i class="bi bi-wifi me-2"></i>
|
||||
<strong class="me-auto">${isAnglophone ? 'Online' : 'En ligne'}</strong>
|
||||
<button type="button" class="btn-close btn-close-white ms-2"
|
||||
onclick="this.closest('.toast').remove()"
|
||||
aria-label="${isAnglophone ? 'Close' : 'Fermer'}"></button>
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
${isAnglophone
|
||||
? 'Connection restored. Data will be synchronized.'
|
||||
: 'Connexion rétablie. Les données seront synchronisées.'}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.appendChild(toast);
|
||||
|
||||
// Auto-remove après 3 secondes
|
||||
setTimeout(() => {
|
||||
if (toast.parentNode) {
|
||||
toast.remove();
|
||||
}
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
// Notification hors ligne
|
||||
function showOfflineNotification() {
|
||||
// Créer un toast temporaire
|
||||
const toast = document.createElement('div');
|
||||
toast.className = 'position-fixed top-0 end-0 p-3';
|
||||
toast.style.zIndex = '9999';
|
||||
|
||||
const isAnglophone = window.appConfig?.isAnglophone || false;
|
||||
|
||||
toast.innerHTML = `
|
||||
<div class="toast show" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header bg-warning text-dark">
|
||||
<i class="bi bi-wifi-off me-2"></i>
|
||||
<strong class="me-auto">${isAnglophone ? 'Offline' : 'Hors ligne'}</strong>
|
||||
<button type="button" class="btn-close ms-2"
|
||||
onclick="this.closest('.toast').remove()"
|
||||
aria-label="${isAnglophone ? 'Close' : 'Fermer'}"></button>
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
${isAnglophone
|
||||
? 'No internet connection. Working in offline mode.'
|
||||
: 'Pas de connexion Internet. Mode hors ligne actif.'}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.appendChild(toast);
|
||||
|
||||
// Auto-remove après 5 secondes
|
||||
setTimeout(() => {
|
||||
if (toast.parentNode) {
|
||||
toast.remove();
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
// Envoyer un message au Service Worker
|
||||
function sendMessageToSW(message) {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
navigator.serviceWorker.controller.postMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
// Obtenir l'état du cache
|
||||
function getCacheStatus() {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
const messageChannel = new MessageChannel();
|
||||
|
||||
messageChannel.port1.onmessage = function(event) {
|
||||
console.log('[SW] Cache status:', event.data);
|
||||
};
|
||||
|
||||
navigator.serviceWorker.controller.postMessage(
|
||||
{ type: 'GET_CACHE_STATUS' },
|
||||
[messageChannel.port2]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Fonction publique pour forcer la mise à jour
|
||||
function forceUpdate() {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
navigator.serviceWorker.controller.postMessage({ type: 'SKIP_WAITING' });
|
||||
}
|
||||
}
|
||||
|
||||
// Initialiser quand la page est prête
|
||||
window.addEventListener('load', function() {
|
||||
registerServiceWorker();
|
||||
setupConnectionHandlers();
|
||||
|
||||
// Ajouter les écouteurs de visibilité pour les rafraîchissements
|
||||
document.addEventListener('visibilitychange', function() {
|
||||
if (!document.hidden && navigator.serviceWorker.controller) {
|
||||
navigator.serviceWorker.controller.postMessage({ type: 'PAGE_VISIBLE' });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Exposer les fonctions publiques
|
||||
window.serviceWorkerManager = {
|
||||
forceUpdate: forceUpdate,
|
||||
getCacheStatus: getCacheStatus,
|
||||
isSupported: 'serviceWorker' in navigator,
|
||||
sendMessage: sendMessageToSW
|
||||
};
|
||||
|
||||
console.log('[App] Service Worker Manager initialisé');
|
||||
})();
|
||||
Reference in New Issue
Block a user