/* eslint-disable no-undef */ importScripts('https://www.gstatic.com/firebasejs/10.12.0/firebase-app-compat.js'); importScripts('https://www.gstatic.com/firebasejs/10.12.0/firebase-messaging-compat.js'); firebase.initializeApp({"apiKey":"","authDomain":"","databaseURL":"","projectId":"","storageBucket":"","messagingSenderId":"","appId":""}); const messaging = firebase.messaging(); const REPLY_API = '/gc/notifications/reply'; function parsePayload(payload) { const data = payload.data || {}; const title = payload.notification?.title || data.title || data.sender_name || 'GLETRA'; const body = payload.notification?.body || data.body || data.message_preview || ''; const icon = data.avatar_url || data.icon || '/gc/icons/icon-192.png'; const tag = data.tag || data.group_key || `gletra-${data.type || 'message'}`; const type = data.type || 'message'; const timestamp = data.timestamp ? Date.parse(data.timestamp) : Date.now(); return { title, body, icon, tag, type, data, timestamp }; } function buildNotificationOptions({ title, body, icon, tag, type, data, timestamp }) { const options = { body, icon, badge: '/gc/icons/icon-192.png', image: data.avatar_url || undefined, tag, renotify: true, timestamp, data, requireInteraction: type === 'call' || type === 'video_call', }; if (type === 'message' && data.reply_token) { options.actions = [ { action: 'reply', title: 'Reply', type: 'text', placeholder: 'Type a message…' }, { action: 'open', title: 'Open' }, ]; } else if (type === 'call' || type === 'video_call') { options.actions = [ { action: 'accept', title: 'Accept' }, { action: 'reject', title: 'Decline' }, ]; } return options; } messaging.onBackgroundMessage((payload) => { const parsed = parsePayload(payload); return self.registration.showNotification(parsed.title, buildNotificationOptions(parsed)); }); self.addEventListener('push', (event) => { if (!event.data) return; let raw; try { raw = event.data.json(); } catch { return; } const parsed = parsePayload({ data: raw.data || raw, notification: raw }); event.waitUntil( self.registration.showNotification(parsed.title, buildNotificationOptions(parsed)) ); }); async function getXsrfToken() { if (typeof self.cookieStore?.get === 'function') { const cookie = await self.cookieStore.get('XSRF-TOKEN'); if (cookie?.value) { return decodeURIComponent(cookie.value); } } return null; } async function postReply(replyToken, message) { await fetch('/sanctum/csrf-cookie', { credentials: 'include' }).catch(() => {}); const headers = { 'Content-Type': 'application/json', Accept: 'application/json' }; const xsrf = await getXsrfToken(); if (xsrf) headers['X-XSRF-TOKEN'] = xsrf; return fetch(REPLY_API, { method: 'POST', credentials: 'include', headers, body: JSON.stringify({ reply_token: replyToken, message }), }); } self.addEventListener('notificationclick', (event) => { const data = event.notification.data || {}; const action = event.action; if (action === 'reply' && event.reply) { event.waitUntil( postReply(data.reply_token, event.reply).then(() => event.notification.close()) ); return; } if (action === 'accept' && data.call_id) { event.notification.close(); event.waitUntil(clients.openWindow(`/gc/calls?accept=${data.call_id}`)); return; } if (action === 'reject' && data.call_id) { event.notification.close(); event.waitUntil( (async () => { await fetch('/sanctum/csrf-cookie', { credentials: 'include' }).catch(() => {}); const headers = { Accept: 'application/json', 'Content-Type': 'application/json' }; const xsrf = await getXsrfToken(); if (xsrf) headers['X-XSRF-TOKEN'] = xsrf; await fetch(`/gc/calls/${data.call_id}/reject`, { method: 'POST', credentials: 'include', headers, }); })() ); return; } event.notification.close(); const url = data.url || data.action_url || '/gc/dashboard'; const target = url.startsWith('http') ? url : new URL(url, self.location.origin).href; event.waitUntil( clients.matchAll({ type: 'window', includeUncontrolled: true }).then((list) => { for (const client of list) { if ('focus' in client) { client.navigate?.(target); return client.focus(); } } if (clients.openWindow) { return clients.openWindow(target); } }) ); });