summaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorKit La Touche <kit@transneptune.net>2025-07-02 16:34:33 -0400
committerKit La Touche <kit@transneptune.net>2025-07-23 16:38:55 -0400
commitc21eb26c8d011932293aeec3afe4849740f7fdf8 (patch)
treed77c92b31dff49e6151d3b2ade851b12a88ad437 /ui
parentaec3eaeebd37bce9ab4dad14e7e86ef0db8f0c2d (diff)
Rough in client and server side of web-push
Diffstat (limited to 'ui')
-rw-r--r--ui/routes/+layout.svelte74
-rw-r--r--ui/service-worker.js9
2 files changed, 82 insertions, 1 deletions
diff --git a/ui/routes/+layout.svelte b/ui/routes/+layout.svelte
index 83a9ef7..0910c16 100644
--- a/ui/routes/+layout.svelte
+++ b/ui/routes/+layout.svelte
@@ -1,10 +1,76 @@
<script>
- import { setContext } from 'svelte';
+ import { setContext, onMount } 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 ==================== */
+ function doSubscribe() {
+ navigator.serviceWorker.ready
+ .then(async(registration) => {
+ console.debug("Beginning subscription");
+ const response = await fetch("/api/vapid");
+ // and if we fail to get it?
+ const vapidPublicKey = await response.text();
+ // Chrome doesn't accept the base64-encoded (string) vapidPublicKey yet
+ // urlBase64ToUint8Array() is defined in /tools.js
+ // const convertedVapidKey = urlBase64ToUint8Array(vapidPublicKey);
+ const convertedVapidKey = vapidPublicKey;
+ // Subscribe the user
+ return registration.pushManager.subscribe({
+ userVisibleOnly: true,
+ applicationServerKey: convertedVapidKey
+ });
+ }).then((subscription) => {
+ debugger;
+ console.debug("Subscribed", subscription.endpoint);
+ return fetch("/api/register", {
+ method: "post",
+ headers: { "Content-type": "application/json" },
+ body: JSON.stringify({ subscription: subscription })
+ });
+ });
+ }
+
+ async function doUnsubscribe() {
+ navigator.serviceWorker.ready
+ .then((registration) => {
+ return registration.pushManager.getSubscription();
+ }).then((subscription) => {
+ return subscription.unsubscribe()
+ .then(function() {
+ console.log("Unsubscribed", subscription.endpoint);
+ return fetch("/api/unregister", {
+ method: "post",
+ headers: { "Content-type": "application/json" },
+ body: JSON.stringify({ subscription })
+ });
+ });
+ });
+ }
+
+ function notifyMe() {
+ fetch("/api/echo", {
+ method: "post",
+ headers: { "Content-type": "application/json" },
+ body: JSON.stringify({ msg: "oople doople" })
+ });
+ }
+
+ onMount(() => {
+ navigator.serviceWorker.ready.then((registration) => {
+ return registration.pushManager.getSubscription();
+ }).then((subscription) => {
+ if (subscription) {
+ console.debug("Already subscribed", subscription.endpoint);
+ } else {
+ doSubscribe();
+ }
+ });
+ });
+ /* ==================== END ==================== */
+
const session = $derived(page.data.session);
let pageContext = $state({
showMenu: false,
@@ -30,6 +96,12 @@
</button>
</div>
<a href="/">pilcrow</a>
+ <button onclick="{notifyMe}">
+ notify
+ </button>
+ <button onclick="{doUnsubscribe}">
+ unsub
+ </button>
<div class="trail">
{#if session}
<div>
diff --git a/ui/service-worker.js b/ui/service-worker.js
index d9b2a7c..319b251 100644
--- a/ui/service-worker.js
+++ b/ui/service-worker.js
@@ -52,3 +52,12 @@ async function cacheFirst(request) {
self.addEventListener('fetch', (event) => {
event.respondWith(cacheFirst(event.request));
});
+
+self.addEventListener('push', (event) => {
+ const payload = event.data?.text() ?? "no payload";
+ event.waitUntil(
+ self.registration.showNotification("ServiceWorker Cookbook", {
+ body: payload,
+ }),
+ );
+});