gamja-webpush.diff

on erock's pastes | raw

expires: 11 Jan, 2024

  1diff --git a/components/app.js b/components/app.js
  2index 4788788..ec5d74a 100644
  3--- a/components/app.js
  4+++ b/components/app.js
  5@@ -28,6 +28,21 @@ const baseConfig = {
  6 	server: {},
  7 };
  8 
  9+function urlBase64ToUint8Array(base64String) {
 10+	var padding = '='.repeat((4 - base64String.length % 4) % 4);
 11+	var base64 = (base64String + padding)
 12+		.replace(/\-/g, '+')
 13+		.replace(/_/g, '/');
 14+
 15+	var rawData = window.atob(base64);
 16+	var outputArray = new Uint8Array(rawData.length);
 17+
 18+	for (var i = 0; i < rawData.length; ++i) {
 19+		outputArray[i] = rawData.charCodeAt(i);
 20+	}
 21+	return outputArray;
 22+}
 23+
 24 const configPromise = fetch("./config.json")
 25 	.then((resp) => {
 26 		if (resp.ok) {
 27@@ -981,9 +996,37 @@ export default class App extends Component {
 28 				affectedBuffers.push(prefix.name);
 29 			}
 30 			return affectedBuffers;
 31+		case irc.RPL_ISUPPORT: {
 32+			const params = msg.params;
 33+			for (const p of params) {
 34+				if (p.indexOf("VAPID") === 0) {
 35+					const value = p.replace("VAPID=", "");
 36+					const vapidPubKey = urlBase64ToUint8Array(value);
 37+					navigator.serviceWorker.ready.then((registration) => {
 38+					return registration.pushManager.getSubscription()
 39+					.then((subscription) => {
 40+						if (subscription) {
 41+							return subscription;
 42+						}
 43+						return registration.pushManager.subscribe({
 44+							userVisibleOnly: true,
 45+							applicationServerKey: vapidPubKey,
 46+						});
 47+					}).then((subscription) => {
 48+						var data = subscription.toJSON();
 49+						var keysStr = irc.formatTags(data.keys);
 50+						client.send({
 51+							command: "WEBPUSH",
 52+							params: ["REGISTER", data.endpoint, keysStr],
 53+						});
 54+					});
 55+				});
 56+				}
 57+			}
 58+			return [];
 59+		}
 60 		case irc.RPL_YOURHOST:
 61 		case irc.RPL_MYINFO:
 62-		case irc.RPL_ISUPPORT:
 63 		case irc.RPL_ENDOFMOTD:
 64 		case irc.ERR_NOMOTD:
 65 		case irc.RPL_AWAY:
 66diff --git a/lib/client.js b/lib/client.js
 67index a1a969a..90e736e 100644
 68--- a/lib/client.js
 69+++ b/lib/client.js
 70@@ -25,6 +25,7 @@ const permanentCaps = [
 71 	"draft/read-marker",
 72 
 73 	"soju.im/bouncer-networks",
 74+	"soju.im/webpush",
 75 ];
 76 
 77 const RECONNECT_MIN_DELAY_MSEC = 10 * 1000; // 10s
 78diff --git a/main.js b/main.js
 79index 2b73e7d..93a7737 100644
 80--- a/main.js
 81+++ b/main.js
 82@@ -1,4 +1,6 @@
 83 import { html, render } from "./lib/index.js";
 84 import App from "./components/app.js";
 85 
 86+navigator.serviceWorker.register("./service-worker.js").catch(console.error);
 87+
 88 render(html`<${App}/>`, document.body);
 89diff --git a/service-worker.js b/service-worker.js
 90new file mode 100644
 91index 0000000..6398c4e
 92--- /dev/null
 93+++ b/service-worker.js
 94@@ -0,0 +1,6 @@
 95+self.addEventListener("push", (event) => {
 96+	var payload = event.data ? event.data.text() : "no payload";
 97+	event.waitUntil(self.registration.showNotification("gamja service worker", {
 98+		body: payload,
 99+	}));
100+});