diff --git a/templates/base.html b/templates/base.html index 4ee4f2c..0d5ba58 100644 --- a/templates/base.html +++ b/templates/base.html @@ -229,6 +229,21 @@ + {% include "components/confirm_modal.html" %} {% include "components/toast_container.html" %} @@ -262,6 +277,68 @@ }); document.addEventListener('htmx:afterSettle', initTooltips); initTooltips(); + + function getCookie(name) { + let cookieValue = null; + if (document.cookie && document.cookie !== '') { + const cookies = document.cookie.split(';'); + for (let i = 0; i < cookies.length; i++) { + const cookie = cookies[i].trim(); + if (cookie.startsWith(name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } + + function doPushSubscribe(reg) { + const vapidKey = "{{ vapid_public_key }}"; + if (!vapidKey) return; + reg.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: vapidKey, + }).then(sub => { + fetch('/api/notifications/push/subscribe/', { + method: 'POST', + headers: {'Content-Type': 'application/json', 'X-CSRFToken': getCookie('csrftoken')}, + body: JSON.stringify({ + endpoint: sub.endpoint, + auth_key: btoa(String.fromCharCode(...new Uint8Array(sub.getKey('auth')))), + p256dh_key: btoa(String.fromCharCode(...new Uint8Array(sub.getKey('p256dh')))), + }), + }); + }).catch(() => {}); + } + + const vapidPublicKey = "{{ vapid_public_key }}"; + if (vapidPublicKey && 'serviceWorker' in navigator && 'PushManager' in window) { + navigator.serviceWorker.register('/sw.js').then(reg => { + if (Notification.permission === 'granted') { + doPushSubscribe(reg); + } else if (Notification.permission === 'default' && !localStorage.getItem('push_declined')) { + document.getElementById('push-prompt').classList.remove('hidden'); + window.__pushReg = reg; + } + }).catch(() => {}); + } + + window.enablePush = function() { + const reg = window.__pushReg; + if (!reg) return; + Notification.requestPermission().then(perm => { + if (perm === 'granted') { + doPushSubscribe(reg); + } + document.getElementById('push-prompt').classList.add('hidden'); + }); + }; + + window.dismissPush = function() { + localStorage.setItem('push_declined', '1'); + document.getElementById('push-prompt').classList.add('hidden'); + }; {% block extra_scripts %}{% endblock %}