feat: delay install prompt until 2 interactions, reduce dismiss to 7 days

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ulas
2026-03-30 17:30:05 +02:00
parent 168cd387b4
commit 4eacba2edd
+33 -3
View File
@@ -7,11 +7,15 @@
* - Chrome/Android: Fängt beforeinstallprompt ab, zeigt Install-Banner * - Chrome/Android: Fängt beforeinstallprompt ab, zeigt Install-Banner
* - iOS (Safari): Zeigt Anleitung "Zum Home-Bildschirm" * - iOS (Safari): Zeigt Anleitung "Zum Home-Bildschirm"
* - Standalone-Modus: Zeigt nichts an * - Standalone-Modus: Zeigt nichts an
* - Dismiss: 30 Tage via localStorage gespeichert * - Dismiss: 7 Tage via localStorage gespeichert
* - Timing: Banner erst nach 2 Nutzer-Interaktionen anzeigen
*/ */
const DISMISS_KEY = 'oikos-install-dismissed'; const DISMISS_KEY = 'oikos-install-dismissed';
const DISMISS_DURATION_MS = 30 * 24 * 60 * 60 * 1000; // 30 Tage const DISMISS_DURATION_MS = 7 * 24 * 60 * 60 * 1000; // 7 Tage
const INTERACTION_KEY = 'oikos-install-interactions';
const INTERACTION_THRESHOLD = 2;
class OikosInstallPrompt extends HTMLElement { class OikosInstallPrompt extends HTMLElement {
constructor() { constructor() {
@@ -35,6 +39,13 @@ class OikosInstallPrompt extends HTMLElement {
return; return;
} }
// Noch nicht genug Interaktionen
const interactions = Number(localStorage.getItem(INTERACTION_KEY) || '0');
if (interactions < INTERACTION_THRESHOLD) {
this._waitForInteractions();
return;
}
if (this._isIOS()) { if (this._isIOS()) {
this._showIOSPrompt(); this._showIOSPrompt();
} else { } else {
@@ -44,6 +55,25 @@ class OikosInstallPrompt extends HTMLElement {
disconnectedCallback() { disconnectedCallback() {
window.removeEventListener('beforeinstallprompt', this._onBeforeInstall); window.removeEventListener('beforeinstallprompt', this._onBeforeInstall);
if (this._offInteraction) this._offInteraction();
}
_waitForInteractions() {
const onInteraction = () => {
const count = Number(localStorage.getItem(INTERACTION_KEY) || '0') + 1;
localStorage.setItem(INTERACTION_KEY, String(count));
if (count >= INTERACTION_THRESHOLD) {
document.removeEventListener('click', onInteraction);
if (this._isIOS()) {
this._showIOSPrompt();
} else {
this._listenForInstallPrompt();
}
}
};
document.addEventListener('click', onInteraction);
this._offInteraction = () => document.removeEventListener('click', onInteraction);
} }
/** iOS Safari erkennen (kein beforeinstallprompt-Support) */ /** iOS Safari erkennen (kein beforeinstallprompt-Support) */
@@ -307,7 +337,7 @@ class OikosInstallPrompt extends HTMLElement {
this._deferredPrompt = null; this._deferredPrompt = null;
} }
/** Dismiss: 30 Tage merken, Banner entfernen */ /** Dismiss: 7 Tage merken, Banner entfernen */
_dismiss() { _dismiss() {
localStorage.setItem(DISMISS_KEY, String(Date.now())); localStorage.setItem(DISMISS_KEY, String(Date.now()));
this._remove(); this._remove();