1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
// 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)
|