Fix PWA: hide install prompt when already installed or running as PWA

- Add isRunningAsPWA() detection (standalone mode, iOS, Android)
- Add localStorage tracking to remember installation state
- Skip prompt if already running as PWA or previously installed
- Increase auto-prompt delay from 5s to 10s for better UX
- Export canInstall() to check installation availability
- Mark as installed when appinstalled event fires

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Your Name 2025-12-23 15:03:09 -05:00
parent 290e713796
commit 6d94b6ac12
1 changed files with 110 additions and 17 deletions

View File

@ -1,34 +1,127 @@
// src/pwaInstall.js
let deferredPrompt = null;
let promptShown = false; // Flag pour n'afficher qu'une fois
/**
* 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;
}
/**
* Vérifie si l'installation a déjà été faite (localStorage)
*/
function isAlreadyInstalled() {
try {
return localStorage.getItem('pwa-installed') === 'true';
} catch {
return false;
}
}
/**
* Marque l'app comme installée dans localStorage
*/
function markAsInstalled() {
try {
localStorage.setItem('pwa-installed', 'true');
} catch (e) {
console.warn('Could not save PWA install state:', e);
}
}
let deferredPrompt = null;
let promptShown = false;
// Écoute l'événement d'installation
window.addEventListener('beforeinstallprompt', (e) => {
// Ne rien faire si déjà en mode PWA
if (isRunningAsPWA()) {
console.log('Already running as PWA, skipping install prompt');
return;
}
// Ne rien faire si déjà installé
if (isAlreadyInstalled()) {
console.log('PWA already installed, skipping prompt');
return;
}
e.preventDefault();
deferredPrompt = e;
console.log('PWA install prompt ready');
// Affiche le prompt automatiquement après 5 secondes (une seule fois)
// Affiche le prompt automatiquement après 10 secondes (une seule fois)
// Délai augmenté pour ne pas déranger immédiatement
setTimeout(() => {
if (!promptShown && deferredPrompt) {
deferredPrompt.prompt();
promptShown = true;
deferredPrompt.userChoice.then((choice) => {
console.log('Install outcome:', choice.outcome);
deferredPrompt = null;
});
if (!promptShown && deferredPrompt && !isRunningAsPWA()) {
showInstallPrompt();
}
}, 5000); // 5000 ms = 5 secondes
}, 10000); // 10 secondes
});
export function promptInstall() {
if (deferredPrompt && !promptShown) {
// Écoute l'événement quand l'app est installée
window.addEventListener('appinstalled', () => {
console.log('PWA was installed');
markAsInstalled();
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);
if (choice.outcome === 'accepted') {
markAsInstalled();
}
deferredPrompt = null;
});
}
/**
* Fonction exportée pour déclencher manuellement l'installation
*/
export function promptInstall() {
if (isRunningAsPWA()) {
console.log('Already running as PWA, no need to install');
return false;
}
if (deferredPrompt && !promptShown) {
showInstallPrompt();
return true;
} else {
console.log('No install prompt available or already shown');
return false;
}
}
/**
* Vérifie si le prompt d'installation est disponible
*/
export function canInstall() {
return !isRunningAsPWA() && !isAlreadyInstalled() && deferredPrompt !== null;
}