// src/pwaInstall.js /** * Détecte si l'application est déjà installée et lancée en mode PWA */ export function isRunningAsPWA() { // Vérifie si l'app est en mode standalone (PWA installé) if (window.matchMedia('(display-mode: standalone)').matches) { return true; } // Vérifie navigator.standalone (iOS) if (window.navigator.standalone === true) { return true; } // Vérifie si lancé depuis un raccourci installé if (document.referrer.includes('android-app://')) { return true; } return false; } let deferredPrompt = null; let promptShown = false; let iosHintShown = false; function isIOS() { if (typeof navigator === "undefined") return false; const ua = navigator.userAgent || ""; const iOSDevice = /iphone|ipad|ipod/i.test(ua); const iPadOS = ua.includes("Mac") && "ontouchend" in document; return iOSDevice || iPadOS; } function isSafari() { if (typeof navigator === "undefined") return false; const ua = navigator.userAgent || ""; const isIOSChrome = /crios/i.test(ua); const isIOSFirefox = /fxios/i.test(ua); const isIOSEdge = /edgios/i.test(ua); const isSafariUA = /safari/i.test(ua); return isSafariUA && !isIOSChrome && !isIOSFirefox && !isIOSEdge; } function showIOSInstallHint() { if (iosHintShown) return; iosHintShown = true; alert( "iOS: pour installer l'app, ouvre le menu Partager (icône carré + flèche), puis choisis “Sur l’écran d’accueil”." ); } // Écoute l'événement d'installation (le navigateur ne fire que si PAS installé) window.addEventListener('beforeinstallprompt', (e) => { if (isRunningAsPWA()) { console.log('Already running as PWA, skipping install prompt'); return; } e.preventDefault(); deferredPrompt = e; console.log('PWA install prompt ready - waiting for manual click'); }); // Écoute l'événement quand l'app est installée window.addEventListener('appinstalled', () => { console.log('PWA was installed'); deferredPrompt = null; }); /** * Affiche le prompt d'installation */ function showInstallPrompt() { if (!deferredPrompt || promptShown || isRunningAsPWA()) { return; } deferredPrompt.prompt(); promptShown = true; deferredPrompt.userChoice.then((choice) => { console.log('Install outcome:', choice.outcome); deferredPrompt = null; }); } /** * Fonction exportée pour déclencher manuellement l'installation * IMPORTANT: Le clic manuel ignore promptShown pour permettre de réessayer */ export function promptInstall() { if (isRunningAsPWA()) { console.log('Already running as PWA, no need to install'); alert('App is already installed!'); return false; } if (isIOS() && isSafari()) { showIOSInstallHint(); return true; } if (deferredPrompt) { // Clic manuel - force l'affichage même si déjà montré console.log('Showing install prompt (manual trigger)'); deferredPrompt.prompt(); deferredPrompt.userChoice.then((choice) => { console.log('Install outcome:', choice.outcome); deferredPrompt = null; }); return true; } else { console.log('No install prompt available - browser may not support PWA install or already installed'); if (isIOS() && isSafari()) { showIOSInstallHint(); return true; } alert('PWA installation not available. Make sure you are using a supported browser (Chrome, Edge, Safari).'); return false; } } /** * Vérifie si le prompt d'installation est disponible * Le navigateur gère automatiquement: beforeinstallprompt ne fire que si PAS installé */ export function canInstall() { if (isRunningAsPWA()) return false; if (isIOS() && isSafari()) return true; return deferredPrompt !== null; }