Johann150
1e8e551ee3
It is now possible for the client to trigger notifications "manually" if push notifications are not configured on the server.
175 lines
5.3 KiB
TypeScript
175 lines
5.3 KiB
TypeScript
declare var self: ServiceWorkerGlobalScope;
|
|
|
|
import { createNotification } from '@/scripts/create-notification';
|
|
import { swLang } from '@/scripts/lang';
|
|
import { swNotificationRead } from '@/scripts/notification-read';
|
|
import { pushNotificationDataMap } from '@/types';
|
|
import * as swos from '@/scripts/operations';
|
|
import { acct as getAcct } from '@/filters/user';
|
|
|
|
self.addEventListener('install', ev => {
|
|
ev.waitUntil(self.skipWaiting());
|
|
});
|
|
|
|
self.addEventListener('activate', ev => {
|
|
ev.waitUntil(
|
|
caches.keys()
|
|
.then(cacheNames => Promise.all(
|
|
cacheNames
|
|
.filter((v) => v !== swLang.cacheName)
|
|
.map(name => caches.delete(name))
|
|
))
|
|
.then(() => self.clients.claim())
|
|
);
|
|
});
|
|
|
|
self.addEventListener('push', ev => {
|
|
ev.waitUntil((async <K extends keyof pushNotificationDataMap>() => {
|
|
const data: pushNotificationDataMap[K] = ev.data?.json();
|
|
|
|
switch (data.type) {
|
|
// case 'driveFileCreated':
|
|
case 'notification':
|
|
case 'unreadMessagingMessage':
|
|
return createNotification(data);
|
|
case 'readAllNotifications':
|
|
for (const n of await self.registration.getNotifications()) {
|
|
if (n?.data?.type === 'notification') n.close();
|
|
}
|
|
break;
|
|
case 'readAllMessagingMessages':
|
|
for (const n of await self.registration.getNotifications()) {
|
|
if (n?.data?.type === 'unreadMessagingMessage') n.close();
|
|
}
|
|
break;
|
|
case 'readNotifications':
|
|
for (const n of await self.registration.getNotifications()) {
|
|
if (data.body?.notificationIds?.includes(n.data.body.id)) {
|
|
n.close();
|
|
}
|
|
}
|
|
break;
|
|
case 'readAllMessagingMessagesOfARoom':
|
|
for (const n of await self.registration.getNotifications()) {
|
|
if (n.data.type === 'unreadMessagingMessage'
|
|
&& ('userId' in data.body
|
|
? data.body.userId === n.data.body.userId
|
|
: data.body.groupId === n.data.body.groupId)
|
|
) {
|
|
n.close();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
})());
|
|
});
|
|
|
|
self.addEventListener('notificationclick', <K extends keyof pushNotificationDataMap>(ev: ServiceWorkerGlobalScopeEventMap['notificationclick']) => {
|
|
ev.waitUntil((async () => {
|
|
if (_DEV_) {
|
|
console.log('notificationclick', ev.action, ev.notification.data);
|
|
}
|
|
|
|
const { action, notification } = ev;
|
|
const data: pushNotificationDataMap[K] = notification.data;
|
|
const { userId: id } = data;
|
|
let client: WindowClient | null = null;
|
|
|
|
switch (data.type) {
|
|
case 'notification':
|
|
switch (action) {
|
|
case 'follow':
|
|
if ('userId' in data.body) await swos.api('following/create', id, { userId: data.body.userId });
|
|
break;
|
|
case 'showUser':
|
|
if ('user' in data.body) client = await swos.openUser(getAcct(data.body.user), id);
|
|
break;
|
|
case 'reply':
|
|
if ('note' in data.body) client = await swos.openPost({ reply: data.body.note }, id);
|
|
break;
|
|
case 'renote':
|
|
if ('note' in data.body) await swos.api('notes/create', id, { renoteId: data.body.note.id });
|
|
break;
|
|
case 'accept':
|
|
switch (data.body.type) {
|
|
case 'receiveFollowRequest':
|
|
await swos.api('following/requests/accept', id, { userId: data.body.userId });
|
|
break;
|
|
case 'groupInvited':
|
|
await swos.api('users/groups/invitations/accept', id, { invitationId: data.body.invitation.id });
|
|
break;
|
|
}
|
|
break;
|
|
case 'reject':
|
|
switch (data.body.type) {
|
|
case 'receiveFollowRequest':
|
|
await swos.api('following/requests/reject', id, { userId: data.body.userId });
|
|
break;
|
|
case 'groupInvited':
|
|
await swos.api('users/groups/invitations/reject', id, { invitationId: data.body.invitation.id });
|
|
break;
|
|
}
|
|
break;
|
|
case 'showFollowRequests':
|
|
client = await swos.openClient('push', '/my/follow-requests', id);
|
|
break;
|
|
default:
|
|
switch (data.body.type) {
|
|
case 'receiveFollowRequest':
|
|
client = await swos.openClient('push', '/my/follow-requests', id);
|
|
break;
|
|
case 'groupInvited':
|
|
client = await swos.openClient('push', '/my/groups', id);
|
|
break;
|
|
case 'reaction':
|
|
client = await swos.openNote(data.body.note.id, id);
|
|
break;
|
|
default:
|
|
if ('note' in data.body) {
|
|
client = await swos.openNote(data.body.note.id, id);
|
|
} else if ('user' in data.body) {
|
|
client = await swos.openUser(getAcct(data.body.user), id);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case 'unreadMessagingMessage':
|
|
client = await swos.openChat(data.body, id);
|
|
break;
|
|
}
|
|
|
|
if (client) {
|
|
client.focus();
|
|
}
|
|
if (data.type === 'notification') {
|
|
swNotificationRead.then(that => that.read(data));
|
|
}
|
|
|
|
notification.close();
|
|
|
|
})());
|
|
});
|
|
|
|
self.addEventListener('notificationclose', <K extends keyof pushNotificationDataMap>(ev: ServiceWorkerGlobalScopeEventMap['notificationclose']) => {
|
|
const data: pushNotificationDataMap[K] = ev.notification.data;
|
|
|
|
if (data.type === 'notification') {
|
|
swNotificationRead.then(that => that.read(data));
|
|
}
|
|
});
|
|
|
|
self.addEventListener('message', (ev: ServiceWorkerGlobalScopeEventMap['message']) => {
|
|
ev.waitUntil((async () => {
|
|
if (typeof ev.data === 'object') {
|
|
switch (ev.data.type) {
|
|
case 'initialize':
|
|
swLang.setLang(ev.data.lang);
|
|
break;
|
|
case 'notification':
|
|
createNotification(ev.data);
|
|
break;
|
|
}
|
|
}
|
|
})());
|
|
});
|