Comments (3)
similar issue, different approach to just show the content element according to status. maybe someone can use it, feel free to disregard.
- button id
#webpush-subscribe-button
- status alert id:
#webpush-status
- use child node (
<span>
) classes as identifier:checking
,subscribed
,unsubscribed
,unsupported
,denied
- define
data-parent-class
per child node to use as class on updating parent (iebtn btn-success
) - define
#webpush-url
once asdata-url
group
is taken off#webpush-url
asdataset.group
(data-group
)
example utilizing bootstrap and font awesome:
jinja template example:
<h1>Webpush</h1>
<h5>save info URL</h5>
{% url 'save_webpush_info' %}
<div id="webpush-url" data-url="{% url 'save_webpush_info' %}" style="display: none;"></div>
<h5>Button</h5>
<button id="webpush-subscribe-button" class="btn btn-default">
<span class="checking">
<i class="fa-fw fas fa-spinner fa-pulse"></i>
{% trans "checking status"|capfirst %}
</span>
<span class="subscribed" style="display: none;" data-parent-class="btn btn-danger">
<i class="fa-fw fas fa-minus"></i>
{% trans "unsubscribe"|capfirst %}
</span>
<span class="unsubscribed" style="display: none;" data-parent-class="btn btn-success">
<i class="fa-fw fas fa-plus"></i>
{% trans "subscribe"|capfirst %}
</span>
<span class="unsupported" style="display: none;" data-parent-class="btn btn-info">
<i class="fa-fw fas fa-info"></i>
{% trans "unsupported"|capfirst %}
</span>
<span class="denied" style="display: none;" data-parent-class="btn btn-warning">
<i class="fa-fw fas fa-times"></i>
{% trans "denied"|capfirst %}
</span>
</button>
<h5>{% trans "subscription"|capfirst %}</h5>
<div id="webpush-status" class="alert alert-info">
<span class="checking">
<i class="fa-fw fas fa-spinner fa-pulse"></i>
{% trans "checking status"|capfirst %}
</span>
<span class="subscribed" style="display: none;" data-parent-class="alert alert-success">
<i class="fa-fw fas fa-check"></i>
{% trans "browser has a subscription"|capfirst %}
</span>
<span class="unsubscribed" style="display: none;" data-parent-class="alert alert-danger">
<i class="fa-fw fas fa-minus"></i>
{% trans "browser does not have a subscription"|capfirst %}
</span>
<span class="unsupported" style="display: none;" data-parent-class="alert alert-info">
<i class="fa-fw fas fa-info"></i>
{% trans "your browser does not support service workers and notification"|capfirst %}
</span>
<span class="denied" style="display: none;" data-parent-class="alert alert-warning">
<i class="fa-fw fas fa-times"></i>
{% trans "your browser denied notifications to this site"|capfirst %}
</span>
</div>
webpush.js
// console.log = function() {};
function toggleContent(parent, class_name) {
var nodes = parent.getElementsByTagName('span');
for (var c=0; c < nodes.length; c++) { nodes[c].style.display = "none"}
var node = parent.getElementsByClassName(class_name)[0];
node.style.display = "block";
if (node.dataset['parentClass'])
parent.className = node.dataset['parentClass']
}
function updateStatus(subscription) {
var subBtn = document.getElementById('webpush-subscribe-button');
var statusBox = document.getElementById('webpush-status');
if (Notification.permission === 'denied') {
if (subBtn) { toggleContent(subBtn, 'denied'); }
if (statusBox) { toggleContent(statusBox, 'denied'); }
} else if (subscription == "unsupported") {
if (subBtn) { toggleContent(subBtn, 'unsupported'); subBtn.disabled = true; }
if (statusBox) { toggleContent(statusBox, 'unsupported'); }
} else if (subscription) {
if (subBtn) { toggleContent(subBtn, 'subscribed'); }
if (statusBox) { toggleContent(statusBox, 'subscribed'); }
} else {
if (subBtn) { toggleContent(subBtn, 'unsubscribed'); }
if (statusBox) { toggleContent(statusBox, 'unsubscribed'); }
}
}
window.addEventListener('load', function() {
if ('serviceWorker' in navigator && ('PushManager' in window)) {
var serviceWorker = document.getElementById('service-worker-js').src;
navigator.serviceWorker.register(serviceWorker)
.then(
function (registration) {
if (!registration.showNotification) { // untested
updateStatus("unsupported");
return false;
}
registration.pushManager.getSubscription()
.then(
function (subscription) {
console.log(subscription);
updateStatus(subscription);
}
)
}
);
} else {
updateStatus("unsupported");
}
var subBtn = document.getElementById('webpush-subscribe-button');
if (subBtn) {
subBtn.addEventListener('click', function () {
if ('serviceWorker' in navigator) {
var serviceWorker = document.getElementById('service-worker-js').src;
navigator.serviceWorker.register(serviceWorker)
.then(
function (registration) {
registration.pushManager.getSubscription()
.then(
function(subscription) {
//updateStatus(subscription);
if (subscription) {
unsubscribe(registration)
} else {
subscribe(registration)
}
}
);
}
);
}
})
}
});
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;
}
function getSubscription(registration) {
return registration.pushManager.getSubscription().then(
function(subscription) {
var metaObj, applicationServerKey, options;
// Check if Subscription is available
if (subscription) {
return subscription;
}
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
return registration.pushManager.subscribe(options)
}
)
}
function subscribe(registration) {
// Get the Subscription or register one
getSubscription(registration)
.then(
function(subscription) {
updateStatus(subscription);
postSubscribeObj('subscribe', subscription);
}
)
.catch(
function(error) {
console.log('Subscription error.', error)
}
)
}
function unsubscribe(registration) {
// Get the Subscription to unregister
registration.pushManager.getSubscription()
.then(
function(subscription) {
console.log(subscription);
updateStatus(false);
// Check we have a subscription to unsubscribe
if (!subscription) {
// No subscription object, so set the state
// to allow the user to subscribe to push
return;
}
postSubscribeObj('unsubscribe', subscription);
}
)
}
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 webpush_url = document.getElementById('webpush-url');
var browser = navigator.userAgent.match(/(firefox|msie|chrome|safari|trident)/ig)[0].toLowerCase();
var data = {
status_type: statusType,
subscription: subscription.toJSON(),
browser: browser,
group: webpush_url.dataset.group
};
fetch(webpush_url.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')) {
}
// Check if the information is deleted from server
if ((response.status == 202) && (statusType == 'unsubscribe')) {
subscription.unsubscribe()
}
}
)
}
from django-webpush.
Thanks @rehborn for providing the snippts. Is it possible for you to provide a patch?
I am currently working on supporing jinja
from django-webpush.
@rehborn is it possible to provide a way to hide the button, so we can send notifications to any user?
from django-webpush.
Related Issues (20)
- django 4.0 compatibility HOT 1
- Problems to load 'webpush_header' HOT 5
- images in notification
- #from django.conf.urls import url HOT 1
- Open webpush url in a popup window
- Migrations problems with Django 3 HOT 5
- New release after 0.3.4 HOT 1
- Grouping of multiple notification not working
- iOS 16.4 Support HOT 4
- Allow passing timeout to pywebpush.send
- Support for IOS 16.4 web push notifications? HOT 4
- IOS 16.4 Support Approach(Solved) HOT 4
- inquiry about notification limits per minute HOT 1
- Subscribe button not working HOT 2
- Errors When Sending Notifications HOT 1
- url not defined HOT 3
- Custom callbacks on subscription
- Cannot read properties of undefined (reding 'pushManager') HOT 4
- Muliple subscriptions for same Device HOT 4
- When I integrate nuxt and django-webpush, it only doesn't work with msedge. HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-webpush.