import api from './api'; function urlBase64ToUint8Array(base64String: string): Uint8Array { const padding = '='.repeat((4 - (base64String.length % 4)) % 4); const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/'); const rawData = window.atob(base64); // Explicit ArrayBuffer backing so the result satisfies BufferSource. const outputArray = new Uint8Array(new ArrayBuffer(rawData.length)); for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); } return outputArray; } export async function subscribeToPush(): Promise { if (!('serviceWorker' in navigator) || !('PushManager' in window)) { return; } const permission = await Notification.requestPermission(); if (permission !== 'granted') { return; } try { const { data } = await api.get<{ publicKey: string }>('/notifications/vapid-public-key'); const registration = await navigator.serviceWorker.ready; const existing = await registration.pushManager.getSubscription(); if (existing) { await sendSubscriptionToServer(existing); return; } const subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array(data.publicKey), }); await sendSubscriptionToServer(subscription); } catch (err) { console.warn('Push subscription failed:', err); } } async function sendSubscriptionToServer(subscription: PushSubscription): Promise { const json = subscription.toJSON(); await api.post('/notifications/subscribe', { endpoint: json.endpoint, keys: json.keys, }); }