clean up service worker

This commit is contained in:
m5r 2022-06-01 23:56:37 +02:00
parent 68570ff3d4
commit 7ca242fff4
8 changed files with 98 additions and 40 deletions

View File

@ -1,47 +1,29 @@
/// <reference lib="WebWorker" /> /// <reference lib="WebWorker" />
import type { NotificationPayload } from "~/utils/web-push.server"; import handleInstall from "./service-worker/install";
import { addBadge, removeBadge } from "~/utils/pwa.client"; import handleActivate from "./service-worker/activate";
import handlePush from "./service-worker/push";
import handleNotificationClick from "./service-worker/notification-click";
import handleFetch from "./service-worker/fetch";
declare let self: ServiceWorkerGlobalScope; declare let self: ServiceWorkerGlobalScope;
const defaultOptions: NotificationOptions = { self.addEventListener("install", (event) => {
icon: "/icons/android-chrome-192x192.png", event.waitUntil(handleInstall(event).then(() => self.skipWaiting()));
badge: "/icons/android-chrome-48x48.png", });
dir: "auto",
image: undefined, self.addEventListener("activate", (event) => {
silent: false, event.waitUntil(handleActivate(event).then(() => self.clients.claim()));
}; });
self.addEventListener("push", (event) => { self.addEventListener("push", (event) => {
const { title, ...payload }: NotificationPayload = JSON.parse(event?.data!.text()); event.waitUntil(handlePush(event));
const options = Object.assign({}, defaultOptions, payload);
event.waitUntil(async () => {
await self.registration.showNotification(title, options);
await addBadge(1);
});
}); });
self.addEventListener("notificationclick", (event) => { self.addEventListener("notificationclick", (event) => {
event.waitUntil( event.waitUntil(handleNotificationClick(event));
(async () => { });
console.log("On notification click: ", event.notification.tag);
// Android doesnt close the notification when you click on it self.addEventListener("fetch", (event) => {
// See: http://crbug.com/463146 event.respondWith(handleFetch(event));
event.notification.close();
await removeBadge();
if (event.action === "reply") {
const recipient = encodeURIComponent(event.notification.data.recipient);
return self.clients.openWindow?.(`/messages/${recipient}`);
}
if (event.action === "answer") {
const recipient = encodeURIComponent(event.notification.data.recipient);
return self.clients.openWindow?.(`/incoming-call/${recipient}`);
}
return self.clients.openWindow?.("/");
})(),
);
}); });

View File

@ -1,4 +1,4 @@
import { type FunctionComponent, type PropsWithChildren } from "react"; import type { FunctionComponent, PropsWithChildren } from "react";
import type { LinksFunction } from "@remix-run/node"; import type { LinksFunction } from "@remix-run/node";
import { Link, Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration, useCatch } from "@remix-run/react"; import { Link, Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration, useCatch } from "@remix-run/react";

View File

@ -2,12 +2,12 @@ import type { ActionFunction } from "@remix-run/node";
import { ClientOnly } from "remix-utils"; import { ClientOnly } from "remix-utils";
import { Form } from "@remix-run/react"; import { Form } from "@remix-run/react";
import db from "~/utils/db.server";
import { notify } from "~/utils/web-push.server"; import { notify } from "~/utils/web-push.server";
import Button from "~/features/settings/components/button"; import Button from "~/features/settings/components/button";
import NotificationsSettings, { import NotificationsSettings, {
FallbackNotificationsSettings, FallbackNotificationsSettings,
} from "~/features/settings/components/settings/notifications-settings"; } from "~/features/settings/components/settings/notifications-settings";
import db from "~/utils/db.server";
export const action: ActionFunction = async () => { export const action: ActionFunction = async () => {
const phoneNumber = await db.phoneNumber.findUnique({ const phoneNumber = await db.phoneNumber.findUnique({
@ -34,7 +34,7 @@ export const action: ActionFunction = async () => {
title: "Reply", title: "Reply",
}, },
], ],
data: { recipient: "+33613370787" }, data: { recipient: "+33613370787", type: "message" },
}); });
return null; return null;
}; };
@ -48,7 +48,7 @@ export default function Notifications() {
</div> </div>
<section> <section>
<Form method="post" action="/settings/notifications"> <Form method="post">
<Button variant="default" type="submit"> <Button variant="default" type="submit">
send it!!! send it!!!
</Button> </Button>

View File

@ -0,0 +1,10 @@
declare let self: ServiceWorkerGlobalScope;
export default async function handleActivate(event: ExtendableEvent) {
console.debug("Service worker activated");
// @ts-ignore
if (self.registration.navigationPreload) {
// @ts-ignore
await self.registration.navigationPreload.enable();
}
}

View File

@ -0,0 +1,10 @@
declare let self: ServiceWorkerGlobalScope;
export default async function handleFetch(event: FetchEvent & { preloadResponse?: Promise<Response | undefined> }) {
const preloaded = await event.preloadResponse;
if (preloaded) {
return preloaded;
}
return fetch(event.request);
}

View File

@ -0,0 +1,5 @@
declare let self: ServiceWorkerGlobalScope;
export default async function handleInstall(event: ExtendableEvent) {
console.debug("Service worker installed");
}

View File

@ -0,0 +1,32 @@
import { removeBadge } from "~/utils/pwa.client";
declare let self: ServiceWorkerGlobalScope;
// noinspection TypeScriptUnresolvedVariable
export default async function handleNotificationClick(event: NotificationEvent) {
console.debug("On notification click: ", event.notification.tag);
// Android doesnt close the notification when you click on it
// See: http://crbug.com/463146
event.notification.close();
await removeBadge();
const url = getUrl(event.notification.data);
return self.clients.openWindow?.(url);
}
type NotificationData = {
recipient: string;
type: "message" | "incoming-call";
};
function getUrl(data: NotificationData) {
const recipient = encodeURIComponent(data.recipient);
switch (data.type) {
case "message":
return `/messages/${recipient}`;
case "incoming-call":
return `/incoming-call/${recipient}`;
default:
return "/messages";
}
}

View File

@ -0,0 +1,19 @@
import type { NotificationPayload } from "~/utils/web-push.server";
import { addBadge } from "~/utils/pwa.client";
declare let self: ServiceWorkerGlobalScope;
const defaultOptions: NotificationOptions = {
icon: "/icons/android-chrome-192x192.png",
badge: "/icons/android-chrome-48x48.png",
dir: "auto",
image: undefined,
silent: false,
};
export default async function handlePush(event: PushEvent) {
const { title, ...payload }: NotificationPayload = event.data!.json();
const options = Object.assign({}, defaultOptions, payload);
await self.registration.showNotification(title, options);
await addBadge(1);
}