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:
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
}