Compare commits

...

3 commits

Author SHA1 Message Date
Guillem George
206de2c05e Added README 2026-05-16 21:30:07 +02:00
Guillem George
77a6d7fa6c oh la la 2026-05-16 20:29:28 +02:00
Guillem George
34e5527244 non mais srx 2026-05-16 20:15:03 +02:00
6 changed files with 41 additions and 19 deletions

View file

@ -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.

View file

@ -19,7 +19,7 @@ await authenticate();
// Sockets // Sockets
// //
let room = window.location.pathname.split("/")[1]; let room = window.location.pathname.split("/")[1];
let update_waitlist = [] const update_waitlist = [];
let initialized = false; let initialized = false;
if (!room) { if (!room) {
@ -53,11 +53,15 @@ socket.on("message", async (response) => {
} }
initCanvas(await getCurrentRoomConfig(room), pixels); initCanvas(await getCurrentRoomConfig(room), pixels);
initialized = true;
while (update_waitlist.length > 0) { while (update_waitlist.length > 0) {
const obj = update_waitlist.pop() const obj = update_waitlist.pop();
if (obj)
renderCanvasUpdate(obj.color, obj.posX, obj.posY) if (obj) {
renderCanvasUpdate(obj.color, obj.posX, obj.posY);
} }
}
console.debug("Loaded canvas"); console.debug("Loaded canvas");
}); });
@ -79,9 +83,10 @@ socket.on("pixel-update", async (msg) => {
} = msg.result.data.json; } = msg.result.data.json;
if (!initialized) { if (!initialized) {
update_waitlist.push({posX, posY, color}) update_waitlist.push({ posX, posY, color });
return; return;
} }
renderCanvasUpdate(color, posX, posY); renderCanvasUpdate(color, posX, posY);
}); });
@ -103,6 +108,4 @@ placeButtonElt.addEventListener("click", () => {
placePixelButton(); placePixelButton();
}); });
export { export { room };
room
}

View file

@ -7,6 +7,7 @@
import $ from "jquery"; import $ from "jquery";
import { getPixelInfo } from "./index"; import { getPixelInfo } from "./index";
import { getStudent } from "../../students";
const canvasContainer = $("#canvas-container")?.[0]; const canvasContainer = $("#canvas-container")?.[0];
const canvas = $("#canvas")?.[0]; const canvas = $("#canvas")?.[0];
@ -68,12 +69,13 @@ export const toggleTooltip = async (state = false) => {
} }
// Display // Display
const date = new Date(response.timestamp * 1000); const date = new Date(response.timestamp);
document.getElementById("tooltip-date").innerText = document.getElementById("tooltip-date").innerText =
date.toLocaleDateString(); date.toLocaleDateString("fr-fr");
document.getElementById("tooltip-time").innerText = document.getElementById("tooltip-time").innerText =
date.toLocaleTimeString(); date.toLocaleTimeString("fr-fr");
getStudent(response.placedByUid);
} }
}; };

View file

@ -104,7 +104,8 @@ async function fetchRoomConfig(room) {
// Update HTML // Update HTML
document.getElementById("room-name").innerText = res.metadata.name; 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"; document.getElementById("room-description").style.display = "block";
} }

View file

@ -1,4 +1,5 @@
import { authedAPIRequest } from "../utils/auth"; import { authedAPIRequest } from "../utils/auth";
import { displayStudentProfile } from "./utils";
//get a student from the API by its uid or login //get a student from the API by its uid or login
async function getStudent(login) { async function getStudent(login) {
@ -27,8 +28,7 @@ async function getStudent(login) {
console.debug(res); console.debug(res);
// Update HTML // Update HTML
// const roomNameElt = document.getElementById("room-name"); displayStudentProfile(res.avatarURL, res.login, res.guild, res.quote);
// roomNameElt.innerText = res.metadata.name
} }
//// get the user's uid from the token in local storage //// get the user's uid from the token in local storage

View file

@ -1,5 +1,11 @@
// FIXME: This file should handle the students DOM manipulation // display the student's profile in the DOM
// Link buttons to their respective functions function displayStudentProfile(picture, login, guild, quote) {
// Functions may include: document.getElementById("tooltip-info-avatar").src = picture;
// - displayStudentProfile (display the student's profile in the DOM) document.getElementById("tooltip-info-login").innerText = login;
// - showModal (add a form modal to the DOM) 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 };