(function(root, factory) { if (typeof module === 'object' && module.exports) module.exports = factory; else root.createPushNotifications = factory; })(typeof self !== 'undefined' ? self : this, function createPushNotifications({ control, status, notification, serviceWorker, fetchJson, }) { let configuration = null; function applicationServerKey(value) { const padded = value.replace(/-/g, '+').replace(/_/g, '/') + '='.repeat((4 - value.length % 4) % 4); if (typeof atob === 'function') { return Uint8Array.from(atob(padded), character => character.charCodeAt(0)); } return Uint8Array.from(Buffer.from(padded, 'base64')); } async function disable() { const registration = await serviceWorker.ready; const subscription = await registration.pushManager.getSubscription(); await fetchJson('api/v1/push-subscription', {method:'DELETE'}); await subscription?.unsubscribe?.(); control.checked = false; status.textContent = 'New update notifications are off for this device.'; } async function enable() { const permission = await notification.requestPermission(); if (permission !== 'granted') { control.checked = false; status.textContent = 'Notifications are blocked. Allow them in your browser settings to enable updates.'; return; } const registration = await serviceWorker.ready; let subscription = await registration.pushManager.getSubscription(); if (!subscription) { subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: applicationServerKey(configuration.public_key), }); } await fetchJson('api/v1/push-subscription', { method:'PUT', headers:{'Content-Type':'application/json'}, body:JSON.stringify(subscription.toJSON()), }); control.checked = true; status.textContent = 'New update notifications enabled for this device.'; } async function change() { control.disabled = true; try { if (control.checked) await enable(); else await disable(); } catch (error) { control.checked = !control.checked; status.textContent = 'Could not change update notifications. Check your connection and try again.'; } finally { control.disabled = false; } } async function init() { if (!control || !notification || !serviceWorker) return; control.addEventListener('change', change); configuration = await fetchJson('api/v1/push-subscription'); if (!configuration.available) { control.disabled = true; status.textContent = 'New update notifications are not available on this server.'; return; } control.checked = Boolean(configuration.subscribed); status.textContent = configuration.subscribed ? 'New update notifications enabled for this device.' : 'New update notifications are off for this device.'; } return {init, change}; });