From aac662f702737a5abf09141ca27b1a5a83047a9a Mon Sep 17 00:00:00 2001 From: m5r Date: Sun, 12 Jun 2022 23:32:57 +0200 Subject: [PATCH] revalidate loaders on message reception --- app/features/core/hooks/use-revalidate.ts | 6 ++++++ .../core/hooks/use-service-worker-revalidate.ts | 11 ++++++----- app/service-worker/cache-utils.ts | 4 ++-- app/service-worker/push.ts | 11 ++++++++--- 4 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 app/features/core/hooks/use-revalidate.ts diff --git a/app/features/core/hooks/use-revalidate.ts b/app/features/core/hooks/use-revalidate.ts new file mode 100644 index 0000000..2d384c5 --- /dev/null +++ b/app/features/core/hooks/use-revalidate.ts @@ -0,0 +1,6 @@ +import { useFetcher } from "@remix-run/react"; + +export default function useRevalidate() { + const fetcher = useFetcher(); + return () => fetcher.submit({}, { method: "post", action: "/dev/null" }); +} diff --git a/app/features/core/hooks/use-service-worker-revalidate.ts b/app/features/core/hooks/use-service-worker-revalidate.ts index d86edf0..e3d507b 100644 --- a/app/features/core/hooks/use-service-worker-revalidate.ts +++ b/app/features/core/hooks/use-service-worker-revalidate.ts @@ -1,16 +1,17 @@ import { useEffect } from "react"; -import { useFetcher } from "@remix-run/react"; + +import useRevalidate from "./use-revalidate"; export default function useServiceWorkerRevalidate() { - const fetcher = useFetcher(); + const revalidate = useRevalidate(); useEffect(() => { - const channel = new BroadcastChannel("sw-messages"); + const channel = new BroadcastChannel("revalidate"); function onMessage(event: MessageEvent) { const isRefresh = event.data === "revalidateLoaderData"; if (isRefresh) { console.debug("Revalidating loaders data"); - fetcher.submit({}, { method: "post", action: "/dev/null" }); + revalidate(); } } @@ -19,5 +20,5 @@ export default function useServiceWorkerRevalidate() { channel.removeEventListener("message", onMessage); channel.close(); }; - }, [fetcher]); + }, [revalidate]); } diff --git a/app/service-worker/cache-utils.ts b/app/service-worker/cache-utils.ts index 4b16584..3767f13 100644 --- a/app/service-worker/cache-utils.ts +++ b/app/service-worker/cache-utils.ts @@ -117,7 +117,7 @@ export function fetchLoaderData(event: FetchEvent): Promise { // and if we had returned a cached response // tell the UI to fetch the latest data console.debug("Revalidate loader data", path); - const channel = new BroadcastChannel("sw-messages"); + const channel = new BroadcastChannel("revalidate"); channel.postMessage("revalidateLoaderData"); lastTimeRevalidated[path] = Date.now(); } @@ -193,7 +193,7 @@ export async function purgeMutatedLoaders(event: FetchEvent) { const cachedPathname = new URL(loader.url).pathname; const shouldPurge = cachedPathname.startsWith(rootPathname); - if (url.pathname === "/settings/phone") { + if (["/dev/null", "/settings/phone"].includes(url.pathname)) { // changes phone number or twilio account credentials // so purge messages and phone calls from cache return ( diff --git a/app/service-worker/push.ts b/app/service-worker/push.ts index 363f0ad..d10e36b 100644 --- a/app/service-worker/push.ts +++ b/app/service-worker/push.ts @@ -15,12 +15,17 @@ export default async function handlePush(event: PushEvent) { const payload: NotificationPayload = event.data!.json(); const options = Object.assign({}, defaultOptions, payload); + const revalidateChannel = new BroadcastChannel("revalidate"); + // should revalidate just "/messages" and `/messages/${encodeURIComponent(payload.data.recipient)}` + revalidateChannel.postMessage("revalidateLoaderData"); + revalidateChannel.close(); + const clients = await self.clients.matchAll({ type: "window" }); const hasOpenTab = clients.some((client) => client.focused === true); if (hasOpenTab) { - const channel = new BroadcastChannel("notifications"); - channel.postMessage(JSON.stringify(payload)); - channel.close(); + const notifyChannel = new BroadcastChannel("notifications"); + notifyChannel.postMessage(JSON.stringify(payload)); + notifyChannel.close(); } else { await self.registration.showNotification(payload.title, options); await addBadge(1);