Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | 2x 2x 2x 2x 36x 2x 2x 2x 4x 3x 3x 1x 1x 2x 2x 2x 3x 3x 1x 7x 2x 5x 5x 5x 2x 5x 4x 4x 1x 2x 2x 2x 1x 1x | import api from './api'
function urlBase64ToUint8Array(base64String: string): Uint8Array<ArrayBuffer> {
const padding = '='.repeat((4 - (base64String.length % 4)) % 4)
const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/')
const raw = atob(base64)
const arr = new Uint8Array(raw.length)
for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i)
return arr
}
async function getVapidPublicKey(): Promise<string> {
const { data } = await api.get<{ publicKey: string }>('/push/public-key')
return data.publicKey
}
async function subscribeToPush(): Promise<void> {
const reg = await navigator.serviceWorker.ready
const existing = await reg.pushManager.getSubscription()
if (existing) {
// Re-send to backend in case it was lost (e.g. new device install)
await sendSubscriptionToServer(existing)
return
}
const vapidKey = await getVapidPublicKey()
const sub = await reg.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(vapidKey),
})
await sendSubscriptionToServer(sub)
}
async function sendSubscriptionToServer(sub: PushSubscription): Promise<void> {
const json = sub.toJSON()
await api.post('/push/subscribe', {
endpoint: json.endpoint,
keys: {
p256dh: json.keys?.p256dh,
auth: json.keys?.auth,
},
})
}
export const pushService = {
/** Call once on app init. Requests permission, subscribes, registers with backend. */
async init(): Promise<void> {
if (!('Notification' in window) || !('serviceWorker' in navigator) || !('PushManager' in window)) {
return // push not supported in this browser
}
let permission = Notification.permission
Iif (permission === 'denied') return
if (permission === 'default') {
permission = await Notification.requestPermission()
}
if (permission !== 'granted') return
try {
await subscribeToPush()
} catch (e) {
console.warn('[Push] Failed to subscribe:', e)
}
},
async unsubscribe(): Promise<void> {
const reg = await navigator.serviceWorker.ready
const sub = await reg.pushManager.getSubscription()
if (!sub) return
await api.delete('/push/subscribe', { data: { endpoint: sub.endpoint } })
await sub.unsubscribe()
},
}
|