feat: pwa with push notifications (#337)

This commit is contained in:
Joaquín Sánchez 2022-12-18 00:29:16 +01:00 committed by GitHub
parent a18e5e2332
commit f0c91a3974
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 2903 additions and 14 deletions

View file

@ -2,7 +2,16 @@ import { login as loginMasto } from 'masto'
import type { Account, AccountCredentials, Instance, WsEvents } from 'masto'
import type { Ref } from 'vue'
import type { UserLogin } from '~/types'
import { DEFAULT_POST_CHARS_LIMIT, DEFAULT_SERVER, STORAGE_KEY_CURRENT_USER, STORAGE_KEY_SERVERS, STORAGE_KEY_USERS } from '~/constants'
import {
DEFAULT_POST_CHARS_LIMIT,
DEFAULT_SERVER,
STORAGE_KEY_CURRENT_USER,
STORAGE_KEY_NOTIFICATION,
STORAGE_KEY_NOTIFICATION_POLICY,
STORAGE_KEY_SERVERS,
STORAGE_KEY_USERS,
} from '~/constants'
import type { PushNotificationPolicy, PushNotificationRequest } from '~/composables/push-notifications/types'
const mock = process.mock
const users = useLocalStorage<UserLogin[]>(STORAGE_KEY_USERS, mock ? [mock.user] : [], { deep: true })
@ -53,12 +62,15 @@ export async function loginTo(user?: Omit<UserLogin, 'account'> & { account?: Ac
else {
try {
const [me, server] = await Promise.all([
const [me, server, pushSubscription] = await Promise.all([
masto.accounts.verifyCredentials(),
masto.instances.fetch(),
// we get 404 response instead empty data
masto.pushSubscriptions.fetch().catch(() => Promise.resolve(undefined)),
])
user.account = me
user.pushSubscription = pushSubscription
currentUserId.value = me.id
servers.value[me.id] = server
@ -83,6 +95,37 @@ export async function loginTo(user?: Omit<UserLogin, 'account'> & { account?: Ac
return masto
}
export async function removePushNotifications(user: UserLogin, fromSWPushManager = true) {
// unsubscribe push notifications
try {
await useMasto().pushSubscriptions.remove()
}
catch {
// ignore
}
// clear push subscription
user.pushSubscription = undefined
const { acct } = user.account
// clear request notification permission
delete useLocalStorage<PushNotificationRequest>(STORAGE_KEY_NOTIFICATION, {}).value[acct]
// clear push notification policy
delete useLocalStorage<PushNotificationPolicy>(STORAGE_KEY_NOTIFICATION_POLICY, {}).value[acct]
// we remove the sw push manager if required and there are no more accounts with subscriptions
if (fromSWPushManager && (users.value.length === 0 || users.value.every(u => !u.pushSubscription))) {
// clear sw push subscription
try {
const registration = await navigator.serviceWorker.ready
const subscription = await registration.pushManager.getSubscription()
if (subscription)
await subscription.unsubscribe()
}
catch {
// juts ignore
}
}
}
export async function signout() {
// TODO: confirm
if (!currentUser.value)
@ -97,6 +140,8 @@ export async function signout() {
clearUserLocalStorage()
delete servers.value[_currentUserId]
await removePushNotifications(currentUser.value)
currentUserId.value = ''
// Remove the current user from the users
users.value.splice(index, 1)