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,
|
currentInstance,
|
||||||
instanceThemes,
|
instanceThemes,
|
||||||
disableCustomScrollbars,
|
disableCustomScrollbars,
|
||||||
enableGrayscale
|
enableGrayscale,
|
||||||
|
pushSubscription,
|
||||||
|
loggedInInstancesInOrder
|
||||||
} = storeLite.get()
|
} = storeLite.get()
|
||||||
|
|
||||||
const theme = (instanceThemes && instanceThemes[currentInstance]) || DEFAULT_THEME
|
const theme = (instanceThemes && instanceThemes[currentInstance]) || DEFAULT_THEME
|
||||||
|
@ -65,3 +67,18 @@ if (/iP(?:hone|ad|od)/.test(navigator.userAgent) &&
|
||||||
IntersectionObserver.toString().includes('[native code]'))) {
|
IntersectionObserver.toString().includes('[native code]'))) {
|
||||||
document.head.removeChild(document.getElementById('theManifest'))
|
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='
|
const dummyApplicationServerKey = 'BImgAz4cF_yvNFp8uoBJCaGpCX4d0atNIFMHfBvAAXCyrnn9IMAFQ10DW_ZvBCzGeR4fZI5FnEi2JVcRE-L88jY='
|
||||||
|
|
||||||
export async function updatePushSubscriptionForInstance (instanceName) {
|
export async function updatePushSubscriptionForInstance (instanceName) {
|
||||||
const { loggedInInstances, pushSubscription } = store.get()
|
const { loggedInInstances, currentPushSubscription } = store.get()
|
||||||
const accessToken = loggedInInstances[instanceName].access_token
|
const accessToken = loggedInInstances[instanceName].access_token
|
||||||
|
|
||||||
if (pushSubscription === null) {
|
if (currentPushSubscription === null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ export async function updatePushSubscriptionForInstance (instanceName) {
|
||||||
const subscription = await registration.pushManager.getSubscription()
|
const subscription = await registration.pushManager.getSubscription()
|
||||||
|
|
||||||
if (subscription === null) {
|
if (subscription === null) {
|
||||||
store.set({ pushSubscription: null })
|
store.setInstanceData(instanceName, 'pushSubscriptions', null)
|
||||||
store.save()
|
store.save()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -28,16 +28,16 @@ export async function updatePushSubscriptionForInstance (instanceName) {
|
||||||
if (btoa(urlBase64ToUint8Array(backendSubscription.server_key).buffer) !== btoa(subscription.options.applicationServerKey)) {
|
if (btoa(urlBase64ToUint8Array(backendSubscription.server_key).buffer) !== btoa(subscription.options.applicationServerKey)) {
|
||||||
await subscription.unsubscribe()
|
await subscription.unsubscribe()
|
||||||
await deleteSubscription(instanceName, accessToken)
|
await deleteSubscription(instanceName, accessToken)
|
||||||
await updateAlerts(instanceName, pushSubscription.alerts)
|
await updateAlerts(instanceName, currentPushSubscription.alerts)
|
||||||
} else {
|
} else {
|
||||||
store.set({ pushSubscription: backendSubscription })
|
store.setInstanceData(instanceName, 'pushSubscriptions', backendSubscription)
|
||||||
store.save()
|
store.save()
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: Better way to detect 404
|
// TODO: Better way to detect 404
|
||||||
if (e.message.startsWith('404:')) {
|
if (e.message.startsWith('404:')) {
|
||||||
await subscription.unsubscribe()
|
await subscription.unsubscribe()
|
||||||
store.set({ pushSubscription: null })
|
store.setInstanceData(instanceName, 'pushSubscriptions', null)
|
||||||
store.save()
|
store.save()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,16 +73,16 @@ export async function updateAlerts (instanceName, alerts) {
|
||||||
|
|
||||||
backendSubscription = await postSubscription(instanceName, accessToken, subscription, alerts)
|
backendSubscription = await postSubscription(instanceName, accessToken, subscription, alerts)
|
||||||
|
|
||||||
store.set({ pushSubscription: backendSubscription })
|
store.setInstanceData(instanceName, 'pushSubscriptions', backendSubscription)
|
||||||
store.save()
|
store.save()
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
const backendSubscription = await putSubscription(instanceName, accessToken, alerts)
|
const backendSubscription = await putSubscription(instanceName, accessToken, alerts)
|
||||||
store.set({ pushSubscription: backendSubscription })
|
store.setInstanceData(instanceName, 'pushSubscriptions', backendSubscription)
|
||||||
store.save()
|
store.save()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const backendSubscription = await postSubscription(instanceName, accessToken, subscription, alerts)
|
const backendSubscription = await postSubscription(instanceName, accessToken, subscription, alerts)
|
||||||
store.set({ pushSubscription: backendSubscription })
|
store.setInstanceData(instanceName, 'pushSubscriptions', backendSubscription)
|
||||||
store.save()
|
store.save()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
<p>Your browser doesn't support push notifications.</p>
|
<p>Your browser doesn't support push notifications.</p>
|
||||||
{:elseif $notificationPermission === "denied"}
|
{: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}
|
{/if}
|
||||||
<form id="push-notification-settings"
|
<form id="push-notification-settings"
|
||||||
disabled="{!pushNotificationsSupport}"
|
disabled="{!pushNotificationsSupport}"
|
||||||
|
@ -51,7 +53,7 @@
|
||||||
await updatePushSubscriptionForInstance(instanceName)
|
await updatePushSubscriptionForInstance(instanceName)
|
||||||
|
|
||||||
const { form } = this.refs
|
const { form } = this.refs
|
||||||
const { pushSubscription } = this.store.get()
|
const pushSubscription = this.store.getInstanceData(instanceName, 'pushSubscriptions')
|
||||||
|
|
||||||
for (let { key } of options) {
|
for (let { key } of options) {
|
||||||
form.elements[key].checked = get(pushSubscription, ['alerts', key])
|
form.elements[key].checked = get(pushSubscription, ['alerts', key])
|
||||||
|
|
|
@ -15,6 +15,7 @@ export function instanceComputations (store) {
|
||||||
computeForInstance(store, 'currentStatusModifications', 'statusModifications', null)
|
computeForInstance(store, 'currentStatusModifications', 'statusModifications', null)
|
||||||
computeForInstance(store, 'currentCustomEmoji', 'customEmoji', [])
|
computeForInstance(store, 'currentCustomEmoji', 'customEmoji', [])
|
||||||
computeForInstance(store, 'currentComposeData', 'composeData', {})
|
computeForInstance(store, 'currentComposeData', 'composeData', {})
|
||||||
|
computeForInstance(store, 'currentPushSubscription', 'pushSubscriptions', null)
|
||||||
|
|
||||||
store.compute(
|
store.compute(
|
||||||
'isUserLoggedIn',
|
'isUserLoggedIn',
|
||||||
|
|
|
@ -36,4 +36,15 @@ export function instanceMixins (Store) {
|
||||||
instanceSettings[instanceName][settingName] = value
|
instanceSettings[instanceName][settingName] = value
|
||||||
this.set({ instanceSettings })
|
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,
|
neverMarkMediaAsSensitive: false,
|
||||||
omitEmojiInDisplayNames: undefined,
|
omitEmojiInDisplayNames: undefined,
|
||||||
pinnedPages: {},
|
pinnedPages: {},
|
||||||
pushSubscription: null,
|
pushSubscriptions: {},
|
||||||
reduceMotion:
|
reduceMotion:
|
||||||
!process.browser ||
|
!process.browser ||
|
||||||
window.matchMedia('(prefers-reduced-motion: reduce)').matches,
|
window.matchMedia('(prefers-reduced-motion: reduce)').matches,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// "lite" version of the store used in the inline script. Purely read-only,
|
// "lite" version of the store used in the inline script.
|
||||||
// does not implement non-LocalStorage store features.
|
|
||||||
|
|
||||||
import { safeParse } from './safeParse'
|
import { safeParse } from './safeParse'
|
||||||
import { testHasLocalStorageOnce } from '../_utils/testStorage'
|
import { testHasLocalStorageOnce } from '../_utils/testStorage'
|
||||||
|
@ -16,5 +15,13 @@ export const storeLite = {
|
||||||
return obj[prop]
|
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