/// /// /// /// self.addEventListener('install', (event) => { self.skipWaiting(); }); self.addEventListener('activate', (event) => { event.waitUntil(self.clients.claim()); }); // ###### Handle unread badge: const conversationReadStatus = { // Format: // conversationId: { lastRead: Optional(Datetime), lastMessage: Datetime } }; function countUnreadChannels() { console.debug(conversationReadStatus); return Object.entries(conversationReadStatus) .map(([conversationId, { lastRead, lastMessage }]) => { const unread = (!lastRead || (lastRead < lastMessage)) ? 1 : 0; if (unread) { console.debug(`Found unread in ${conversationId}`, lastRead, lastMessage); } return unread; }) .reduce((total, current) => total + current, 0); } self.addEventListener('push', (event) => { // Let's show a notification right away so Safari doesn't tell Apple to be // mad at us: event.waitUntil( self.registration.showNotification('Test notification', { actions: [], body: event.data.text(), }), ); const data = event.data?.json(); // Now we can do slower things that might fail: conversationReadStatus[data.conversation] ||= { lastRead: null, lastMessage: null }; conversationReadStatus[data.conversation].lastMessage = new Date(); console.debug( `Last message in ${data.conversation}`, conversationReadStatus[data.conversation].lastMessage, ); event.waitUntil( (async () => { if (navigator.setAppBadge) { navigator.setAppBadge(countUnreadChannels()); } })(), ); }); // The client has to tell us when it has read a conversation: self.addEventListener('message', (event) => { const data = event.data; switch (data.type) { case 'CONVERSATION_READ': conversationReadStatus[data.conversationId] ||= { lastRead: null, lastMessage: null }; if (data.at) { console.debug('Found data.at', new Date(data.at.ts)); conversationReadStatus[data.conversationId].lastRead = new Date(data.at.ts); } else { console.debug('Found no data.at'); conversationReadStatus[data.conversationId].lastRead = new Date(); } console.debug( `Last read in ${data.conversationId}`, conversationReadStatus[data.conversationId].lastRead, ); event.waitUntil( (async () => { if (navigator.setAppBadge) { navigator.setAppBadge(countUnreadChannels()); } })(), ); break; default: break; } });