83 lines
2.3 KiB
JavaScript
83 lines
2.3 KiB
JavaScript
self.addEventListener('install', () => self.skipWaiting());
|
|
self.addEventListener('activate', (event) => event.waitUntil(self.clients.claim()));
|
|
|
|
async function broadcastToClients(payload) {
|
|
const clients = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
|
|
clients.forEach((client) => {
|
|
client.postMessage({
|
|
type: 'SHINE_WEB_PUSH_EVENT',
|
|
payload,
|
|
});
|
|
});
|
|
}
|
|
|
|
self.addEventListener('push', (event) => {
|
|
let body = '';
|
|
let rawText = '';
|
|
let kind = '';
|
|
let fromLogin = '';
|
|
let title = '';
|
|
try {
|
|
if (event.data) {
|
|
const text = event.data.text();
|
|
rawText = text || '';
|
|
try {
|
|
const json = JSON.parse(rawText || '{}');
|
|
kind = String(json.kind || '');
|
|
title = String(json.title || '');
|
|
body = String(json.text || '');
|
|
fromLogin = String(json.fromLogin || '');
|
|
} catch {
|
|
body = rawText || '';
|
|
}
|
|
}
|
|
} catch {
|
|
// ignore
|
|
}
|
|
|
|
const shouldNotify = kind === 'new_message' || kind === 'test_push' || (!kind && body);
|
|
const notificationTitle = kind === 'test_push'
|
|
? (title || 'SHiNE: тестовый push')
|
|
: 'SHiNE: входящее сообщение';
|
|
const notifyPromise = shouldNotify
|
|
? self.registration.showNotification(notificationTitle, {
|
|
body: body || (fromLogin ? `Вам пришло сообщение от ${fromLogin}` : 'Вам пришло сообщение'),
|
|
tag: kind === 'test_push' ? 'shine-test-push' : 'shine-direct-message',
|
|
renotify: true,
|
|
})
|
|
: Promise.resolve();
|
|
|
|
event.waitUntil(Promise.all([
|
|
notifyPromise,
|
|
broadcastToClients({
|
|
kind,
|
|
body,
|
|
fromLogin,
|
|
rawText,
|
|
receivedAt: Date.now(),
|
|
}),
|
|
]));
|
|
});
|
|
|
|
self.addEventListener('notificationclick', (event) => {
|
|
event.notification?.close();
|
|
|
|
event.waitUntil((async () => {
|
|
const allClients = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
|
|
const existing = allClients.find((client) => {
|
|
try {
|
|
return client.url.includes('/index.html') || client.url.endsWith('/');
|
|
} catch {
|
|
return false;
|
|
}
|
|
});
|
|
|
|
if (existing) {
|
|
await existing.focus();
|
|
return;
|
|
}
|
|
|
|
await self.clients.openWindow('./index.html');
|
|
})());
|
|
});
|