Add install prompt button for PWA
This commit is contained in:
parent
0a74d8cef1
commit
4f3f32e915
@ -19,6 +19,7 @@ const modal = document.getElementById('modalOverlay');
|
|||||||
const modalInput = document.getElementById('modalInput');
|
const modalInput = document.getElementById('modalInput');
|
||||||
const modalTitle = document.getElementById('modalTitle');
|
const modalTitle = document.getElementById('modalTitle');
|
||||||
const hapticTick = () => { if ('vibrate' in navigator) navigator.vibrate(12); };
|
const hapticTick = () => { if ('vibrate' in navigator) navigator.vibrate(12); };
|
||||||
|
const installBtn = document.getElementById('installBtn');
|
||||||
|
|
||||||
// --- Service Worker ---
|
// --- Service Worker ---
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
@ -29,6 +30,42 @@ if ('serviceWorker' in navigator) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Install Prompt ---
|
||||||
|
let deferredInstallPrompt = null;
|
||||||
|
const isStandalone = () =>
|
||||||
|
window.matchMedia('(display-mode: standalone)').matches ||
|
||||||
|
window.navigator.standalone === true;
|
||||||
|
|
||||||
|
function hideInstall() {
|
||||||
|
if (installBtn) installBtn.classList.add('hidden');
|
||||||
|
}
|
||||||
|
function showInstall() {
|
||||||
|
if (installBtn) installBtn.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('beforeinstallprompt', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
deferredInstallPrompt = e;
|
||||||
|
if (!isStandalone()) showInstall();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('appinstalled', () => {
|
||||||
|
deferredInstallPrompt = null;
|
||||||
|
hideInstall();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (installBtn) {
|
||||||
|
installBtn.addEventListener('click', async () => {
|
||||||
|
if (!deferredInstallPrompt) return;
|
||||||
|
deferredInstallPrompt.prompt();
|
||||||
|
const choice = await deferredInstallPrompt.userChoice;
|
||||||
|
if (choice.outcome === 'accepted') hideInstall();
|
||||||
|
deferredInstallPrompt = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isStandalone()) hideInstall();
|
||||||
|
|
||||||
// --- Sweet-ish Alerts ---
|
// --- Sweet-ish Alerts ---
|
||||||
function removeSwal() {
|
function removeSwal() {
|
||||||
const existing = document.querySelector('.swal-overlay');
|
const existing = document.querySelector('.swal-overlay');
|
||||||
|
|||||||
@ -116,6 +116,7 @@ h1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header-btn.is-active { background: var(--header-text); color: var(--header-bg); }
|
.header-btn.is-active { background: var(--header-text); color: var(--header-bg); }
|
||||||
|
.hidden { display: none !important; }
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
max-width: 650px;
|
max-width: 650px;
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
<h1>Toadstool Tally</h1>
|
<h1>Toadstool Tally</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-controls">
|
<div class="header-controls">
|
||||||
|
<button class="header-btn hidden" id="installBtn" title="Install app">⬇️</button>
|
||||||
<button class="header-btn" id="themeBtn" onclick="toggleTheme()" title="Toggle Dark Mode">🌓</button>
|
<button class="header-btn" id="themeBtn" onclick="toggleTheme()" title="Toggle Dark Mode">🌓</button>
|
||||||
<button class="header-btn" id="focusBtn" onclick="toggleFocusMode()" title="Focus Mode (Keeps Screen On)">👁️</button>
|
<button class="header-btn" id="focusBtn" onclick="toggleFocusMode()" title="Focus Mode (Keeps Screen On)">👁️</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user