summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKit La Touche <kit@transneptune.net>2025-08-03 23:12:09 -0400
committerKit La Touche <kit@transneptune.net>2025-08-03 23:12:09 -0400
commiteaf95ece7dfb4d4d591b2f501183b2706653742e (patch)
treee406ba0a53dbf49d01058f65ff602341c34c9144
parente6cba7c6d273b400eb70d10b1cab8a3bcc42b251 (diff)
Add roughed-in UI for setting up notifications
-rw-r--r--ui/lib/components/NotificationSettings.svelte84
-rw-r--r--ui/routes/+layout.svelte88
-rw-r--r--ui/styles/forms.css3
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);
}