diff --git a/app/src/broadcast.ts b/app/src/broadcast.ts index 4570809..26198fe 100644 --- a/app/src/broadcast.ts +++ b/app/src/broadcast.ts @@ -2,7 +2,7 @@ import { onCleanup } from "solid-js"; import { Group, IncomingMessage } from "./database/schema"; export const BROADCAST_NAME = "meal"; -const broadcast = new BroadcastChannel(BROADCAST_NAME); +export const broadcast = new BroadcastChannel(BROADCAST_NAME); export type BroadcastMessage = | { @@ -13,6 +13,9 @@ export type BroadcastMessage = type: "Message received"; groupId: string; message: IncomingMessage; + } + | { + type: "Wipe"; }; export function broadcastMessage(message: BroadcastMessage) { diff --git a/app/src/routes/chat.tsx b/app/src/routes/chat.tsx index fc30d85..cdcb0dc 100644 --- a/app/src/routes/chat.tsx +++ b/app/src/routes/chat.tsx @@ -1,15 +1,6 @@ import { Navigate, useParams } from "@solidjs/router"; -import { - createEffect, - createResource, - For, - JSX, - Show, - Suspense, -} from "solid-js"; -import { getGroup } from "../database"; +import { For, JSX, Show, Suspense } from "solid-js"; import { setupCrackle } from "../useCrackle"; -import { useBroadcast } from "../broadcast"; import { useApp } from "../components/AppContextProvider"; // TODO take this inspiration https://firebasestorage.googleapis.com/v0/b/design-spec/o/projects%2Fgoogle-material-3%2Fimages%2Fly7219l1-1.png?alt=media&token=67ff316b-7515-4e9f-9971-4e580290b1f2 @@ -21,10 +12,11 @@ export default function Chat() { return ; } + const groupId: string = parameters.groupId; + const app = useApp(); - const group = () => - app.status === "ready" && app.getGroup(parameters.groupId); + const group = () => app.status === "ready" && app.getGroup(groupId); // const [group, { mutate }] = createResource(parameters.groupId, getGroup); // createEffect(() => { // const currentGroup = group(); @@ -58,7 +50,7 @@ export default function Chat() { const handle = await setupCrackle; await handle.sendMessage({ - groupId: parameters.groupId, + groupId, sentAt: new Date(), text, }); diff --git a/app/src/service-worker/serviceWorker.ts b/app/src/service-worker/serviceWorker.ts index fd493ea..3044108 100644 --- a/app/src/service-worker/serviceWorker.ts +++ b/app/src/service-worker/serviceWorker.ts @@ -245,7 +245,7 @@ const handler = { async wipe() { // Wipe client await Promise.all([ - getSocket.then((socket) => socket.close()), + broadcastMessage({ type: "Wipe" }), //TODO test what happens if clients have open connections to the database deleteDatabase(), deleteClient(), diff --git a/app/src/socketProxy.ts b/app/src/socketProxy.ts index bde976f..3358398 100644 --- a/app/src/socketProxy.ts +++ b/app/src/socketProxy.ts @@ -7,6 +7,7 @@ * See more [Leader election](https://en.wikipedia.org/wiki/Leader_election) */ +import { broadcast, BroadcastMessage } from "./broadcast"; import { messagesUrl } from "./messagesUrl"; import { setupCrackle } from "./useCrackle"; @@ -41,8 +42,19 @@ async function setUpWebsocket() { async function runSocket() { const closeController = new AbortController(); - // Respond to keep alive messages from other tabs + const socket = await setUpWebsocket(); + broadcast.addEventListener( + "message", + (event: MessageEvent) => { + if (event.data.type !== "Wipe") return; + socket.close(); + }, + { + once: true, + signal: closeController.signal, + } + ); socket.addEventListener( "error",