GithubHelp home page GithubHelp logo

Comments (3)

rehborn avatar rehborn commented on June 4, 2024

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 (ie btn btn-success)
  • define #webpush-url once as data-url
  • group is taken off #webpush-url as dataset.group (data-group)

example utilizing bootstrap and font awesome:

unsubscribed
selection_003

subscribed
selection_002

unsupported
selection_001

denied
selection_004

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.

safwanrahman avatar safwanrahman commented on June 4, 2024

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.

vmesel avatar vmesel commented on June 4, 2024

@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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.