diff options
| author | Kit La Touche <kit@transneptune.net> | 2025-08-03 23:12:09 -0400 |
|---|---|---|
| committer | Kit La Touche <kit@transneptune.net> | 2025-08-03 23:12:09 -0400 |
| commit | eaf95ece7dfb4d4d591b2f501183b2706653742e (patch) | |
| tree | e406ba0a53dbf49d01058f65ff602341c34c9144 | |
| parent | e6cba7c6d273b400eb70d10b1cab8a3bcc42b251 (diff) | |
Add roughed-in UI for setting up notifications
| -rw-r--r-- | ui/lib/components/NotificationSettings.svelte | 84 | ||||
| -rw-r--r-- | ui/routes/+layout.svelte | 88 | ||||
| -rw-r--r-- | ui/styles/forms.css | 3 |
3 files changed, 84 insertions, 91 deletions
diff --git a/ui/lib/components/NotificationSettings.svelte b/ui/lib/components/NotificationSettings.svelte index c690b21..81c3708 100644 --- a/ui/lib/components/NotificationSettings.svelte +++ b/ui/lib/components/NotificationSettings.svelte @@ -1,13 +1,89 @@ <script> + import { onMount } from "svelte"; import Toggle from '$lib/components/Toggle.svelte'; - // let { invites, createInvite = async () => {} } = $props(); - async function onsubmit(event) { - event.preventDefault(); - await createInvite(); + let subscriptionJson = $state(null); + + function doSubscribe() { + navigator.serviceWorker.ready + .then(async (registration) => { + const response = await fetch("/api/vapid"); + // and if we fail to get it? + const vapidPublicKey = await response.text(); + const convertedVapidKey = vapidPublicKey; + return registration.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: convertedVapidKey + }); + }).then((subscription) => { + const subJson = subscription.toJSON(); + subscriptionJson = { + endpoint: subJson.endpoint, + p256dh: subJson.keys.p256dh, + auth: subJson.keys.auth, + }; + return fetch("/api/push", { + method: "post", + headers: { "Content-type": "application/json" }, + body: JSON.stringify(subscriptionJson), + }); + }); + } + + function doUnsubscribe() { + navigator.serviceWorker.ready + .then((registration) => { + return registration.pushManager.getSubscription(); + }).then((subscription) => { + const { endpoint } = subscription.toJSON(); + return subscription.unsubscribe() + .then(() => { + fetch("/api/push", { + method: "delete", + headers: { "Content-type": "application/json" }, + body: JSON.stringify({ endpoint }), + }); + subscriptionJson = null; + }); + }); + } + + function toggleSub() { + if (subscriptionJson !== null) { + doUnsubscribe(); + } else { + doSubscribe(); + } } + + onMount(() => { + navigator.serviceWorker.ready.then((registration) => { + return registration.pushManager.getSubscription(); + }).then((subscription) => { + if (subscription) { + subscriptionJson = JSON.parse(JSON.stringify(subscription)); + } + }); + }); </script> +<h2>Enable notifications</h2> + +<p> + {#if subscriptionJson === null} + Notifications are currently disabled. + {:else} + Notifications are currently enabled. + {/if} +</p> +<button class="btn" onclick="{toggleSub}"> + {#if subscriptionJson === null} + Enable notifications + {:else} + Disable notifications + {/if} +</button> + <h2>Notify me when:</h2> <Toggle diff --git a/ui/routes/+layout.svelte b/ui/routes/+layout.svelte index 841d597..8412fbc 100644 --- a/ui/routes/+layout.svelte +++ b/ui/routes/+layout.svelte @@ -1,87 +1,10 @@ <script> - import { setContext, onMount } from "svelte"; + import { setContext } from "svelte"; import { onNavigate } from '$app/navigation'; import { page } from '$app/state'; import '../app.css'; import logo from '$lib/assets/logo.png'; - /* ==================== Start subscription library-esque ==================== */ - let subscriptionJson = $state(null); - - function doSubscribe() { - navigator.serviceWorker.ready - .then(async (registration) => { - const response = await fetch("/api/vapid"); - // and if we fail to get it? - const vapidPublicKey = await response.text(); - const convertedVapidKey = vapidPublicKey; - return registration.pushManager.subscribe({ - userVisibleOnly: true, - applicationServerKey: convertedVapidKey - }); - }).then((subscription) => { - const subJson = subscription.toJSON(); - subscriptionJson = { - endpoint: subJson.endpoint, - p256dh: subJson.keys.p256dh, - auth: subJson.keys.auth, - }; - return fetch("/api/push", { - method: "post", - headers: { "Content-type": "application/json" }, - body: JSON.stringify(subscriptionJson), - }); - }); - } - - async function doUnsubscribe() { - navigator.serviceWorker.ready - .then((registration) => { - return registration.pushManager.getSubscription(); - }).then((subscription) => { - const { endpoint } = subscription.toJSON(); - return subscription.unsubscribe() - .then(() => { - fetch("/api/push", { - method: "delete", - headers: { "Content-type": "application/json" }, - body: JSON.stringify({ endpoint }), - }); - subscriptionJson = null; - }); - }); - } - - function toggleSub() { - if (subscriptionJson !== null) { - doUnsubscribe(); - } else { - doSubscribe(); - } - } - - function notifyMe() { - fetch("/api/echo", { - method: "post", - headers: { "Content-type": "application/json" }, - body: JSON.stringify({ - endpoint: subscriptionJson.endpoint, - msg: JSON.stringify({"msg": "oople doople"}), - }) - }); - } - - onMount(() => { - navigator.serviceWorker.ready.then((registration) => { - return registration.pushManager.getSubscription(); - }).then((subscription) => { - if (subscription) { - subscriptionJson = JSON.parse(JSON.stringify(subscription)); - } - }); - }); - /* ==================== END ==================== */ - const session = $derived(page.data.session); let pageContext = $state({ showMenu: false, @@ -107,15 +30,6 @@ </button> </div> <a href="/">pilcrow</a> - <button onclick="{notifyMe}"> - notify - </button> - <button onclick="{toggleSub}"> - toggle sub - </button> - <div> - hasSub: {subscriptionJson !== null} - </div> <div class="trail"> {#if session} <div> diff --git a/ui/styles/forms.css b/ui/styles/forms.css index f4d218f..1cc44a3 100644 --- a/ui/styles/forms.css +++ b/ui/styles/forms.css @@ -13,6 +13,7 @@ label input { border: 1px solid var(--colour-input-border); } +.btn, form.form > button { font-family: 'Overlock', cursive; background-color: var(--colour-input-bg); @@ -23,6 +24,8 @@ form.form > button { margin: 0.25rem; } +button[disabled], .disabled { + opacity: 0.6; color: var(--light-text); } |
