feat: 📲 Install-Button in Topbar — umgeht Chrome Engagement-Heuristik
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 1s
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 1s
Chrome zeigt 'App installieren' im Menü erst nach mehrmaligem Besuch
mit User-Interaktion. Das ist die sog. Site-Engagement-Heuristik —
keine technische Voraussetzung, sondern UX-Gate.
Workaround: beforeinstallprompt-Event abfangen und manuell auslösen.
- 📲 Install-Button in Topbar (standardmäßig versteckt)
- Bei beforeinstallprompt: Event speichern, Button anzeigen
- Klick → prompt() aufrufen → Install-Dialog öffnet sich
- appinstalled-Event: Button wieder verstecken
- iOS-Fallback: Hinweis zum manuellen 'Zum Home-Bildschirm'
Damit ist die Install-Funktion jederzeit sichtbar und nutzbar,
unabhängig davon wie oft der User die Seite vorher besucht hat.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
[deploy]
This commit is contained in:
parent
7c9563ec90
commit
d19e4eb41e
1 changed files with 31 additions and 0 deletions
31
index.php
31
index.php
|
|
@ -42,6 +42,7 @@ header('Expires: 0');
|
||||||
<header id="topbar">
|
<header id="topbar">
|
||||||
<button id="back-btn" class="icon-btn" style="display:none">←</button>
|
<button id="back-btn" class="icon-btn" style="display:none">←</button>
|
||||||
<h1 id="page-title">Baustelle</h1>
|
<h1 id="page-title">Baustelle</h1>
|
||||||
|
<button id="install-btn" class="icon-btn" title="Als App installieren" style="display:none">📲</button>
|
||||||
<button id="help-btn" class="icon-btn" title="Hilfe">❓</button>
|
<button id="help-btn" class="icon-btn" title="Hilfe">❓</button>
|
||||||
<span id="status-badge">🟢</span>
|
<span id="status-badge">🟢</span>
|
||||||
</header>
|
</header>
|
||||||
|
|
@ -63,6 +64,36 @@ header('Expires: 0');
|
||||||
<script src="lib/router.js?v=<?php echo $jsVersion; ?>"></script>
|
<script src="lib/router.js?v=<?php echo $jsVersion; ?>"></script>
|
||||||
<script src="app.js?v=<?php echo $jsVersion; ?>"></script>
|
<script src="app.js?v=<?php echo $jsVersion; ?>"></script>
|
||||||
<script>
|
<script>
|
||||||
|
/* PWA Install Prompt abfangen */
|
||||||
|
let deferredInstallPrompt = null;
|
||||||
|
window.addEventListener('beforeinstallprompt', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
deferredInstallPrompt = e;
|
||||||
|
var btn = document.getElementById('install-btn');
|
||||||
|
if (btn) btn.style.display = '';
|
||||||
|
console.log('PWA: Install-Prompt ist verfügbar');
|
||||||
|
});
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
var btn = document.getElementById('install-btn');
|
||||||
|
if (btn) btn.addEventListener('click', async function () {
|
||||||
|
if (!deferredInstallPrompt) {
|
||||||
|
alert('Installation nicht verfügbar. Falls du die App bereits installiert hast, öffne sie über das Home-Screen-Icon.\n\nAuf iPhone: Safari → Teilen → "Zum Home-Bildschirm".');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
deferredInstallPrompt.prompt();
|
||||||
|
var choice = await deferredInstallPrompt.userChoice;
|
||||||
|
if (choice.outcome === 'accepted') {
|
||||||
|
btn.style.display = 'none';
|
||||||
|
}
|
||||||
|
deferredInstallPrompt = null;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
window.addEventListener('appinstalled', function () {
|
||||||
|
var btn = document.getElementById('install-btn');
|
||||||
|
if (btn) btn.style.display = 'none';
|
||||||
|
console.log('PWA: Installation abgeschlossen');
|
||||||
|
});
|
||||||
|
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
window.addEventListener('load', function () {
|
window.addEventListener('load', function () {
|
||||||
navigator.serviceWorker.register('sw.js?v=<?php echo $swVersion; ?>').then(function (reg) {
|
navigator.serviceWorker.register('sw.js?v=<?php echo $swVersion; ?>').then(function (reg) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue