Sichtbarer "App installieren"-Knopf statt versteckter Browser-Funktion

Nutzer-Report: "ich kann sie immer noch nicht runter laden" -- Manifest +
Service Worker reichen technisch fuer Installierbarkeit, aber ohne
sichtbaren Knopf muss man wissen, dass Chrome/Edge das Adressleisten-
Symbol/3-Punkte-Meny dafuer versteckt. Jetzt: echter Knopf im Footer
("Als App installieren", jede Seite) und in der Verwaltung-Session-Leiste
("Als eigene App installieren"), nutzt beforeinstallprompt + prompt() --
loest pro Seite automatisch mit GENAU dem Manifest aus, das diese Seite
selbst verlinkt (index.html -> manifest.json, verwaltung.html ->
manifest-verwaltung.json), kein Sonderfall-Code noetig. Bleibt unsichtbar,
wenn der Browser das nicht unterstuetzt (Safari/iOS) oder die Seite schon
als App laeuft.

Ausserdem: eigener apple-mobile-web-app-title fuer verwaltung.html
("DogiCrew-Verwaltung" statt generisch "DogFather" beim iOS-Home-Bildschirm).

Cache-Busting-Version (?v=) erneut hochgezaehlt (20260820 -> 20260820b),
da main.js sich durch diese Aenderung erneut geaendert hat.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-08-20 19:30:42 +02:00
co-authored by Claude Opus 5
parent 4173e43c78
commit 7099d80491
36 changed files with 279 additions and 232 deletions
+45
View File
@@ -138,6 +138,7 @@
pt: "© {jahr} DogFather Universe. Team Dogi é família 🩵",
},
footer_impressum: { de: "Impressum & Datenschutz", "de-CH": "Impressum & Datenschutz", en: "Legal notice & privacy", fr: "Mentions légales et confidentialité", pt: "Aviso legal e privacidade" },
footer_app_installieren: { de: "Als App installieren", "de-CH": "Als App installiere", en: "Install as app", fr: "Installer comme application", pt: "Instalar como aplicativo" },
music_title: { de: "Musik von Team Dogi 🎵", "de-CH": "Musig vo Team Dogi 🎵", en: "Music from Team Dogi 🎵", fr: "Musique de Team Dogi 🎵", pt: "Música do Team Dogi 🎵" },
music_close_aria: { de: "Musik-Feld schließen", "de-CH": "Musig-Feld zuemache", en: "Close music panel", fr: "Fermer le panneau musique", pt: "Fechar painel de música" },
music_intro: {
@@ -570,6 +571,7 @@
<p class="small" style="margin-top:.8rem;max-width:32ch;">
${t("footer_tagline")}
</p>
<button type="button" id="pwa-install-btn" class="btn btn-outline" style="display:none;margin-top:1rem;">📲 ${t("footer_app_installieren")}</button>
</div>
<div>
<h4>DogFather</h4>
@@ -1145,4 +1147,47 @@
appleTitel.content = "DogFather";
document.head.appendChild(appleTitel);
}
/* ===================================================================
PWA: sichtbarer "App installieren"-Knopf (20.08.2026)
Nutzer-Wunsch: "ich kann sie immer noch nicht runter laden" — reine
Installierbarkeit über Manifest+Service-Worker reicht nicht, wenn
niemand weiß, WO im Browser man das anklickt (verstecktes
Adressleisten-Symbol/3-Punkte-Menü). Jede Seite mit einem Element
#pwa-install-btn (siehe renderFooter() oben + verwaltung.html) bekommt
jetzt einen echten, sichtbaren Knopf, der den nativen Install-Dialog
direkt auslöst — funktioniert pro Seite mit GENAU dem Manifest, das
diese Seite selbst verlinkt (index.html -> manifest.json,
verwaltung.html -> manifest-verwaltung.json), ganz ohne Sonderfall-Code
hier. Zeigt sich NUR, wenn der Browser das überhaupt unterstützt UND
die Seite nicht schon als installierte App läuft (Safari/iOS feuert
"beforeinstallprompt" nie — dort bleibt "Zum Home-Bildschirm" über das
Teilen-Menü weiterhin der einzige Weg, das ist eine Apple-Plattform-
Grenze, kein Bug dieser Seite). */
let installEvent = null;
const laeuftSchonAlsApp = () =>
window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true;
window.addEventListener("beforeinstallprompt", (e) => {
e.preventDefault();
installEvent = e;
const btn = document.getElementById("pwa-install-btn");
if (btn && !laeuftSchonAlsApp()) btn.style.display = "";
});
document.addEventListener("click", (e) => {
if (e.target.closest && e.target.closest("#pwa-install-btn") && installEvent) {
installEvent.prompt();
installEvent.userChoice.finally(() => {
installEvent = null;
const btn = document.getElementById("pwa-install-btn");
if (btn) btn.style.display = "none";
});
}
});
window.addEventListener("appinstalled", () => {
const btn = document.getElementById("pwa-install-btn");
if (btn) btn.style.display = "none";
});
})();