/** * InstallPrompt.tsx — X3: PWA install banner * Appare dopo 45s di uso cumulativo. Android: "Installa" button. * iOS Safari: istruzioni "Condividi → Aggiungi a schermata Home". * Dismissable permanente via localStorage. */ import { useState, useEffect, useRef } from "react"; import { Z_INDEX } from "@/lib/zindex"; import { getCapabilities } from "@/lib/capabilities"; const DISMISSED_KEY = "pwa_install_dismissed_v1"; const USAGE_KEY = "pwa_usage_seconds"; export default function InstallPrompt() { const [show, setShow] = useState(false); const [isIos, setIsIos] = useState(false); const deferredRef = useRef(null); useEffect(() => { try { const caps = getCapabilities(); if (caps.isStandalone) return; if (localStorage.getItem(DISMISSED_KEY)) return; setIsIos(!!(caps.isIos && caps.isSafari)); const handler = (e: Event) => { e.preventDefault(); deferredRef.current = e; }; window.addEventListener("beforeinstallprompt", handler); const prev = parseInt(localStorage.getItem(USAGE_KEY) ?? "0", 10); const start = Date.now(); const tick = setInterval(() => { const elapsed = Math.floor((Date.now() - start) / 1000) + prev; localStorage.setItem(USAGE_KEY, String(elapsed)); if (elapsed >= 45) { setShow(true); clearInterval(tick); } }, 5000); return () => { window.removeEventListener("beforeinstallprompt", handler); clearInterval(tick); }; } catch { /* non-blocking */ } return undefined; }, []); if (!show) return null; const dismiss = () => { setShow(false); try { localStorage.setItem(DISMISSED_KEY, "1"); } catch { /* */ } }; const install = async () => { if (deferredRef.current) { try { await deferredRef.current.prompt(); const { outcome } = await deferredRef.current.userChoice; if (outcome === "accepted") dismiss(); } catch { /* user dismissed */ } } }; return (
Installa l'app
{isIos ? 'Tocca Condividi → "Aggiungi a schermata Home"' : "Accesso rapido, funziona offline"}
{!isIos && ( )}
); }