fix: push subscriptions per instance (#1277)
* fix: push subscriptions per instance fixes #1274 * fixup * add notice about one push notification per instance at a time
This commit is contained in:
parent
51e7f703d3
commit
6980083ed0
|
@ -14,7 +14,9 @@ const {
|
|||
currentInstance,
|
||||
instanceThemes,
|
||||
disableCustomScrollbars,
|
||||
enableGrayscale
|
||||
enableGrayscale,
|
||||
pushSubscription,
|
||||
loggedInInstancesInOrder
|
||||
} = storeLite.get()
|
||||
|
||||
const theme = (instanceThemes && instanceThemes[currentInstance]) || DEFAULT_THEME
|
||||
|
@ -65,3 +67,18 @@ if (/iP(?:hone|ad|od)/.test(navigator.userAgent) &&
|
|||
IntersectionObserver.toString().includes('[native code]'))) {
|
||||
document.head.removeChild(document.getElementById('theManifest'))
|
||||
}
|
||||
|
||||
if (pushSubscription) {
|
||||
// Fix a bug in Pinafore <=v1.9.0 if we only have one instance we're logged in to
|
||||
// (https://github.com/nolanlawson/pinafore/issues/1274)
|
||||
if (loggedInInstancesInOrder && loggedInInstancesInOrder.length === 1) {
|
||||
storeLite.set({
|
||||
pushSubscriptions: {
|
||||
[currentInstance]: pushSubscription
|
||||
}
|
||||
})
|
||||
}
|
||||
storeLite.set({
|
||||
pushSubscription: null
|
||||
})
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@ import { urlBase64ToUint8Array } from '../_utils/base64'
|
|||
const dummyApplicationServerKey = 'BImgAz4cF_yvNFp8uoBJCaGpCX4d0atNIFMHfBvAAXCyrnn9IMAFQ10DW_ZvBCzGeR4fZI5FnEi2JVcRE-L88jY='
|
||||
|
||||
export async function updatePushSubscriptionForInstance (instanceName) {
|
||||
const { loggedInInstances, pushSubscription } = store.get()
|
||||
const { loggedInInstances, currentPushSubscription } = store.get()
|
||||
const accessToken = loggedInInstances[instanceName].access_token
|
||||
|
||||
if (pushSubscription === null) {
|
||||
if (currentPushSubscription === null) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ export async function updatePushSubscriptionForInstance (instanceName) {
|
|||
const subscription = await registration.pushManager.getSubscription()
|
||||
|
||||
if (subscription === null) {
|
||||
store.set({ pushSubscription: null })
|
||||
store.setInstanceData(instanceName, 'pushSubscriptions', null)
|
||||
store.save()
|
||||
return
|
||||
}
|
||||
|
@ -28,16 +28,16 @@ export async function updatePushSubscriptionForInstance (instanceName) {
|
|||
if (btoa(urlBase64ToUint8Array(backendSubscription.server_key).buffer) !== btoa(subscription.options.applicationServerKey)) {
|
||||
await subscription.unsubscribe()
|
||||
await deleteSubscription(instanceName, accessToken)
|
||||
await updateAlerts(instanceName, pushSubscription.alerts)
|
||||
await updateAlerts(instanceName, currentPushSubscription.alerts)
|
||||
} else {
|
||||
store.set({ pushSubscription: backendSubscription })
|
||||
store.setInstanceData(instanceName, 'pushSubscriptions', backendSubscription)
|
||||
store.save()
|
||||
}
|
||||
} catch (e) {
|
||||
// TODO: Better way to detect 404
|
||||
if (e.message.startsWith('404:')) {
|
||||
await subscription.unsubscribe()
|
||||
store.set({ pushSubscription: null })
|
||||
store.setInstanceData(instanceName, 'pushSubscriptions', null)
|
||||
store.save()
|
||||
}
|
||||
}
|
||||
|
@ -73,16 +73,16 @@ export async function updateAlerts (instanceName, alerts) {
|
|||
|
||||
backendSubscription = await postSubscription(instanceName, accessToken, subscription, alerts)
|
||||
|
||||
store.set({ pushSubscription: backendSubscription })
|
||||
store.setInstanceData(instanceName, 'pushSubscriptions', backendSubscription)
|
||||
store.save()
|
||||
} else {
|
||||
try {
|
||||
const backendSubscription = await putSubscription(instanceName, accessToken, alerts)
|
||||
store.set({ pushSubscription: backendSubscription })
|
||||
store.setInstanceData(instanceName, 'pushSubscriptions', backendSubscription)
|
||||
store.save()
|
||||
} catch (e) {
|
||||
const backendSubscription = await postSubscription(instanceName, accessToken, subscription, alerts)
|
||||
store.set({ pushSubscription: backendSubscription })
|
||||
store.setInstanceData(instanceName, 'pushSubscriptions', backendSubscription)
|
||||
store.save()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<div class="push-notifications">
|
||||
{#if pushNotificationsSupport === false}
|
||||
<p>Your browser doesn't support push notifications.</p>
|
||||
<p>Your browser doesn't support push notifications.</p>
|
||||
{:elseif $notificationPermission === "denied"}
|
||||
<p role="alert">You have denied permission to show notifications.</p>
|
||||
<p role="alert">You have denied permission to show notifications.</p>
|
||||
{:elseif $loggedInInstancesInOrder.length > 1}
|
||||
<p>Note that you can only have push notifications for one instance at a time.</p>
|
||||
{/if}
|
||||
<form id="push-notification-settings"
|
||||
disabled="{!pushNotificationsSupport}"
|
||||
|
@ -51,7 +53,7 @@
|
|||
await updatePushSubscriptionForInstance(instanceName)
|
||||
|
||||
const { form } = this.refs
|
||||
const { pushSubscription } = this.store.get()
|
||||
const pushSubscription = this.store.getInstanceData(instanceName, 'pushSubscriptions')
|
||||
|
||||
for (let { key } of options) {
|
||||
form.elements[key].checked = get(pushSubscription, ['alerts', key])
|
||||
|
|
|
@ -15,6 +15,7 @@ export function instanceComputations (store) {
|
|||
computeForInstance(store, 'currentStatusModifications', 'statusModifications', null)
|
||||
computeForInstance(store, 'currentCustomEmoji', 'customEmoji', [])
|
||||
computeForInstance(store, 'currentComposeData', 'composeData', {})
|
||||
computeForInstance(store, 'currentPushSubscription', 'pushSubscriptions', null)
|
||||
|
||||
store.compute(
|
||||
'isUserLoggedIn',
|
||||
|
|
|
@ -36,4 +36,15 @@ export function instanceMixins (Store) {
|
|||
instanceSettings[instanceName][settingName] = value
|
||||
this.set({ instanceSettings })
|
||||
}
|
||||
|
||||
Store.prototype.setInstanceData = function (instanceName, key, value) {
|
||||
let instanceData = this.get()[key] || {}
|
||||
instanceData[instanceName] = value
|
||||
this.set({ [key]: instanceData })
|
||||
}
|
||||
|
||||
Store.prototype.getInstanceData = function (instanceName, key) {
|
||||
let instanceData = this.get()[key] || {}
|
||||
return instanceData[instanceName]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ const persistedState = {
|
|||
neverMarkMediaAsSensitive: false,
|
||||
omitEmojiInDisplayNames: undefined,
|
||||
pinnedPages: {},
|
||||
pushSubscription: null,
|
||||
pushSubscriptions: {},
|
||||
reduceMotion:
|
||||
!process.browser ||
|
||||
window.matchMedia('(prefers-reduced-motion: reduce)').matches,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// "lite" version of the store used in the inline script. Purely read-only,
|
||||
// does not implement non-LocalStorage store features.
|
||||
// "lite" version of the store used in the inline script.
|
||||
|
||||
import { safeParse } from './safeParse'
|
||||
import { testHasLocalStorageOnce } from '../_utils/testStorage'
|
||||
|
@ -16,5 +15,13 @@ export const storeLite = {
|
|||
return obj[prop]
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
set (obj) {
|
||||
if (hasLocalStorage) {
|
||||
for (let [key, value] of Object.entries(obj)) {
|
||||
localStorage.setItem(`store_${key}`, JSON.stringify(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue