// FIXME: This file should handle the sockets and the subscriptions import { io } from "socket.io-client"; import { v4 as uuidv4 } from "uuid"; import { createAlert } from "./notify"; import { fetchRoomConfig, joinRoom } from "../rooms"; import { getCanvas } from "../rooms/canvas"; import { initCanvas, renderCanvasUpdate } from "../rooms/canvas/utils"; import { sendTokenRequest } from "../utils/auth"; let subscribed = false; export let socket = undefined; const updateBuffer = []; // Exports must include // - initSocket (initialize the connection to the socket server) export async function initSocket() { if (!localStorage.getItem("token")) { if (!(await sendTokenRequest())) { createAlert("ForgeID", "Authentication failed", "error"); return; } createAlert("ForgeID", "Authentication successful", "success"); } if (socket) { return socket; } socket = io(import.meta.env.VITE_URL, { extraHeaders: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, }); socket.on("connect", () => { joinRoom(); }); socket.on("message", async (msg) => { if (msg.result && msg.result.type === "started") { const roomConfig = await fetchRoomConfig("epi-place"); if (!roomConfig) { return; } const pixels = await getCanvas("epi-place"); if (!pixels) { return; } initCanvas(roomConfig, pixels); // debuffer pixel updates catchUpOnUpdates(); subscribed = true; } }); socket.on("pixel-update", (update) => { if (!subscribed) { updateBuffer.push({ color: update.result.data.json.color, posX: update.result.data.json.posX, posY: update.result.data.json.posY, }); } else { renderCanvasUpdate( update.result.data.json.color, update.result.data.json.posX, update.result.data.json.posY, ); } }); return socket; } // - socket (variable resulting of initSocket function) // Functions may include: // - subscribe (subscribe to a room's stream or chat) export function subscribe(slug) { const subscription = { id: uuidv4(), method: "subscription", params: { path: "rooms.canvas.getStream", input: { json: { roomSlug: slug, }, }, }, }; socket.send(subscription); } function catchUpOnUpdates() { while (updateBuffer.length > 0) { const update = updateBuffer.pop(); renderCanvasUpdate(update.color, update.posX, update.posY); } } // - unsubscribe (unsubscribe from a room's stream or chat) // - sendMessage (send a message to a room's chat)