Skip to content

Instantly share code, notes, and snippets.

@Enweave
Last active July 18, 2020 01:29
Show Gist options
  • Select an option

  • Save Enweave/bed863a7b55eb33b003c14436ca6f2ee to your computer and use it in GitHub Desktop.

Select an option

Save Enweave/bed863a7b55eb33b003c14436ca6f2ee to your computer and use it in GitHub Desktop.
webpush.js
// adressing this issue https://github.com/safwanrahman/django-webpush/issues/66
function urlB64ToUint8Array(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 (var i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
var isPushEnabled,
serviceWorker,
subBtn,
messageBox,
registration,
subscription
;
function checkPushFeatures() {
// Are Notifications supported in the service worker?
if (!(registration.showNotification)) {
// Show a message and activate the button
messageBox.textContent = 'Showing Notification is not supported in your browser';
messageBox.style.display = 'block';
return;
}
// Check the current Notification permission.
// If its denied, it's a permanent block until the
// user changes the permission
if (Notification.permission === 'denied') {
// Show a message and activate the button
messageBox.textContent = 'The Push Notification is blocked from your browser.';
messageBox.style.display = 'block';
return;
}
// Check if push messaging is supported
if (!('PushManager' in window)) {
// Show a message and activate the button
messageBox.textContent = 'Push Notification is not available in the browser';
messageBox.style.display = 'block';
return;
}
}
var subscribe = function() {
var metaObj, applicationServerKey, options;
metaObj = document.querySelector('meta[name="django-webpush-vapid-key"]');
applicationServerKey = metaObj.content;
options = {
userVisibleOnly: true
};
if (applicationServerKey){
options.applicationServerKey = urlB64ToUint8Array(applicationServerKey)
}
// If not, register one
registration.pushManager.subscribe(options).then(function(sub){
subscription = sub;
postSubscribeObj('subscribe', subscription);
})
};
var unsubscribe = function() {
postSubscribeObj('unsubscribe', subscription);
};
window.addEventListener('load', function() {
// Do everything if the Browser Supports Service Worker
if ('serviceWorker' in navigator) {
serviceWorker = document.querySelector('meta[name="service-worker-js"]').content;
subBtn = document.getElementById('webpush-subscribe-button');
messageBox = document.getElementById('webpush-message');
subBtn.displayState = function(state) {
switch (state) {
case 'loading':
subBtn.disabled = true;
subBtn.textContent = "loading";
break;
case 'sub':
subBtn.disabled = false;
subBtn.textContent = 'Subscribe to Push Messaging';
break;
case 'unsub':
subBtn.disabled = false;
subBtn.textContent = 'Unubscribe from Push Messaging';
break;
default:
console.error("Unknown state", state);
}
}
var setup = function() {
isPushEnabled = subscription ? true : false;
checkPushFeatures(registration);
if (isPushEnabled) {
subBtn.displayState('unsub')
} else {
subBtn.displayState('sub')
}
subBtn.addEventListener('click',
function() {
subBtn.displayState('loading')
if (isPushEnabled) {
unsubscribe();
} else {
subscribe();
}
}
);
};
navigator.serviceWorker.register(serviceWorker).then(
function(reg) {
subBtn.displayState('loading')
// subBtn.textContent = 'Loading....';
registration = reg;
registration.pushManager.getSubscription().then(function(sub) {
subscription = sub;
setup();
})
}
);
}
else {
messageBox.textContent = 'Service Worker is not supported in your Browser!';
messageBox.style.display = 'block';
}
});
function postSubscribeObj(statusType, subscription) {
// Send the information to the server with fetch API.
// the type of the request, the name of the user subscribing,
// and the push subscription endpoint + key the server needs
// to send push messages
var browser = navigator.userAgent.match(/(firefox|msie|chrome|safari|trident)/ig)[0].toLowerCase(),
data = { status_type: statusType,
subscription: subscription ? subscription.toJSON() : {},
browser: browser,
group: subBtn.dataset.group
};
fetch(subBtn.dataset.url, {
method: 'post',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data),
credentials: 'include'
}).then(
function(response) {
// Check the information is saved successfully into server
if ((response.status == 201) && (statusType == 'subscribe')) {
subBtn.displayState('unsub');
isPushEnabled = true;
messageBox.textContent = 'Successfully subscribed for Push Notification';
messageBox.style.display = 'block';
}
// Check if the information is deleted from server
if ((response.status == 202) && (statusType == 'unsubscribe')) {
// Remove the subscription
subscription.unsubscribe().then(
function(successful) {
subscription = null;
subBtn.displayState('sub');
isPushEnabled = false;
messageBox.textContent = 'Successfully unsubscribed for Push Notification';
messageBox.style.display = 'block';
}
)
}
}
)
}
@ottk3
Copy link

ottk3 commented Sep 14, 2019

Thanks a lot! This should be a pull-request imho. Fixes the correct button-state for group subscriptions for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment