138 lines
3.9 KiB
JavaScript
138 lines
3.9 KiB
JavaScript
'use strict';
|
|
|
|
/* -------- NOTIFICATIONS --------- */
|
|
|
|
self.addEventListener('push', handleNotificationPush);
|
|
self.addEventListener('notificationclick', handleNotificationClick);
|
|
|
|
/* -------- NOTIFICATIONS HANDLERS --------- */
|
|
|
|
function handleNotificationPush(event) {
|
|
logger.log('Push notification received');
|
|
|
|
if ($Log.notificationReceived) {
|
|
event.waitUntil(logNotificationReceived(event));
|
|
}
|
|
|
|
// Show notification or fallback
|
|
if (event.data && event.data.title) {
|
|
event.waitUntil(showNotification(event.data));
|
|
} else if ($Notifications.fallbackURL) {
|
|
event.waitUntil(
|
|
self.registration.pushManager.getSubscription()
|
|
.then(fetchNotification)
|
|
.then(convertResponseToJson)
|
|
.then(showNotification)
|
|
.catch(showNotification)
|
|
);
|
|
} else {
|
|
logger.warn('No notification.data and no fallbackURL.');
|
|
event.waitUntil(showNotification());
|
|
}
|
|
}
|
|
|
|
function handleNotificationClick(event) {
|
|
logger.log('Push notification clicked.', event.notification.tag);
|
|
|
|
if ($Log.notificationClicked) {
|
|
event.waitUntil(logNotificationClick(event));
|
|
}
|
|
|
|
// Open the url if provided
|
|
if (event.notification.data && event.notification.data.url) {
|
|
const url = event.notification.data.url;
|
|
event.waitUntil(openWindow(url));
|
|
} else if (event.notification.tag.indexOf(':') !== -1) {
|
|
// TODO: Deprecate
|
|
const url = event.notification.tag.split(':')[2] || '/';
|
|
event.waitUntil(openWindow(url));
|
|
} else {
|
|
logger.warn('Cannot route click with no data.url property. Using "/".', event.notification.tag);
|
|
event.waitUntil(openWindow('/'));
|
|
}
|
|
|
|
event.notification.close();
|
|
logger.groupEnd(event.notification.tag);
|
|
}
|
|
|
|
/* -------- NOTIFICATIONS HELPERS --------- */
|
|
|
|
function showNotification(data) {
|
|
if (!data || !data.tag) {
|
|
// eslint-disable-next-line no-param-reassign
|
|
data = $Notifications.default;
|
|
}
|
|
logger.group(data.tag);
|
|
logger.log('Show notification.', data.tag);
|
|
return self.registration
|
|
.showNotification(data.title, data)
|
|
.then(delayDismissNotification);
|
|
}
|
|
|
|
function fetchNotification(subscription) {
|
|
if (!subscription) {
|
|
logger.warn('No subscription found.');
|
|
throw new Error('No subscription found.');
|
|
}
|
|
logger.log('Fetching remote notification data.');
|
|
const queries = {
|
|
endpoint: subscription.endpoint
|
|
};
|
|
const url = formatUrl($Notifications.fallbackURL, queries);
|
|
return fetch(url, { credentials: 'include' });
|
|
}
|
|
|
|
function convertResponseToJson(response) {
|
|
if (response.status !== 200) {
|
|
throw new Error('Notification data fetch failed.');
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
function delayDismissNotification() {
|
|
setTimeout(function serviceWorkerDismissNotification() {
|
|
self.registration.getNotifications()
|
|
.then(notifications => {
|
|
notifications.forEach(notification => {
|
|
notification.close();
|
|
logger.log('Dismissing notification.', notification.tag);
|
|
logger.groupEnd(notification.tag);
|
|
});
|
|
});
|
|
}, $Notifications.duration || 5000);
|
|
}
|
|
|
|
function openWindow(url) {
|
|
if (clients.openWindow) {
|
|
return clients.openWindow(url);
|
|
}
|
|
return Promise.resolve();
|
|
}
|
|
|
|
function logNotificationReceived(event) {
|
|
return logAction(event, $Log.notificationReceived);
|
|
}
|
|
|
|
function logNotificationClick(event) {
|
|
return logAction(event.notification, $Log.notificationClicked);
|
|
}
|
|
|
|
function logAction(notification, url) {
|
|
logger.log(`Send log event to ${url}.`, notification.tag);
|
|
return self.registration.pushManager.getSubscription().then((subscription) => {
|
|
const query = {
|
|
endpoint: subscription.endpoint,
|
|
tag: notification.tag
|
|
};
|
|
return fetch(formatUrl(url, query), { credentials: 'include' });
|
|
});
|
|
}
|
|
|
|
function formatUrl(url, queries) {
|
|
const prefix = url.includes('?') ? '&' : '?';
|
|
const query = Object.keys(queries).map(function (key) {
|
|
return `${key}=${queries[key]}`;
|
|
}).join('&');
|
|
return url + prefix + query;
|
|
}
|