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:
parent
290e713796
commit
6d94b6ac12
|
|
@ -1,34 +1,127 @@
|
||||||
// src/pwaInstall.js
|
// 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) => {
|
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();
|
e.preventDefault();
|
||||||
deferredPrompt = e;
|
deferredPrompt = e;
|
||||||
console.log('PWA install prompt ready');
|
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(() => {
|
setTimeout(() => {
|
||||||
if (!promptShown && deferredPrompt) {
|
if (!promptShown && deferredPrompt && !isRunningAsPWA()) {
|
||||||
deferredPrompt.prompt();
|
showInstallPrompt();
|
||||||
promptShown = true;
|
|
||||||
deferredPrompt.userChoice.then((choice) => {
|
|
||||||
console.log('Install outcome:', choice.outcome);
|
|
||||||
deferredPrompt = null;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, 5000); // 5000 ms = 5 secondes
|
}, 10000); // 10 secondes
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// É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() {
|
export function promptInstall() {
|
||||||
|
if (isRunningAsPWA()) {
|
||||||
|
console.log('Already running as PWA, no need to install');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (deferredPrompt && !promptShown) {
|
if (deferredPrompt && !promptShown) {
|
||||||
deferredPrompt.prompt();
|
showInstallPrompt();
|
||||||
promptShown = true;
|
return true;
|
||||||
deferredPrompt.userChoice.then((choice) => {
|
|
||||||
console.log('Install outcome:', choice.outcome);
|
|
||||||
deferredPrompt = null;
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
console.log('No install prompt available or already shown');
|
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;
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue