logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe
commit: 0ad837846a3b833203bdae68fc6d3cb37c257c4b
parent: 2fe0af2af12c436d25f258eec21c149d773ec0d0
Author: HJ <spam@hjkos.com>
Date:   Tue, 25 Dec 2018 11:33:00 +0000

Merge branch 'push_fix' into 'develop'

Fixes for push notifications

Closes #235

See merge request pleroma/pleroma-fe!433

Diffstat:

Msrc/main.js25+++++++++++--------------
Msrc/modules/config.js2+-
Msrc/modules/users.js7++++++-
Msrc/services/push/push.js69+++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Mstatic/config.json3++-
5 files changed, 75 insertions(+), 31 deletions(-)

diff --git a/src/main.js b/src/main.js @@ -54,24 +54,21 @@ const persistedStateOptions = { const registerPushNotifications = store => { store.subscribe((mutation, state) => { const vapidPublicKey = state.instance.vapidPublicKey + const webPushNotification = state.config.webPushNotifications const permission = state.interface.notificationPermission === 'granted' - const isUserMutation = mutation.type === 'setCurrentUser' - - if (isUserMutation && vapidPublicKey && permission) { - return store.dispatch('registerPushNotifications') - } - const user = state.users.currentUser - const isVapidMutation = mutation.type === 'setInstanceOption' && mutation.payload.name === 'vapidPublicKey' - - if (isVapidMutation && user && permission) { - return store.dispatch('registerPushNotifications') - } + const isUserMutation = mutation.type === 'setCurrentUser' + const isVapidMutation = mutation.type === 'setInstanceOption' && mutation.payload.name === 'vapidPublicKey' const isPermMutation = mutation.type === 'setNotificationPermission' && mutation.payload === 'granted' - - if (isPermMutation && user && vapidPublicKey) { - return store.dispatch('registerPushNotifications') + const isUserConfigMutation = mutation.type === 'setOption' && mutation.payload.name === 'webPushNotifications' + + if (isUserMutation || isVapidMutation || isPermMutation || isUserConfigMutation) { + if (user && vapidPublicKey && permission && webPushNotification) { + return store.dispatch('registerPushNotifications') + } else if (isUserConfigMutation && !webPushNotification) { + return store.dispatch('unregisterPushNotifications') + } } }) } diff --git a/src/modules/config.js b/src/modules/config.js @@ -24,7 +24,7 @@ const defaultState = { likes: true, repeats: true }, - webPushNotifications: true, + webPushNotifications: false, muteWords: [], highlight: {}, interfaceLanguage: browserLocale, diff --git a/src/modules/users.js b/src/modules/users.js @@ -1,7 +1,7 @@ import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js' import { compact, map, each, merge } from 'lodash' import { set } from 'vue' -import registerPushNotifications from '../services/push/push.js' +import { registerPushNotifications, unregisterPushNotifications } from '../services/push/push.js' import oauthApi from '../services/new_api/oauth' import { humanizeErrors } from './errors' @@ -116,6 +116,11 @@ const users = { registerPushNotifications(isEnabled, vapidPublicKey, token) }, + unregisterPushNotifications (store) { + const token = store.state.currentUser.credentials + + unregisterPushNotifications(token) + }, addNewStatuses (store, { statuses }) { const users = map(statuses, 'user') const retweetedUsers = compact(map(statuses, 'retweeted_status.user')) diff --git a/src/services/push/push.js b/src/services/push/push.js @@ -14,12 +14,12 @@ function isPushSupported () { return 'serviceWorker' in navigator && 'PushManager' in window } -function registerServiceWorker () { +function getOrCreateServiceWorker () { return runtime.register() - .catch((err) => console.error('Unable to register service worker.', err)) + .catch((err) => console.error('Unable to get or create a service worker.', err)) } -function subscribe (registration, isEnabled, vapidPublicKey) { +function subscribePush (registration, isEnabled, vapidPublicKey) { if (!isEnabled) return Promise.reject(new Error('Web Push is disabled in config')) if (!vapidPublicKey) return Promise.reject(new Error('VAPID public key is not found')) @@ -30,6 +30,27 @@ function subscribe (registration, isEnabled, vapidPublicKey) { return registration.pushManager.subscribe(subscribeOptions) } +function unsubscribePush (registration) { + return registration.pushManager.getSubscription() + .then((subscribtion) => { + if (subscribtion === null) { return } + return subscribtion.unsubscribe() + }) +} + +function deleteSubscriptionFromBackEnd (token) { + return window.fetch('/api/v1/push/subscription/', { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}` + } + }).then((response) => { + if (!response.ok) throw new Error('Bad status code from server.') + return response + }) +} + function sendSubscriptionToBackEnd (subscription, token) { return window.fetch('/api/v1/push/subscription/', { method: 'POST', @@ -48,22 +69,42 @@ function sendSubscriptionToBackEnd (subscription, token) { } } }) + }).then((response) => { + if (!response.ok) throw new Error('Bad status code from server.') + return response.json() + }).then((responseData) => { + if (!responseData.id) throw new Error('Bad response from server.') + return responseData }) - .then((response) => { - if (!response.ok) throw new Error('Bad status code from server.') - return response.json() - }) - .then((responseData) => { - if (!responseData.id) throw new Error('Bad response from server.') - return responseData - }) } -export default function registerPushNotifications (isEnabled, vapidPublicKey, token) { +export function registerPushNotifications (isEnabled, vapidPublicKey, token) { if (isPushSupported()) { - registerServiceWorker() - .then((registration) => subscribe(registration, isEnabled, vapidPublicKey)) + getOrCreateServiceWorker() + .then((registration) => subscribePush(registration, isEnabled, vapidPublicKey)) .then((subscription) => sendSubscriptionToBackEnd(subscription, token)) .catch((e) => console.warn(`Failed to setup Web Push Notifications: ${e.message}`)) } } + +export function unregisterPushNotifications (token) { + if (isPushSupported()) { + Promise.all([ + deleteSubscriptionFromBackEnd(token), + getOrCreateServiceWorker() + .then((registration) => { + return unsubscribePush(registration).then((result) => [registration, result]) + }) + .then(([registration, unsubResult]) => { + if (!unsubResult) { + console.warn('Push subscription cancellation wasn\'t successful, killing SW anyway...') + } + return registration.unregister().then((result) => { + if (!result) { + console.warn('Failed to kill SW') + } + }) + }) + ]).catch((e) => console.warn(`Failed to disable Web Push Notifications: ${e.message}`)) + } +} diff --git a/static/config.json b/static/config.json @@ -16,5 +16,6 @@ "alwaysShowSubjectInput": true, "hidePostStats": false, "hideUserStats": false, - "loginMethod": "password" + "loginMethod": "password", + "webPushNotifications": false }