Skip to content

Instantly share code, notes, and snippets.

@itrelease
Created February 20, 2016 14:51
Show Gist options
  • Save itrelease/1286428187d4616fcef6 to your computer and use it in GitHub Desktop.
Save itrelease/1286428187d4616fcef6 to your computer and use it in GitHub Desktop.
pn.js
/* eslint-disable no-console */
import React, { PropTypes, Component } from 'react';
import getClassName from '../../utils/getClassName';
const bem = getClassName('TriggerPushNotification');
export default class TriggerPushNotification extends Component {
static get propTypes() {
return {
token: PropTypes.string
};
}
static get contextTypes() {
return {
flux: React.PropTypes.object.isRequired
};
}
constructor(...args) {
super(...args);
this.state = {
isPending: true
};
this.handleClick = this.handleClick.bind(this);
this.initializeState = this.initializeState.bind(this);
this.subscribe = this.subscribe.bind(this);
}
componentDidMount() {
const isTokenDeleted = localStorage.getItem('meduzaPNTokenDeleted');
if ('serviceWorker' in navigator) {
if (!isTokenDeleted) {
navigator.serviceWorker.register('/push-worker.js').then(this.subscribe);
} else {
this.setState({ isPending: false });
}
} else {
console.warn('Service workers aren\'t supported in this browser.');
}
}
render() {
const { isPending } = this.state;
const token = localStorage.getItem('meduzaPNToken');
return (
<div
className={bem({ pending: isPending })}
onClick={this.handleClick}>
{(token === null) &&
'Включить уведомления'
}
{(token !== null) &&
'Выключить уведомления'
}
</div>
);
}
handleClick() {
const { isPending } = this.state;
const token = localStorage.getItem('meduzaPNToken');
if (isPending) {
return;
}
if (token !== null) {
this.unsubscribe();
} else {
this.subscribe();
}
}
initializeState() {
const pnActions = this.context.flux.getActions('pushNotification');
// Are Notifications supported in the service worker?
if (typeof ServiceWorkerRegistration === 'undefined' ||
!('showNotification' in ServiceWorkerRegistration.prototype)) {
console.warn('Notifications aren\'t supported.');
return;
}
// Check the current Notification permission.
// If its denied, it's a permanent block until the
// user changes the permission
if (typeof Notification === 'undefined' ||
Notification.permission === 'denied') {
console.warn('The user has blocked notifications.');
return;
}
// Check if push messaging is supported
if (!('PushManager' in window)) {
console.warn('Push messaging isn\'t supported.');
return;
}
this.setState({ isPending: true });
// We need the service worker registration to check for a subscription
navigator.serviceWorker.ready.then(serviceWorkerRegistration => {
// Do we already have a push message subscription?
serviceWorkerRegistration.pushManager.getSubscription()
.then(subscription => {
this.setState({ isPending: false });
// var pushButton = document.querySelector('.js-push-button');
// pushButton.disabled = false;
if (!subscription) {
// We aren't subscribed to push, so set UI
// to allow the user to enable push
return;
}
// Keep your server in sync with the latest subscriptionId
// sendSubscriptionToServer(subscription);
// isPushEnabled = true;
pnActions.subscribe(subscription.endpoint.slice(10).split('/').pop()).then((token) => {
this.forceUpdate();
});
})
.catch(err => {
this.setState({ isPending: false });
console.warn('Error during getSubscription()', err);
});
});
}
subscribe() {
if (!('serviceWorker' in navigator)) {
return;
}
const pnActions = this.context.flux.getActions('pushNotification');
navigator.serviceWorker.ready.then(serviceWorkerRegistration => {
serviceWorkerRegistration.pushManager.subscribe({ userVisibleOnly: true })
.then(subscription => {
// The subscription was successful
// isPushEnabled = true;
// TODO: Send the subscription.endpoint to your server
// and save it to send a push message at a later date
// return sendSubscriptionToServer(subscription);
return pnActions.subscribe(subscription.endpoint.slice(10).split('/').pop()).then(() => {
this.setState({ isPending: false });
});
})
.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('Permission for Notifications was denied');
} else {
// A problem occurred with the subscription; common reasons
// include network errors, and lacking gcm_sender_id and/or
// gcm_user_visible_only in the manifest.
console.error('Unable to subscribe to push.', e);
}
});
});
}
unsubscribe() {
this.setState({ isPending: true });
// const { token } = this.props;
const token = localStorage.getItem('meduzaPNToken');
const pnActions = this.context.flux.getActions('pushNotification');
navigator.serviceWorker.ready.then(serviceWorkerRegistration => {
// To unsubscribe from push messaging, you need get the
// subscription object, which you can call unsubscribe() on.
serviceWorkerRegistration.pushManager.getSubscription()
.then(pushSubscription => {
// Check we have a subscription to unsubscribe
if (!pushSubscription) {
this.setState({ isPending: false });
// No subscription object, so set the state
// to allow the user to subscribe to push
return;
}
// const subscriptionId = pushSubscription.subscriptionId;
// TODO: Make a request to your server to remove
// the subscriptionId from your data store so you
// don't attempt to send them push messages anymore
// We have a subscription, so call unsubscribe on it
pushSubscription.unsubscribe()
.then(() => {
this.setState({ isPending: false });
return pnActions.unsubscribe(token);
// return true;
})
.catch(e => {
this.setState({ isPending: false });
// We failed to unsubscribe, this can lead to
// an unusual state, so may be best to remove
// the users data from your data store and
// inform the user that you have done so
console.log('Unsubscription error: ', e);
});
}).catch(e => {
this.setState({ isPending: false });
console.error('Error thrown while unsubscribing from push messaging.', e);
});
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment