Files
notifications/public/index.html
T
2026-06-02 23:00:35 +10:00

113 lines
4.3 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Notification + Push test</title>
<style>
body { font-family: system-ui, sans-serif; max-width: 32rem; margin: 2rem auto; padding: 0 1rem; line-height: 1.5; }
button { display: block; width: 100%; padding: .9rem; margin: .6rem 0; font-size: 1rem; border: 1px solid #999; border-radius: .5rem; background: #f5f5f5; }
button:active { background: #e5e5e5; }
h2 { margin-top: 1.5rem; font-size: 1rem; color: #555; border-bottom: 1px solid #ddd; padding-bottom: .25rem; }
#status { padding: .75rem; border-radius: .5rem; background: #eef; white-space: pre-wrap; font-size: .9rem; }
code { background: #eee; padding: 0 .25rem; border-radius: .25rem; }
</style>
</head>
<body>
<h1>Notification + Push test</h1>
<h2>Local (page open)</h2>
<button id="register">1. Register service worker</button>
<button id="permission">2. Request permission</button>
<button id="notify">3. Fire a local notification</button>
<h2>Push (server-sent, works with tab closed)</h2>
<button id="subscribe">4. Subscribe to push</button>
<button id="sendTest">5. Ask server to push now</button>
<div id="status">Status will appear here.</div>
<script>
const statusEl = document.getElementById('status');
function log(msg) {
statusEl.textContent = msg + '\n\n' +
'Permission: ' + Notification.permission + '\n' +
'SW controller: ' + (navigator.serviceWorker.controller ? 'yes' : 'no');
}
// VAPID public key arrives base64url-encoded; the browser needs a Uint8Array.
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
const raw = atob(base64);
return Uint8Array.from([...raw].map(c => c.charCodeAt(0)));
}
document.getElementById('register').addEventListener('click', async () => {
if (!('serviceWorker' in navigator)) return log('No service worker support.');
try {
await navigator.serviceWorker.register('sw.js');
await navigator.serviceWorker.ready;
log('Service worker registered and ready.');
} catch (e) {
log('Registration failed: ' + e);
}
});
document.getElementById('permission').addEventListener('click', async () => {
const result = await Notification.requestPermission();
log('Permission result: ' + result);
});
document.getElementById('notify').addEventListener('click', async () => {
if (Notification.permission !== 'granted') return log('Permission not granted yet (run step 2).');
const reg = await navigator.serviceWorker.ready; // Android Chrome needs the SW, not new Notification()
await reg.showNotification('OGLAS trough alert!', {
body: 'Trough 21 appears to be empty',
icon: '/sh3d/icon.svg',
badge: 'https://dummyimage.com/96x96/333/fff.png&text=!',
vibrate: [120, 60, 120],
tag: 'test', renotify: true,
actions: [ { action: 'open', title: 'Open' }, { action: 'dismiss', title: 'Dismiss' } ]
});
log('Local notification fired.');
});
document.getElementById('subscribe').addEventListener('click', async () => {
if (Notification.permission !== 'granted') return log('Grant permission first (step 2).');
try {
const reg = await navigator.serviceWorker.ready;
const key = await (await fetch('/sh3d/api/vapidPublicKey')).text();
const sub = await reg.pushManager.subscribe({
userVisibleOnly: true, // required on Chrome
applicationServerKey: urlBase64ToUint8Array(key)
});
await fetch('/sh3d/api/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(sub)
});
log('Subscribed and sent subscription to server.');
} catch (e) {
log('Subscribe failed: ' + e);
}
});
document.getElementById('sendTest').addEventListener('click', async () => {
try {
const res = await fetch('/sh3d/api/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'Server push', body: 'If you see this, the loop works.' })
});
const data = await res.json();
log('Server reports sent to ' + data.sent + ' subscription(s).\nNow background the tab and send again to prove it works closed.');
} catch (e) {
log('Send request failed: ' + e);
}
});
</script>
</body>
</html>