From 1e4cd71e06b26c4da07768862303b61a72c01c82 Mon Sep 17 00:00:00 2001 From: Guillem George Date: Sat, 16 May 2026 18:18:56 +0200 Subject: [PATCH 1/7] bk --- src/pages/index.js | 4 ++++ src/rooms/canvas/index.js | 2 +- src/rooms/canvas/utils.js | 6 ++++++ src/rooms/index.js | 3 ++- src/students/index.js | 2 +- 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/pages/index.js b/src/pages/index.js index 18dd801..606bef0 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -101,3 +101,7 @@ const placeButtonElt = document.getElementById("color-place-button"); placeButtonElt.addEventListener("click", () => { placePixelButton(); }); + +export { + room +} diff --git a/src/rooms/canvas/index.js b/src/rooms/canvas/index.js index d3fe575..644a73b 100644 --- a/src/rooms/canvas/index.js +++ b/src/rooms/canvas/index.js @@ -89,7 +89,7 @@ async function getPixelInfo(room, posX, posY) { const response = await authedAPIRequest( "/rooms/" + room + "/canvas/pixels", { - method: "POST", + method: "GET", headers: { "Content-Type": "application/json", }, diff --git a/src/rooms/canvas/utils.js b/src/rooms/canvas/utils.js index c6feb9e..ba7fef5 100644 --- a/src/rooms/canvas/utils.js +++ b/src/rooms/canvas/utils.js @@ -6,6 +6,8 @@ // - toggleTooltip (toggle the tooltip and display the pixel's information) import $ from "jquery"; +import { getPixelInfo } from "./index"; +import { room } from "../../pages/index"; const canvasContainer = $("#canvas-container")?.[0]; const canvas = $("#canvas")?.[0]; @@ -60,6 +62,10 @@ export const toggleTooltip = async (state = false) => { if (state) { // FIXME: You should implement or call a function to get the pixel's information // and display it. Make use of target.x and target.y to get the pixel's position. + const response = await getPixelInfo(room, target.x, target.y); + if (!response) { + return; + } } }; diff --git a/src/rooms/index.js b/src/rooms/index.js index 0364732..1e53671 100644 --- a/src/rooms/index.js +++ b/src/rooms/index.js @@ -1,6 +1,7 @@ import { authedAPIRequest } from "../utils/auth"; import { subscribe } from "../utils/streams"; import { resetValues } from "./canvas/utils"; +import { room } from "../pages/index" // FIXME: This file should handle the rooms API // Functions may include: // - fetchRoomConfig (get the configuration of a room) @@ -19,7 +20,7 @@ function setCurrentRoomConfig(cfg) { } async function getCurrentRoomConfig() { if (!roomConfig) { - await fetchRoomConfig(); + await fetchRoomConfig(room); } return roomConfig; diff --git a/src/students/index.js b/src/students/index.js index b7fab1e..5c84a45 100644 --- a/src/students/index.js +++ b/src/students/index.js @@ -13,7 +13,7 @@ async function getStudent(login) { if (!response || !response.ok) { console.error( - "Could not retrieve student: " + response + "Could not retrieve student: " + response && response.statusText ? response.statusText : " no status text", ); From e84731e8dedb7d9126b87beed1c7f1945810af85 Mon Sep 17 00:00:00 2001 From: Guillem George Date: Sat, 16 May 2026 18:51:01 +0200 Subject: [PATCH 2/7] pieds --- src/pages/index.js | 23 ++++++++++++++++++----- src/rooms/canvas/index.js | 10 +++++----- src/rooms/canvas/utils.js | 14 +++++++++++--- src/rooms/index.js | 3 +-- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/pages/index.js b/src/pages/index.js index 606bef0..fde38e0 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -19,6 +19,8 @@ await authenticate(); // Sockets // let room = window.location.pathname.split("/")[1]; +const update_waitlist = []; +const initialized = false; if (!room) { room = "epi-place"; @@ -50,7 +52,15 @@ socket.on("message", async (response) => { return; } - initCanvas(await getCurrentRoomConfig(), pixels); + initCanvas(await getCurrentRoomConfig(room), pixels); + while (update_waitlist.length > 0) { + const obj = update_waitlist.pop(); + + if (obj) { + renderCanvasUpdate(obj.color, obj.posX, obj.posY); + } + } + console.debug("Loaded canvas"); }); @@ -71,7 +81,7 @@ socket.on("pixel-update", async (msg) => { color, } = msg.result.data.json; - const cfg = await getCurrentRoomConfig(); + const cfg = await getCurrentRoomConfig(room); if (!cfg || !cfg.settings || !cfg.settings.roomColors) { console.error( @@ -81,6 +91,11 @@ socket.on("pixel-update", async (msg) => { return; } + if (!initialized) { + update_waitlist.push({ posX, posY, color }); + return; + } + renderCanvasUpdate(color, posX, posY); }); @@ -102,6 +117,4 @@ placeButtonElt.addEventListener("click", () => { placePixelButton(); }); -export { - room -} +export { room }; diff --git a/src/rooms/canvas/index.js b/src/rooms/canvas/index.js index 644a73b..c7343fe 100644 --- a/src/rooms/canvas/index.js +++ b/src/rooms/canvas/index.js @@ -86,17 +86,17 @@ async function getPixelInfo(room, posX, posY) { return null; } + const params = new URLSearchParams({ + posX, + posY, + }); const response = await authedAPIRequest( - "/rooms/" + room + "/canvas/pixels", + "/rooms/" + room + "/canvas/pixels" + "?" + params, { method: "GET", headers: { "Content-Type": "application/json", }, - body: JSON.stringify({ - posX, - posY, - }), }, ); diff --git a/src/rooms/canvas/utils.js b/src/rooms/canvas/utils.js index ba7fef5..2e5ac33 100644 --- a/src/rooms/canvas/utils.js +++ b/src/rooms/canvas/utils.js @@ -7,7 +7,6 @@ import $ from "jquery"; import { getPixelInfo } from "./index"; -import { room } from "../../pages/index"; const canvasContainer = $("#canvas-container")?.[0]; const canvas = $("#canvas")?.[0]; @@ -60,12 +59,21 @@ export const toggleTooltip = async (state = false) => { tooltip.style.display = state ? "flex" : "none"; if (state) { - // FIXME: You should implement or call a function to get the pixel's information - // and display it. Make use of target.x and target.y to get the pixel's position. + // Get pixel + const room = window.location.pathname.split("/")[1] || "epi-place"; const response = await getPixelInfo(room, target.x, target.y); + if (!response) { return; } + + // Display + const date = new Date(response.timestamp * 1000); + + document.getElementById("tooltip-date").innerText = + date.toLocaleDateString(); + document.getElementById("tooltip-time").innerText = + date.toLocaleTimeString(); } }; diff --git a/src/rooms/index.js b/src/rooms/index.js index 1e53671..784ddf4 100644 --- a/src/rooms/index.js +++ b/src/rooms/index.js @@ -1,7 +1,6 @@ import { authedAPIRequest } from "../utils/auth"; import { subscribe } from "../utils/streams"; import { resetValues } from "./canvas/utils"; -import { room } from "../pages/index" // FIXME: This file should handle the rooms API // Functions may include: // - fetchRoomConfig (get the configuration of a room) @@ -18,7 +17,7 @@ let roomConfig = null; function setCurrentRoomConfig(cfg) { roomConfig = cfg; } -async function getCurrentRoomConfig() { +async function getCurrentRoomConfig(room) { if (!roomConfig) { await fetchRoomConfig(room); } From 3914fbdba8a21ac6c6d5d6064e60c818e6c8cab4 Mon Sep 17 00:00:00 2001 From: Guillem George Date: Sat, 16 May 2026 18:55:37 +0200 Subject: [PATCH 3/7] nbvgdfsgrcolulwqhr4wkjbv --- src/rooms/canvas/index.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/rooms/canvas/index.js b/src/rooms/canvas/index.js index c7343fe..9e1d0bf 100644 --- a/src/rooms/canvas/index.js +++ b/src/rooms/canvas/index.js @@ -15,11 +15,15 @@ async function fetchCanvas(room) { }); if (!response || !response.ok) { + // console.error( + // "Could not retrieve room canvas: " + response && response.statusText + // ? response.statusText + // : "no more informations", + // ); console.error( - "Could not retrieve room canvas: " + response && response.statusText - ? response.statusText - : "no more informations", + "Could not retrieve room canvas: nique ta mère la moulinette", ); + // console.debug(await response.text()); return null; } From b7d988048bac6f8a10f0db7a0b61e832a8beff44 Mon Sep 17 00:00:00 2001 From: Guillem George Date: Sat, 16 May 2026 19:02:11 +0200 Subject: [PATCH 4/7] manger --- src/pages/index.js | 30 +++++++++--------------------- src/rooms/index.js | 6 +++--- 2 files changed, 12 insertions(+), 24 deletions(-) diff --git a/src/pages/index.js b/src/pages/index.js index fde38e0..403ad60 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -19,8 +19,8 @@ await authenticate(); // Sockets // let room = window.location.pathname.split("/")[1]; -const update_waitlist = []; -const initialized = false; +let update_waitlist = [] +let initialized = false; if (!room) { room = "epi-place"; @@ -54,13 +54,10 @@ socket.on("message", async (response) => { initCanvas(await getCurrentRoomConfig(room), pixels); while (update_waitlist.length > 0) { - const obj = update_waitlist.pop(); - - if (obj) { - renderCanvasUpdate(obj.color, obj.posX, obj.posY); - } + const obj = update_waitlist.pop() + if (obj) + renderCanvasUpdate(obj.color, obj.posX, obj.posY) } - console.debug("Loaded canvas"); }); @@ -81,21 +78,10 @@ socket.on("pixel-update", async (msg) => { color, } = msg.result.data.json; - const cfg = await getCurrentRoomConfig(room); - - if (!cfg || !cfg.settings || !cfg.settings.roomColors) { - console.error( - "Internal error: Cannot access config after retrieving it", - ); - console.debug(cfg); - return; - } - if (!initialized) { - update_waitlist.push({ posX, posY, color }); + update_waitlist.push({posX, posY, color}) return; } - renderCanvasUpdate(color, posX, posY); }); @@ -117,4 +103,6 @@ placeButtonElt.addEventListener("click", () => { placePixelButton(); }); -export { room }; +export { + room +} diff --git a/src/rooms/index.js b/src/rooms/index.js index 784ddf4..1643d41 100644 --- a/src/rooms/index.js +++ b/src/rooms/index.js @@ -103,9 +103,9 @@ async function fetchRoomConfig(room) { setCurrentRoomConfig(res); // Update HTML - const roomNameElt = document.getElementById("room-name"); - - roomNameElt.innerText = res.metadata.name; + document.getElementById("room-name").innerText = res.metadata.name; + document.getElementById("room-description").innerText = res.metadata.description; + document.getElementById("room-description").style.display = "block"; } export { From 34e5527244445e2064d2a07600a088d8c96b3820 Mon Sep 17 00:00:00 2001 From: Guillem George Date: Sat, 16 May 2026 20:15:03 +0200 Subject: [PATCH 5/7] non mais srx --- src/pages/index.js | 19 +++++++++++-------- src/rooms/index.js | 3 ++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/pages/index.js b/src/pages/index.js index 403ad60..4172042 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -19,7 +19,7 @@ await authenticate(); // Sockets // let room = window.location.pathname.split("/")[1]; -let update_waitlist = [] +const update_waitlist = []; let initialized = false; if (!room) { @@ -53,11 +53,15 @@ socket.on("message", async (response) => { } initCanvas(await getCurrentRoomConfig(room), pixels); + initialized = true; while (update_waitlist.length > 0) { - const obj = update_waitlist.pop() - if (obj) - renderCanvasUpdate(obj.color, obj.posX, obj.posY) + const obj = update_waitlist.pop(); + + if (obj) { + renderCanvasUpdate(obj.color, obj.posX, obj.posY); + } } + console.debug("Loaded canvas"); }); @@ -79,9 +83,10 @@ socket.on("pixel-update", async (msg) => { } = msg.result.data.json; if (!initialized) { - update_waitlist.push({posX, posY, color}) + update_waitlist.push({ posX, posY, color }); return; } + renderCanvasUpdate(color, posX, posY); }); @@ -103,6 +108,4 @@ placeButtonElt.addEventListener("click", () => { placePixelButton(); }); -export { - room -} +export { room }; diff --git a/src/rooms/index.js b/src/rooms/index.js index 1643d41..ddc6e8d 100644 --- a/src/rooms/index.js +++ b/src/rooms/index.js @@ -104,7 +104,8 @@ async function fetchRoomConfig(room) { // Update HTML document.getElementById("room-name").innerText = res.metadata.name; - document.getElementById("room-description").innerText = res.metadata.description; + document.getElementById("room-description").innerText = + res.metadata.description; document.getElementById("room-description").style.display = "block"; } From 77a6d7fa6c6ee1c77384cc46802e7f3ad02cbf7a Mon Sep 17 00:00:00 2001 From: Guillem George Date: Sat, 16 May 2026 20:29:28 +0200 Subject: [PATCH 6/7] oh la la --- src/rooms/canvas/utils.js | 2 ++ src/students/index.js | 4 ++-- src/students/utils.js | 16 +++++++++++----- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/rooms/canvas/utils.js b/src/rooms/canvas/utils.js index 2e5ac33..b7e1855 100644 --- a/src/rooms/canvas/utils.js +++ b/src/rooms/canvas/utils.js @@ -7,6 +7,7 @@ import $ from "jquery"; import { getPixelInfo } from "./index"; +import { getStudent } from "../../students"; const canvasContainer = $("#canvas-container")?.[0]; const canvas = $("#canvas")?.[0]; @@ -74,6 +75,7 @@ export const toggleTooltip = async (state = false) => { date.toLocaleDateString(); document.getElementById("tooltip-time").innerText = date.toLocaleTimeString(); + getStudent(response.placedByUid); } }; diff --git a/src/students/index.js b/src/students/index.js index 5c84a45..55a6b7d 100644 --- a/src/students/index.js +++ b/src/students/index.js @@ -1,4 +1,5 @@ import { authedAPIRequest } from "../utils/auth"; +import { displayStudentProfile } from "./utils"; //get a student from the API by its uid or login async function getStudent(login) { @@ -27,8 +28,7 @@ async function getStudent(login) { console.debug(res); // Update HTML - // const roomNameElt = document.getElementById("room-name"); - // roomNameElt.innerText = res.metadata.name + displayStudentProfile(res.avatarURL, res.login, res.guild, res.quote); } //// get the user's uid from the token in local storage diff --git a/src/students/utils.js b/src/students/utils.js index 09bb32e..eb7d2b2 100644 --- a/src/students/utils.js +++ b/src/students/utils.js @@ -1,5 +1,11 @@ -// FIXME: This file should handle the students DOM manipulation -// Link buttons to their respective functions -// Functions may include: -// - displayStudentProfile (display the student's profile in the DOM) -// - showModal (add a form modal to the DOM) +// display the student's profile in the DOM +function displayStudentProfile(picture, login, guild, quote) { + document.getElementById("tooltip-info-avatar").src = picture; + document.getElementById("tooltip-info-login").innerText = login; + document.getElementById("tooltip-info-guild").innerText = guild; + document.getElementById("tooltip-info-quote").innerText = quote; +} +// add a form modal to the DOM +function showModal() {} + +export { displayStudentProfile, showModal }; From 206de2c05e7780816d69f1d6734447b5d28f30e4 Mon Sep 17 00:00:00 2001 From: Guillem George Date: Sat, 16 May 2026 21:30:07 +0200 Subject: [PATCH 7/7] Added README --- README.md | 10 ++++++++++ src/rooms/canvas/utils.js | 6 +++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e69de29..379fca9 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,10 @@ +# E/Place + +> **Note** This is a school project, therefore it probably won't interest you if you are looking for something useful. + +## Overview + +The goal of this rush was to implement a client for a r/place-like canvas. For those who don't know what I'm taliking about, r/place was an event on reddit where you had a world map where you could place a pixel of color every 5 minutes where you wanted. +This is basically the same thing: It first authenticates the user via OpenID, then connects to the server using Sockets.IO and a REST API simultaneously. Then it allows the user to place pixels, choose the color, view other people pixels, create or join rooms or customize profile, all with real time map update. +We had approximately 2 days to implement the client. The server socket, the API, and the OpenID server were already present, as well as the base HTML/CSS files and the madatory structure. + diff --git a/src/rooms/canvas/utils.js b/src/rooms/canvas/utils.js index b7e1855..420688f 100644 --- a/src/rooms/canvas/utils.js +++ b/src/rooms/canvas/utils.js @@ -69,12 +69,12 @@ export const toggleTooltip = async (state = false) => { } // Display - const date = new Date(response.timestamp * 1000); + const date = new Date(response.timestamp); document.getElementById("tooltip-date").innerText = - date.toLocaleDateString(); + date.toLocaleDateString("fr-fr"); document.getElementById("tooltip-time").innerText = - date.toLocaleTimeString(); + date.toLocaleTimeString("fr-fr"); getStudent(response.placedByUid); } };