mirror of
https://git.sr.ht/~emersion/gamja
synced 2024-11-25 09:07:56 -05:00
wip: add support for WEBPUSH
This commit is contained in:
parent
32012bbea5
commit
dc6614e4ff
5 changed files with 70 additions and 0 deletions
|
@ -23,6 +23,7 @@ import { SERVER_BUFFER, BufferType, ReceiptType, ServerStatus, Unread, BufferEve
|
||||||
import commands from "../commands.js";
|
import commands from "../commands.js";
|
||||||
import { setup as setupKeybindings } from "../keybindings.js";
|
import { setup as setupKeybindings } from "../keybindings.js";
|
||||||
import * as store from "../store.js";
|
import * as store from "../store.js";
|
||||||
|
import * as webpush from "../webpush.js";
|
||||||
|
|
||||||
const baseConfig = {
|
const baseConfig = {
|
||||||
server: {},
|
server: {},
|
||||||
|
@ -1095,6 +1096,10 @@ export default class App extends Component {
|
||||||
switch (msg.command) {
|
switch (msg.command) {
|
||||||
case irc.RPL_WELCOME:
|
case irc.RPL_WELCOME:
|
||||||
this.fetchBacklog(serverID);
|
this.fetchBacklog(serverID);
|
||||||
|
if (client.enabledCaps["soju.im/webpush"]) {
|
||||||
|
// TODO: check if notifications are enabled
|
||||||
|
webpush.register(client);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case irc.RPL_ENDOFMOTD:
|
case irc.RPL_ENDOFMOTD:
|
||||||
case irc.ERR_NOMOTD:
|
case irc.ERR_NOMOTD:
|
||||||
|
|
|
@ -24,6 +24,7 @@ const permanentCaps = [
|
||||||
"draft/read-marker",
|
"draft/read-marker",
|
||||||
|
|
||||||
"soju.im/bouncer-networks",
|
"soju.im/bouncer-networks",
|
||||||
|
"soju.im/webpush",
|
||||||
];
|
];
|
||||||
|
|
||||||
const RECONNECT_MIN_DELAY_MSEC = 10 * 1000; // 10s
|
const RECONNECT_MIN_DELAY_MSEC = 10 * 1000; // 10s
|
||||||
|
|
2
main.js
2
main.js
|
@ -1,4 +1,6 @@
|
||||||
import { html, render } from "./lib/index.js";
|
import { html, render } from "./lib/index.js";
|
||||||
import App from "./components/app.js";
|
import App from "./components/app.js";
|
||||||
|
|
||||||
|
navigator.serviceWorker.register("./service-worker.js");
|
||||||
|
|
||||||
render(html`<${App}/>`, document.body);
|
render(html`<${App}/>`, document.body);
|
||||||
|
|
6
service-worker.js
Normal file
6
service-worker.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
self.addEventListener("push", (event) => {
|
||||||
|
var payload = event.data ? event.data.text() : "no payload";
|
||||||
|
event.waitUntil(self.registration.showNotification("gamja service worker", {
|
||||||
|
body: payload,
|
||||||
|
}));
|
||||||
|
});
|
56
webpush.js
Normal file
56
webpush.js
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import * as irc from "./lib/irc.js";
|
||||||
|
|
||||||
|
async function register(client) {
|
||||||
|
let encodedVapidPubkey = client.isupport.get("VAPID");
|
||||||
|
if (!encodedVapidPubkey) {
|
||||||
|
throw new Error("Server is missing VAPID public key");
|
||||||
|
}
|
||||||
|
let vapidPubKey = urlBase64ToUint8Array(encodedVapidPubkey);
|
||||||
|
|
||||||
|
let registration = await navigator.serviceWorker.ready;
|
||||||
|
let subscription = registration.pushManager.getSubscription();
|
||||||
|
if (subscription && !compareVapidPubkeys(subscription.options.applicationServerKey, vapidPubKey)) {
|
||||||
|
await subscription.unsubscribe();
|
||||||
|
subscription = null;
|
||||||
|
}
|
||||||
|
if (!subscription) {
|
||||||
|
subscription = await registration.pushManager.subscribe({
|
||||||
|
userVisibleOnly: true,
|
||||||
|
applicationServerKey: vapidPubKey,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = subscription.toJSON();
|
||||||
|
var keysStr = irc.formatTags(data.keys);
|
||||||
|
client.send({
|
||||||
|
command: "WEBPUSH",
|
||||||
|
params: ["REGISTER", data.endpoint, keysStr],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function urlBase64ToUint8Array(base64String) {
|
||||||
|
var padding = '='.repeat((4 - base64String.length % 4) % 4);
|
||||||
|
var base64 = (base64String + padding)
|
||||||
|
.replace(/\-/g, '+')
|
||||||
|
.replace(/_/g, '/');
|
||||||
|
|
||||||
|
var rawData = window.atob(base64);
|
||||||
|
var outputArray = new Uint8Array(rawData.length);
|
||||||
|
|
||||||
|
for (var i = 0; i < rawData.length; ++i) {
|
||||||
|
outputArray[i] = rawData.charCodeAt(i);
|
||||||
|
}
|
||||||
|
return outputArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
function compareVapidPubkeys(a, b) {
|
||||||
|
if (a.length !== b.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < a.length; i++) {
|
||||||
|
if (a[i] !== b[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
Loading…
Reference in a new issue