document.addEventListener('DOMContentLoaded', () => {
const applicationServerKey =
'какой-то ключ';
let isPushEnabled = false;
if (!('serviceWorker' in navigator)) {
console.warn('Service workers are not supported by this browser');
//changePushButtonState('incompatible');
return;
}
if (!('PushManager' in window)) {
console.warn('Push notifications are not supported by this browser');
//changePushButtonState('incompatible');
return;
}
if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
console.warn('Notifications are not supported by this browser');
//changePushButtonState('incompatible');
return;
}
// Check the current Notification permission.
// If its denied, the button should appears as such, until the user changes the permission manually
if (Notification.permission === 'denied') {
console.warn('Notifications are denied by the user');
//changePushButtonState('incompatible');
return;
}
navigator.serviceWorker.register('/local/web-push/serviceWorker.js').then(
async() => {
console.log('[SW] Service worker has been registered');
let result = await push_updateSubscription();
console.log(result);
},
e => {
console.error('[SW] Service worker registration failed', e);
//changePushButtonState('incompatible');
}
);
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - (base64String.length % 4)) % 4);
const base64 = (base64String + padding).replace(/\-/g, '+').replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
function checkNotificationPermission() {
return new Promise((resolve, reject) => {
if (Notification.permission === 'denied') {
return reject(new Error('Push messages are blocked.'));
}
if (Notification.permission === 'granted') {
return resolve();
}
if (Notification.permission === 'default') {
return Notification.requestPermission().then(result => {
if (result !== 'granted') {
reject(new Error('Bad permission result'));
}
resolve();
});
}
});
}
function push_subscribe() {
//changePushButtonState('computing');
return checkNotificationPermission()
.then(() => navigator.serviceWorker.ready)
.then(serviceWorkerRegistration =>
serviceWorkerRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(applicationServerKey),
})
)
.then(subscription => {
// Subscription was successful
// create subscription on your server
return push_sendSubscriptionToServer(subscription, 'POST');
})
.catch(e => {
if (Notification.permission === 'denied') {
// The user denied the notification permission which
// means we failed to subscribe and the user will need
// to manually change the notification permission to
// subscribe to push messages
console.warn('Notifications are denied by the user.');
changePushButtonState('incompatible');
} else {
// A problem occurred with the subscription; common reasons
// include network errors or the user skipped the permission
console.error('Impossible to subscribe to push notifications', e);
changePushButtonState('disabled');
}
});
}
async function push_updateSubscription() {
navigator.serviceWorker.ready
.then(async(serviceWorkerRegistration) => serviceWorkerRegistration.pushManager.getSubscription())
.then(async(subscription) => {
if (!subscription) {
push_subscribe();
return;
}
// Keep your server in sync with the latest endpoint
let response = await push_sendSubscriptionToServer(subscription, 'PUT');
console.log(response);
return response;
})
.catch(e => {
console.error('Error when updating the subscription', e);
});
}
async function push_sendSubscriptionToServer(subscription, method) {
const key = subscription.getKey('p256dh');
const token = subscription.getKey('auth');
const contentEncoding = (PushManager.supportedContentEncodings || ['aesgcm'])[0];
let response = await fetch('/local/web-push/push_subscription.php', {
method,
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify({
endpoint: subscription.endpoint,
publicKey: key ? btoa(String.fromCharCode.apply(null, new Uint8Array(key))) : null,
authToken: token ? btoa(String.fromCharCode.apply(null, new Uint8Array(token))) : null,
contentEncoding,
}),
});
console.log(response);
return response;
}
});