Merge branch 'push_fix' into 'develop'
Fixes for push notifications Closes #235 See merge request pleroma/pleroma-fe!433
This commit is contained in:
commit
0ad837846a
5 changed files with 74 additions and 30 deletions
23
src/main.js
23
src/main.js
|
@ -54,24 +54,21 @@ const persistedStateOptions = {
|
||||||
const registerPushNotifications = store => {
|
const registerPushNotifications = store => {
|
||||||
store.subscribe((mutation, state) => {
|
store.subscribe((mutation, state) => {
|
||||||
const vapidPublicKey = state.instance.vapidPublicKey
|
const vapidPublicKey = state.instance.vapidPublicKey
|
||||||
|
const webPushNotification = state.config.webPushNotifications
|
||||||
const permission = state.interface.notificationPermission === 'granted'
|
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 user = state.users.currentUser
|
||||||
|
|
||||||
|
const isUserMutation = mutation.type === 'setCurrentUser'
|
||||||
const isVapidMutation = mutation.type === 'setInstanceOption' && mutation.payload.name === 'vapidPublicKey'
|
const isVapidMutation = mutation.type === 'setInstanceOption' && mutation.payload.name === 'vapidPublicKey'
|
||||||
|
|
||||||
if (isVapidMutation && user && permission) {
|
|
||||||
return store.dispatch('registerPushNotifications')
|
|
||||||
}
|
|
||||||
|
|
||||||
const isPermMutation = mutation.type === 'setNotificationPermission' && mutation.payload === 'granted'
|
const isPermMutation = mutation.type === 'setNotificationPermission' && mutation.payload === 'granted'
|
||||||
|
const isUserConfigMutation = mutation.type === 'setOption' && mutation.payload.name === 'webPushNotifications'
|
||||||
|
|
||||||
if (isPermMutation && user && vapidPublicKey) {
|
if (isUserMutation || isVapidMutation || isPermMutation || isUserConfigMutation) {
|
||||||
return store.dispatch('registerPushNotifications')
|
if (user && vapidPublicKey && permission && webPushNotification) {
|
||||||
|
return store.dispatch('registerPushNotifications')
|
||||||
|
} else if (isUserConfigMutation && !webPushNotification) {
|
||||||
|
return store.dispatch('unregisterPushNotifications')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ const defaultState = {
|
||||||
likes: true,
|
likes: true,
|
||||||
repeats: true
|
repeats: true
|
||||||
},
|
},
|
||||||
webPushNotifications: true,
|
webPushNotifications: false,
|
||||||
muteWords: [],
|
muteWords: [],
|
||||||
highlight: {},
|
highlight: {},
|
||||||
interfaceLanguage: browserLocale,
|
interfaceLanguage: browserLocale,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
|
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
|
||||||
import { compact, map, each, merge } from 'lodash'
|
import { compact, map, each, merge } from 'lodash'
|
||||||
import { set } from 'vue'
|
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 oauthApi from '../services/new_api/oauth'
|
||||||
import { humanizeErrors } from './errors'
|
import { humanizeErrors } from './errors'
|
||||||
|
|
||||||
|
@ -116,6 +116,11 @@ const users = {
|
||||||
|
|
||||||
registerPushNotifications(isEnabled, vapidPublicKey, token)
|
registerPushNotifications(isEnabled, vapidPublicKey, token)
|
||||||
},
|
},
|
||||||
|
unregisterPushNotifications (store) {
|
||||||
|
const token = store.state.currentUser.credentials
|
||||||
|
|
||||||
|
unregisterPushNotifications(token)
|
||||||
|
},
|
||||||
addNewStatuses (store, { statuses }) {
|
addNewStatuses (store, { statuses }) {
|
||||||
const users = map(statuses, 'user')
|
const users = map(statuses, 'user')
|
||||||
const retweetedUsers = compact(map(statuses, 'retweeted_status.user'))
|
const retweetedUsers = compact(map(statuses, 'retweeted_status.user'))
|
||||||
|
|
|
@ -14,12 +14,12 @@ function isPushSupported () {
|
||||||
return 'serviceWorker' in navigator && 'PushManager' in window
|
return 'serviceWorker' in navigator && 'PushManager' in window
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerServiceWorker () {
|
function getOrCreateServiceWorker () {
|
||||||
return runtime.register()
|
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 (!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'))
|
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)
|
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) {
|
function sendSubscriptionToBackEnd (subscription, token) {
|
||||||
return window.fetch('/api/v1/push/subscription/', {
|
return window.fetch('/api/v1/push/subscription/', {
|
||||||
method: 'POST',
|
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()) {
|
if (isPushSupported()) {
|
||||||
registerServiceWorker()
|
getOrCreateServiceWorker()
|
||||||
.then((registration) => subscribe(registration, isEnabled, vapidPublicKey))
|
.then((registration) => subscribePush(registration, isEnabled, vapidPublicKey))
|
||||||
.then((subscription) => sendSubscriptionToBackEnd(subscription, token))
|
.then((subscription) => sendSubscriptionToBackEnd(subscription, token))
|
||||||
.catch((e) => console.warn(`Failed to setup Web Push Notifications: ${e.message}`))
|
.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}`))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,5 +16,6 @@
|
||||||
"alwaysShowSubjectInput": true,
|
"alwaysShowSubjectInput": true,
|
||||||
"hidePostStats": false,
|
"hidePostStats": false,
|
||||||
"hideUserStats": false,
|
"hideUserStats": false,
|
||||||
"loginMethod": "password"
|
"loginMethod": "password",
|
||||||
|
"webPushNotifications": false
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue