diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2022-12-27 14:36:33 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2022-12-27 14:36:33 +0900 |
| commit | 9384f5399da39e53855beb8e7f8ded1aa56bf72e (patch) | |
| tree | ce5959571a981b9c4047da3c7b3fd080aa44222c /packages/client/src/components/MkPushNotificationAllowButton.vue | |
| parent | wip: retention for dashboard (diff) | |
| download | sharkey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.tar.gz sharkey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.tar.bz2 sharkey-9384f5399da39e53855beb8e7f8ded1aa56bf72e.zip | |
rename: client -> frontend
Diffstat (limited to 'packages/client/src/components/MkPushNotificationAllowButton.vue')
| -rw-r--r-- | packages/client/src/components/MkPushNotificationAllowButton.vue | 167 |
1 files changed, 0 insertions, 167 deletions
diff --git a/packages/client/src/components/MkPushNotificationAllowButton.vue b/packages/client/src/components/MkPushNotificationAllowButton.vue deleted file mode 100644 index b356fd3b89..0000000000 --- a/packages/client/src/components/MkPushNotificationAllowButton.vue +++ /dev/null @@ -1,167 +0,0 @@ -<template> -<MkButton - v-if="supported && !pushRegistrationInServer" - type="button" - primary - :gradate="gradate" - :rounded="rounded" - :inline="inline" - :autofocus="autofocus" - :wait="wait" - :full="full" - @click="subscribe" -> - {{ i18n.ts.subscribePushNotification }} -</MkButton> -<MkButton - v-else-if="!showOnlyToRegister && ($i ? pushRegistrationInServer : pushSubscription)" - type="button" - :primary="false" - :gradate="gradate" - :rounded="rounded" - :inline="inline" - :autofocus="autofocus" - :wait="wait" - :full="full" - @click="unsubscribe" -> - {{ i18n.ts.unsubscribePushNotification }} -</MkButton> -<MkButton v-else-if="$i && pushRegistrationInServer" disabled :rounded="rounded" :inline="inline" :wait="wait" :full="full"> - {{ i18n.ts.pushNotificationAlreadySubscribed }} -</MkButton> -<MkButton v-else-if="!supported" disabled :rounded="rounded" :inline="inline" :wait="wait" :full="full"> - {{ i18n.ts.pushNotificationNotSupported }} -</MkButton> -</template> - -<script setup lang="ts"> -import { $i, getAccounts } from '@/account'; -import MkButton from '@/components/MkButton.vue'; -import { instance } from '@/instance'; -import { api, apiWithDialog, promiseDialog } from '@/os'; -import { i18n } from '@/i18n'; - -defineProps<{ - primary?: boolean; - gradate?: boolean; - rounded?: boolean; - inline?: boolean; - link?: boolean; - to?: string; - autofocus?: boolean; - wait?: boolean; - danger?: boolean; - full?: boolean; - showOnlyToRegister?: boolean; -}>(); - -// ServiceWorker registration -let registration = $ref<ServiceWorkerRegistration | undefined>(); -// If this browser supports push notification -let supported = $ref(false); -// If this browser has already subscribed to push notification -let pushSubscription = $ref<PushSubscription | null>(null); -let pushRegistrationInServer = $ref<{ state?: string; key?: string; userId: string; endpoint: string; sendReadMessage: boolean; } | undefined>(); - -function subscribe() { - if (!registration || !supported || !instance.swPublickey) return; - - // SEE: https://developer.mozilla.org/en-US/docs/Web/API/PushManager/subscribe#Parameters - return promiseDialog(registration.pushManager.subscribe({ - userVisibleOnly: true, - applicationServerKey: urlBase64ToUint8Array(instance.swPublickey), - }) - .then(async subscription => { - pushSubscription = subscription; - - // Register - pushRegistrationInServer = await api('sw/register', { - endpoint: subscription.endpoint, - auth: encode(subscription.getKey('auth')), - publickey: encode(subscription.getKey('p256dh')), - }); - }, async err => { // When subscribe failed - // 通知が許可されていなかったとき - if (err?.name === 'NotAllowedError') { - console.info('User denied the notification permission request.'); - return; - } - - // 違うapplicationServerKey (または gcm_sender_id)のサブスクリプションが - // 既に存在していることが原因でエラーになった可能性があるので、 - // そのサブスクリプションを解除しておく - // (これは実行されなさそうだけど、おまじない的に古い実装から残してある) - await unsubscribe(); - }), null, null); -} - -async function unsubscribe() { - if (!pushSubscription) return; - - const endpoint = pushSubscription.endpoint; - const accounts = await getAccounts(); - - pushRegistrationInServer = undefined; - - if ($i && accounts.length >= 2) { - apiWithDialog('sw/unregister', { - i: $i.token, - endpoint, - }); - } else { - pushSubscription.unsubscribe(); - apiWithDialog('sw/unregister', { - endpoint, - }); - pushSubscription = null; - } -} - -function encode(buffer: ArrayBuffer | null) { - return btoa(String.fromCharCode.apply(null, new Uint8Array(buffer))); -} - -/** - * Convert the URL safe base64 string to a Uint8Array - * @param base64String base64 string - */ - function urlBase64ToUint8Array(base64String: string): Uint8Array { - const padding = '='.repeat((4 - base64String.length % 4) % 4); - const base64 = (base64String + padding) - .replace(/-/g, '+') - .replace(/_/g, '/'); - - const rawData = window.atob(base64); - const outputArray = new Uint8Array(rawData.length); - - for (let i = 0; i < rawData.length; ++i) { - outputArray[i] = rawData.charCodeAt(i); - } - return outputArray; -} - -navigator.serviceWorker.ready.then(async swr => { - registration = swr; - - pushSubscription = await registration.pushManager.getSubscription(); - - if (instance.swPublickey && ('PushManager' in window) && $i && $i.token) { - supported = true; - - if (pushSubscription) { - const res = await api('sw/show-registration', { - endpoint: pushSubscription.endpoint, - }); - - if (res) { - pushRegistrationInServer = res; - } - } - } -}); - -defineExpose({ - pushRegistrationInServer: $$(pushRegistrationInServer), -}); -</script> |