172 lines
4.4 KiB
JavaScript
172 lines
4.4 KiB
JavaScript
// 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;
|
||
}
|
||
|
||
/**
|
||
* 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;
|
||
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
|
||
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 - waiting for manual click');
|
||
// Pas de prompt automatique - l'utilisateur cliquera sur le bouton s'il veut installer
|
||
});
|
||
|
||
// É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
|
||
* 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);
|
||
if (choice.outcome === 'accepted') {
|
||
markAsInstalled();
|
||
}
|
||
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
|
||
*/
|
||
export function canInstall() {
|
||
if (isRunningAsPWA() || isAlreadyInstalled()) return false;
|
||
if (isIOS() && isSafari()) return true;
|
||
return deferredPrompt !== null;
|
||
}
|