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"}
|
{: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>
|
||||||
{/if}
|
{/if}
|
||||||
<form id="push-notification-settings" disabled="{!pushNotificationsSupport}" ref:pushNotificationsForm aria-label="Push notification settings">
|
<form id="push-notification-settings"
|
||||||
<input type="checkbox" id="push-notifications-follow" name="follow" disabled="{!pushNotificationsSupport}" on:change="onPushSettingsChange(event)">
|
disabled="{!pushNotificationsSupport}"
|
||||||
<label for="push-notifications-follow">New followers</label>
|
ref:form
|
||||||
|
aria-label="Push notification settings">
|
||||||
|
{#each options as option, i (option.key)}
|
||||||
|
{#if i > 0}
|
||||||
<br>
|
<br>
|
||||||
<input type="checkbox" id="push-notifications-favourite" name="favourite" disabled="{!pushNotificationsSupport}" on:change="onPushSettingsChange(event)">
|
{/if}
|
||||||
<label for="push-notifications-favourite">Favorites</label>
|
<input type="checkbox"
|
||||||
<br>
|
id="push-notifications-{option.key}"
|
||||||
<input type="checkbox" id="push-notifications-reblog" name="reblog" disabled="{!pushNotificationsSupport}" on:change="onPushSettingsChange(event)">
|
name="{option.key}"
|
||||||
<label for="push-notifications-reblog">Boosts</label>
|
disabled="{!pushNotificationsSupport}"
|
||||||
<br>
|
on:change="onPushSettingsChange(event)">
|
||||||
<input type="checkbox" id="push-notifications-mention" name="mention" disabled="{!pushNotificationsSupport}" on:change="onPushSettingsChange(event)">
|
<label for="push-notifications-{option.key}">{option.label}</label>
|
||||||
<label for="push-notifications-mention">Mentions</label>
|
{/each}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
|
@ -27,11 +30,11 @@
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
line-height: 2em;
|
line-height: 2em;
|
||||||
}
|
}
|
||||||
.push-notifications form[disabled="true"] {
|
form[disabled="true"] {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
.push-notifications p {
|
p {
|
||||||
margin: 0;
|
margin: 0 0 10px 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
|
@ -44,30 +47,52 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
async oncreate () {
|
async oncreate () {
|
||||||
let { instanceName } = this.get()
|
let { instanceName, options } = this.get()
|
||||||
await updatePushSubscriptionForInstance(instanceName)
|
await updatePushSubscriptionForInstance(instanceName)
|
||||||
|
|
||||||
const form = this.refs.pushNotificationsForm
|
const { form } = this.refs
|
||||||
const { pushSubscription } = this.store.get()
|
const { pushSubscription } = this.store.get()
|
||||||
|
|
||||||
form.elements.follow.checked = get(pushSubscription, ['alerts', 'follow'])
|
for (let { key } of options) {
|
||||||
form.elements.favourite.checked = get(pushSubscription, ['alerts', 'favourite'])
|
form.elements[key].checked = get(pushSubscription, ['alerts', key])
|
||||||
form.elements.reblog.checked = get(pushSubscription, ['alerts', 'reblog'])
|
}
|
||||||
form.elements.mention.checked = get(pushSubscription, ['alerts', 'mention'])
|
|
||||||
},
|
},
|
||||||
store: () => store,
|
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: {
|
computed: {
|
||||||
pushNotificationsSupport: ({ $pushNotificationsSupport }) => $pushNotificationsSupport
|
pushNotificationsSupport: ({ $pushNotificationsSupport }) => $pushNotificationsSupport
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async onPushSettingsChange (e) {
|
async onPushSettingsChange (e) {
|
||||||
const { instanceName } = this.get()
|
const { instanceName, options } = this.get()
|
||||||
const form = this.refs.pushNotificationsForm
|
const { form } = this.refs
|
||||||
const alerts = {
|
const alerts = {}
|
||||||
follow: form.elements.follow.checked,
|
|
||||||
favourite: form.elements.favourite.checked,
|
for (let { key } of options) {
|
||||||
reblog: form.elements.reblog.checked,
|
alerts[key] = form.elements[key].checked
|
||||||
mention: form.elements.mention.checked
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -131,87 +131,72 @@ async function showSimpleNotification (data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function showRichNotification (data, notification) {
|
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) {
|
switch (notification.type) {
|
||||||
case 'follow': {
|
case 'follow': {
|
||||||
await self.registration.showNotification(data.title, {
|
await self.registration.showNotification(data.title, {
|
||||||
icon: data.icon,
|
icon,
|
||||||
body: data.body,
|
body,
|
||||||
tag: notification.id,
|
tag,
|
||||||
data: {
|
data: {
|
||||||
url: `${self.location.origin}/accounts/${notification.account.id}`
|
url: `${origin}/accounts/${notification.account.id}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'mention': {
|
case 'reblog':
|
||||||
const actions = [{
|
case 'favourite':
|
||||||
action: 'favourite',
|
case 'poll':
|
||||||
title: 'Favourite'
|
await self.registration.showNotification(data.title, {
|
||||||
}]
|
icon,
|
||||||
|
body,
|
||||||
if ('reply' in NotificationEvent.prototype) {
|
tag,
|
||||||
actions.splice(0, 0, {
|
data: {
|
||||||
action: 'reply',
|
url: `${origin}/statuses/${notification.status.id}`
|
||||||
type: 'text',
|
|
||||||
title: 'Reply'
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
if (['public', 'unlisted'].includes(notification.status.visibility)) {
|
break
|
||||||
actions.push({
|
case 'mention':
|
||||||
|
const isPublic = ['public', 'unlisted'].includes(notification.status.visibility)
|
||||||
|
const actions = [
|
||||||
|
{
|
||||||
|
action: 'favourite',
|
||||||
|
title: 'Favorite'
|
||||||
|
},
|
||||||
|
isPublic && {
|
||||||
action: 'reblog',
|
action: 'reblog',
|
||||||
title: 'Boost'
|
title: 'Boost'
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
].filter(Boolean)
|
||||||
|
|
||||||
await self.registration.showNotification(data.title, {
|
await self.registration.showNotification(data.title, {
|
||||||
icon: data.icon,
|
icon,
|
||||||
body: data.body,
|
body,
|
||||||
tag: notification.id,
|
tag,
|
||||||
data: {
|
data: {
|
||||||
instance: origin,
|
instance: new URL(data.icon).origin,
|
||||||
status_id: notification.status.id,
|
status_id: notification.status.id,
|
||||||
access_token: data.access_token,
|
access_token: data.access_token,
|
||||||
url: `${self.location.origin}/statuses/${notification.status.id}`
|
url: `${origin}/statuses/${notification.status.id}`
|
||||||
},
|
},
|
||||||
actions
|
actions
|
||||||
})
|
})
|
||||||
break
|
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 cloneNotification = notification => {
|
||||||
const clone = { }
|
const clone = {}
|
||||||
|
|
||||||
// Object.assign() does not work with notifications
|
// Object.assign() does not work with notifications
|
||||||
for (let k in notification) {
|
for (let k in notification) {
|
||||||
|
if (notification.hasOwnProperty(k)) {
|
||||||
clone[k] = notification[k]
|
clone[k] = notification[k]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return clone
|
return clone
|
||||||
}
|
}
|
||||||
|
@ -227,21 +212,19 @@ const updateNotificationWithoutAction = (notification, action) => {
|
||||||
self.addEventListener('notificationclick', event => {
|
self.addEventListener('notificationclick', event => {
|
||||||
event.waitUntil((async () => {
|
event.waitUntil((async () => {
|
||||||
switch (event.action) {
|
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': {
|
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')
|
await updateNotificationWithoutAction(event.notification, 'reblog')
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'favourite': {
|
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')
|
await updateNotificationWithoutAction(event.notification, 'favourite')
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue