feat: add poll result push notifications (#1227)
fixes one of the sub-tasks in #1130. I also went ahead and removed the reply feature, because I cannot get it to work in Android 6.0.1 and I can't find any documentation for it in W3C/WHATWG, so I'm not sure how it is supposed to work.
This commit is contained in:
parent
a17948cf99
commit
12c5b732ae
|
@ -4,18 +4,21 @@
|
|||
{:elseif $notificationPermission === "denied"}
|
||||
<p role="alert">You have denied permission to show notifications.</p>
|
||||
{/if}
|
||||
<form id="push-notification-settings" disabled="{!pushNotificationsSupport}" ref:pushNotificationsForm aria-label="Push notification settings">
|
||||
<input type="checkbox" id="push-notifications-follow" name="follow" disabled="{!pushNotificationsSupport}" on:change="onPushSettingsChange(event)">
|
||||
<label for="push-notifications-follow">New followers</label>
|
||||
<br>
|
||||
<input type="checkbox" id="push-notifications-favourite" name="favourite" disabled="{!pushNotificationsSupport}" on:change="onPushSettingsChange(event)">
|
||||
<label for="push-notifications-favourite">Favorites</label>
|
||||
<br>
|
||||
<input type="checkbox" id="push-notifications-reblog" name="reblog" disabled="{!pushNotificationsSupport}" on:change="onPushSettingsChange(event)">
|
||||
<label for="push-notifications-reblog">Boosts</label>
|
||||
<br>
|
||||
<input type="checkbox" id="push-notifications-mention" name="mention" disabled="{!pushNotificationsSupport}" on:change="onPushSettingsChange(event)">
|
||||
<label for="push-notifications-mention">Mentions</label>
|
||||
<form id="push-notification-settings"
|
||||
disabled="{!pushNotificationsSupport}"
|
||||
ref:form
|
||||
aria-label="Push notification settings">
|
||||
{#each options as option, i (option.key)}
|
||||
{#if i > 0}
|
||||
<br>
|
||||
{/if}
|
||||
<input type="checkbox"
|
||||
id="push-notifications-{option.key}"
|
||||
name="{option.key}"
|
||||
disabled="{!pushNotificationsSupport}"
|
||||
on:change="onPushSettingsChange(event)">
|
||||
<label for="push-notifications-{option.key}">{option.label}</label>
|
||||
{/each}
|
||||
</form>
|
||||
</div>
|
||||
<style>
|
||||
|
@ -27,11 +30,11 @@
|
|||
padding: 20px;
|
||||
line-height: 2em;
|
||||
}
|
||||
.push-notifications form[disabled="true"] {
|
||||
form[disabled="true"] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.push-notifications p {
|
||||
margin: 0;
|
||||
p {
|
||||
margin: 0 0 10px 0;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
|
@ -44,30 +47,52 @@
|
|||
|
||||
export default {
|
||||
async oncreate () {
|
||||
let { instanceName } = this.get()
|
||||
let { instanceName, options } = this.get()
|
||||
await updatePushSubscriptionForInstance(instanceName)
|
||||
|
||||
const form = this.refs.pushNotificationsForm
|
||||
const { form } = this.refs
|
||||
const { pushSubscription } = this.store.get()
|
||||
|
||||
form.elements.follow.checked = get(pushSubscription, ['alerts', 'follow'])
|
||||
form.elements.favourite.checked = get(pushSubscription, ['alerts', 'favourite'])
|
||||
form.elements.reblog.checked = get(pushSubscription, ['alerts', 'reblog'])
|
||||
form.elements.mention.checked = get(pushSubscription, ['alerts', 'mention'])
|
||||
for (let { key } of options) {
|
||||
form.elements[key].checked = get(pushSubscription, ['alerts', key])
|
||||
}
|
||||
},
|
||||
store: () => store,
|
||||
data: () => ({
|
||||
options: [
|
||||
{
|
||||
key: 'follow',
|
||||
label: 'New Followers'
|
||||
},
|
||||
{
|
||||
key: 'favourite',
|
||||
label: 'Favorites'
|
||||
},
|
||||
{
|
||||
key: 'reblog',
|
||||
label: 'Boosts'
|
||||
},
|
||||
{
|
||||
key: 'mention',
|
||||
label: 'Mentions'
|
||||
},
|
||||
{
|
||||
key: 'poll',
|
||||
label: 'Poll results'
|
||||
}
|
||||
]
|
||||
}),
|
||||
computed: {
|
||||
pushNotificationsSupport: ({ $pushNotificationsSupport }) => $pushNotificationsSupport
|
||||
},
|
||||
methods: {
|
||||
async onPushSettingsChange (e) {
|
||||
const { instanceName } = this.get()
|
||||
const form = this.refs.pushNotificationsForm
|
||||
const alerts = {
|
||||
follow: form.elements.follow.checked,
|
||||
favourite: form.elements.favourite.checked,
|
||||
reblog: form.elements.reblog.checked,
|
||||
mention: form.elements.mention.checked
|
||||
const { instanceName, options } = this.get()
|
||||
const { form } = this.refs
|
||||
const alerts = {}
|
||||
|
||||
for (let { key } of options) {
|
||||
alerts[key] = form.elements[key].checked
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -46,7 +46,7 @@ self.addEventListener('activate', event => {
|
|||
// delete old asset/ondemand caches
|
||||
for (let key of keys) {
|
||||
if (key !== ASSETS &&
|
||||
!key.startsWith('webpack_assets_')) {
|
||||
!key.startsWith('webpack_assets_')) {
|
||||
await caches.delete(key)
|
||||
}
|
||||
}
|
||||
|
@ -131,86 +131,71 @@ async function showSimpleNotification (data) {
|
|||
}
|
||||
|
||||
async function showRichNotification (data, notification) {
|
||||
const { origin } = new URL(data.icon)
|
||||
const { icon, body } = data
|
||||
const tag = notification.id
|
||||
const { origin } = self.location
|
||||
|
||||
switch (notification.type) {
|
||||
case 'follow': {
|
||||
await self.registration.showNotification(data.title, {
|
||||
icon: data.icon,
|
||||
body: data.body,
|
||||
tag: notification.id,
|
||||
icon,
|
||||
body,
|
||||
tag,
|
||||
data: {
|
||||
url: `${self.location.origin}/accounts/${notification.account.id}`
|
||||
url: `${origin}/accounts/${notification.account.id}`
|
||||
}
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'mention': {
|
||||
const actions = [{
|
||||
action: 'favourite',
|
||||
title: 'Favourite'
|
||||
}]
|
||||
|
||||
if ('reply' in NotificationEvent.prototype) {
|
||||
actions.splice(0, 0, {
|
||||
action: 'reply',
|
||||
type: 'text',
|
||||
title: 'Reply'
|
||||
})
|
||||
}
|
||||
|
||||
if (['public', 'unlisted'].includes(notification.status.visibility)) {
|
||||
actions.push({
|
||||
case 'reblog':
|
||||
case 'favourite':
|
||||
case 'poll':
|
||||
await self.registration.showNotification(data.title, {
|
||||
icon,
|
||||
body,
|
||||
tag,
|
||||
data: {
|
||||
url: `${origin}/statuses/${notification.status.id}`
|
||||
}
|
||||
})
|
||||
break
|
||||
case 'mention':
|
||||
const isPublic = ['public', 'unlisted'].includes(notification.status.visibility)
|
||||
const actions = [
|
||||
{
|
||||
action: 'favourite',
|
||||
title: 'Favorite'
|
||||
},
|
||||
isPublic && {
|
||||
action: 'reblog',
|
||||
title: 'Boost'
|
||||
})
|
||||
}
|
||||
}
|
||||
].filter(Boolean)
|
||||
|
||||
await self.registration.showNotification(data.title, {
|
||||
icon: data.icon,
|
||||
body: data.body,
|
||||
tag: notification.id,
|
||||
icon,
|
||||
body,
|
||||
tag,
|
||||
data: {
|
||||
instance: origin,
|
||||
instance: new URL(data.icon).origin,
|
||||
status_id: notification.status.id,
|
||||
access_token: data.access_token,
|
||||
url: `${self.location.origin}/statuses/${notification.status.id}`
|
||||
url: `${origin}/statuses/${notification.status.id}`
|
||||
},
|
||||
actions
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'reblog': {
|
||||
await self.registration.showNotification(data.title, {
|
||||
icon: data.icon,
|
||||
body: data.body,
|
||||
tag: notification.id,
|
||||
data: {
|
||||
url: `${self.location.origin}/statuses/${notification.status.id}`
|
||||
}
|
||||
})
|
||||
break
|
||||
}
|
||||
case 'favourite': {
|
||||
await self.registration.showNotification(data.title, {
|
||||
icon: data.icon,
|
||||
body: data.body,
|
||||
tag: notification.id,
|
||||
data: {
|
||||
url: `${self.location.origin}/statuses/${notification.status.id}`
|
||||
}
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const cloneNotification = notification => {
|
||||
const clone = { }
|
||||
const clone = {}
|
||||
|
||||
// Object.assign() does not work with notifications
|
||||
for (let k in notification) {
|
||||
clone[k] = notification[k]
|
||||
if (notification.hasOwnProperty(k)) {
|
||||
clone[k] = notification[k]
|
||||
}
|
||||
}
|
||||
|
||||
return clone
|
||||
|
@ -227,21 +212,19 @@ const updateNotificationWithoutAction = (notification, action) => {
|
|||
self.addEventListener('notificationclick', event => {
|
||||
event.waitUntil((async () => {
|
||||
switch (event.action) {
|
||||
case 'reply': {
|
||||
await post(`${event.notification.data.instance}/api/v1/statuses/`, {
|
||||
status: event.reply,
|
||||
in_reply_to_id: event.notification.data.status_id
|
||||
}, { 'Authorization': `Bearer ${event.notification.data.access_token}` })
|
||||
await updateNotificationWithoutAction(event.notification, 'reply')
|
||||
break
|
||||
}
|
||||
case 'reblog': {
|
||||
await post(`${event.notification.data.instance}/api/v1/statuses/${event.notification.data.status_id}/reblog`, null, { 'Authorization': `Bearer ${event.notification.data.access_token}` })
|
||||
const url = `${event.notification.data.instance}/api/v1/statuses/${event.notification.data.status_id}/reblog`
|
||||
await post(url, null, {
|
||||
'Authorization': `Bearer ${event.notification.data.access_token}`
|
||||
})
|
||||
await updateNotificationWithoutAction(event.notification, 'reblog')
|
||||
break
|
||||
}
|
||||
case 'favourite': {
|
||||
await post(`${event.notification.data.instance}/api/v1/statuses/${event.notification.data.status_id}/favourite`, null, { 'Authorization': `Bearer ${event.notification.data.access_token}` })
|
||||
const url = `${event.notification.data.instance}/api/v1/statuses/${event.notification.data.status_id}/favourite`
|
||||
await post(url, null, {
|
||||
'Authorization': `Bearer ${event.notification.data.access_token}`
|
||||
})
|
||||
await updateNotificationWithoutAction(event.notification, 'favourite')
|
||||
break
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue