Working avatar + english comments
This commit is contained in:
@@ -39,10 +39,16 @@ BACKEND
|
||||
Aucun moyen de changer l'etat de la room de waiting a en cours ou finished
|
||||
ca attendra le systeme du jeu
|
||||
|
||||
21/01 Ajout du service/route pour le systeme d'avatar
|
||||
permet aux utilisateurs de changer ou supprimer leur avatar actuel
|
||||
Ajout egalement d'une simple fonction pour recuperer l'avatar d'un utilisateur (pour le frontend)
|
||||
|
||||
DATABASE
|
||||
|
||||
17/01 Ajout des tables game_rooms, game_players, game_rounds, words
|
||||
- nom, status et parametres de la game
|
||||
- joueurs dans la game, leur scores et leur role actuel (dessinateur, devineur)
|
||||
- historique de la game, qui a dessine quoi precedemment ainsi que les timers des rounds, sera aussi utile si on veut faire les stats de compte a l'avenir.
|
||||
- contient la liste des mots utilisable par les joueurs
|
||||
- contient la liste des mots utilisable par les joueurs
|
||||
|
||||
21/01 Ajout de avatar_url dans la table users
|
||||
+2
-2
@@ -28,8 +28,8 @@ services:
|
||||
# - "3001:3001"
|
||||
depends_on:
|
||||
- database
|
||||
# volumes:
|
||||
# //
|
||||
volumes:
|
||||
- ./srcs/backend/avatar:/app/avatar
|
||||
env_file:
|
||||
- ../.env
|
||||
networks:
|
||||
|
||||
@@ -38,6 +38,7 @@ async function createTables()
|
||||
username VARCHAR(50) UNIQUE NOT NULL,
|
||||
password_hash TEXT NOT NULL,
|
||||
email VARCHAR(100),
|
||||
avatar_url TEXT DEFAULT '/avatar/default.png',
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ import {Server} from 'socket.io';
|
||||
import authRouter from './routes/auth.js';
|
||||
import chatRouter from './routes/global_chat.js';
|
||||
import gameRoomRouter from './routes/game_room.js';
|
||||
// import avatarRouter from './routes/avatar.js';
|
||||
import avatarRouter from './routes/avatar.js';
|
||||
import {waitForDb, createTables, ensureOauthClient} from './db.js';
|
||||
import setupSocketIO from './services/socket.js';
|
||||
// import avatarService from './services/avatar.js';
|
||||
import avatarService from './services/avatar.js';
|
||||
|
||||
const app = express();
|
||||
const server = http.createServer(app);
|
||||
@@ -38,11 +38,11 @@ async function startServer()
|
||||
console.warn('OAuth client might already exist or failed to register:', e.message);
|
||||
}
|
||||
|
||||
// app.use('/avatar', express.static(avatarService.AVATAR_DIR));
|
||||
app.use('/avatar', express.static(avatarService.AVATAR_DIR));
|
||||
app.use('/api/auth', authRouter);
|
||||
app.use('/api/global_chat', chatRouter);
|
||||
app.use('/api/rooms', gameRoomRouter);
|
||||
// app.use('/api/avatar', avatarRouter);
|
||||
app.use('/api/avatar', avatarRouter);
|
||||
app.get('/api', (req, res) => res.send('Backend running'));
|
||||
|
||||
server.listen(3001, () =>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import express from 'express';
|
||||
import multer from 'multer';
|
||||
import avatarService from '../services/avatar.js';
|
||||
import {authenticateToken} from '../middleware/auth.js';
|
||||
import authenticateToken from '../middleware/auth.js';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ function direBonjour() {
|
||||
alert("clicked !");
|
||||
}
|
||||
|
||||
// Définir les éléments du menu (structure logique)
|
||||
// Define the elements of the menu (logical structure)
|
||||
const menuElement = new Element("menu");
|
||||
const loginElement = new MenuElement("login");
|
||||
const registeredElement = new MenuElement("registered");
|
||||
@@ -17,11 +17,11 @@ const explorerElement = new MenuElement("explorer");
|
||||
const accueilElement = new MenuElement("accueil");
|
||||
const globalChatElement = new MenuElement("global_chat");
|
||||
|
||||
// Lancement de la grille (commentés si on ne l’utilise pas tout de suite)
|
||||
// Start of the grid (commented if we dont use it yet)
|
||||
// const gridgreen = new Grid('#143a0fff', -1, 25, 0.12, "normal");
|
||||
// const gridReverseRed = new Grid('#3a0f0f75', -1, 12.5, 0.09, "reverse");
|
||||
|
||||
// Fenêtres et écrans
|
||||
// Windows and screens
|
||||
const test = new fenetre();
|
||||
const loginWindow = new LoginWindow();
|
||||
const global_chat = new GlobalChat();
|
||||
|
||||
@@ -3,7 +3,7 @@ export class GlobalChat extends fenetre {
|
||||
constructor() {
|
||||
super(320, 240, "Global Chat");
|
||||
|
||||
// Création des éléments
|
||||
// Creation of the elements
|
||||
this.output = document.createElement("div");
|
||||
this.output.className = "chat-output";
|
||||
|
||||
@@ -24,12 +24,12 @@ export class GlobalChat extends fenetre {
|
||||
|
||||
this.applyStyles();
|
||||
this.applyEvents();
|
||||
// Connexion au chat global est déclenchée via des contrôles dédiés
|
||||
// Connection to the global chat is started via dedicated controls
|
||||
this.connected = false;
|
||||
this.createConnectControls();
|
||||
}
|
||||
|
||||
// Crée les contrôles Connect / Reconnect dans la fenêtre du chat
|
||||
// Create the controls (Connect / Reconnect) in the chat window
|
||||
createConnectControls() {
|
||||
this.controls = document.createElement("div");
|
||||
this.controls.style.display = "flex";
|
||||
@@ -62,7 +62,7 @@ export class GlobalChat extends fenetre {
|
||||
}
|
||||
|
||||
async reconnect_sockio_global_chat() {
|
||||
// Déconnecte et reconnecte le socket si nécessaire
|
||||
// Disconnect and reconnect the socket if necessary
|
||||
if (this.socket) {
|
||||
try {
|
||||
this.socket.close();
|
||||
@@ -77,7 +77,7 @@ export class GlobalChat extends fenetre {
|
||||
}
|
||||
|
||||
applyStyles() {
|
||||
// Conteneur principal en flex column
|
||||
// Main container in flex collumn
|
||||
this.body.style.display = "flex";
|
||||
this.body.style.flexDirection = "column";
|
||||
this.body.style.height = "100%";
|
||||
@@ -85,7 +85,7 @@ export class GlobalChat extends fenetre {
|
||||
this.body.style.boxSizing = "border-box";
|
||||
this.body.style.gap = "10px";
|
||||
|
||||
// Zone des messages
|
||||
// Messages zone
|
||||
this.output.style.flex = "1";
|
||||
this.output.style.overflowY = "auto";
|
||||
this.output.style.padding = "8px";
|
||||
@@ -95,7 +95,7 @@ export class GlobalChat extends fenetre {
|
||||
this.output.style.flexDirection = "column";
|
||||
this.output.style.gap = "10px";
|
||||
|
||||
// Conteneur input + bouton
|
||||
// Input container + button
|
||||
this.inputContainer.style.display = "flex";
|
||||
this.inputContainer.style.gap = "8px";
|
||||
this.inputContainer.style.paddingTop = "8px";
|
||||
@@ -107,7 +107,7 @@ export class GlobalChat extends fenetre {
|
||||
this.input.style.borderRadius = "6px";
|
||||
this.input.style.fontSize = "14px";
|
||||
|
||||
// Bouton envoyer
|
||||
// Sender button
|
||||
this.sendButton.style.padding = "8px 16px";
|
||||
this.sendButton.style.background = "#0066cc";
|
||||
this.sendButton.style.color = "white";
|
||||
@@ -118,10 +118,10 @@ export class GlobalChat extends fenetre {
|
||||
}
|
||||
|
||||
applyEvents() {
|
||||
// Envoi avec le bouton
|
||||
// Send with the button
|
||||
this.sendButton.addEventListener("click", () => this.sendMessage());
|
||||
|
||||
// Envoi avec Entrée
|
||||
// Send with Enter key
|
||||
this.input.addEventListener("keypress", (e) => {
|
||||
if (e.key === "Enter" && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
@@ -130,7 +130,7 @@ export class GlobalChat extends fenetre {
|
||||
});
|
||||
}
|
||||
|
||||
// Envoie le message courant via Socket.IO
|
||||
// Send current message via Socket.IO
|
||||
sendMessage() {
|
||||
const content = this.input.value.trim();
|
||||
if (!content) return;
|
||||
@@ -143,7 +143,7 @@ export class GlobalChat extends fenetre {
|
||||
return;
|
||||
}
|
||||
|
||||
// Affichage immédiat dans l'interface pour feedback utilisateur
|
||||
// Immediate display in the interface pour user feedback
|
||||
const div = document.createElement("div");
|
||||
div.className = "chat-message";
|
||||
div.innerHTML = `<strong>Moi:</strong> ${content}`;
|
||||
@@ -167,7 +167,7 @@ export class GlobalChat extends fenetre {
|
||||
return;
|
||||
}
|
||||
|
||||
// Si déjà connecté, ne pas tenter de nouveau
|
||||
// If already connected, dont retry
|
||||
if (this.socket && this.socket.connected) {
|
||||
this.output.innerHTML += '<div class="system">Déjà connecté au chat global</div>';
|
||||
return;
|
||||
@@ -194,7 +194,7 @@ export class GlobalChat extends fenetre {
|
||||
reconnectionDelay: 1000,
|
||||
transports: ["websocket", "polling"]
|
||||
};
|
||||
// Optionnel: se connecter via un port alternatif si défini (ex: pour contourner le proxy)
|
||||
// Optional: connect from an alternative port (ex: to dodge the proxy)
|
||||
const altPort = window.GLOBAL_CHAT_ALT_PORT;
|
||||
if (altPort) {
|
||||
const host = location.hostname || 'localhost';
|
||||
@@ -218,7 +218,7 @@ export class GlobalChat extends fenetre {
|
||||
this.output.innerHTML += `<div class="system">Déconnecté du chat (${reason})</div>`;
|
||||
});
|
||||
|
||||
// Réception des messages
|
||||
// Messages reception
|
||||
this.socket.on("chat-message", (msg) => {
|
||||
const div = document.createElement("div");
|
||||
div.className = "chat-message";
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
export class Grid {
|
||||
constructor(color = '#143a0fff', zIndex = 1, gridSize = 25, speed = 0.35, sens = "normal") {
|
||||
// Initialisation des propriétés de l'instance
|
||||
this.canvas = document.createElement('canvas');
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
this.offset = 0;
|
||||
this.gridSize = gridSize;
|
||||
this.speed = speed;
|
||||
this.color = color;
|
||||
|
||||
// Configuration du style
|
||||
document.body.appendChild(this.canvas);
|
||||
this.canvas.style.position = 'fixed';
|
||||
this.canvas.style.top = '0';
|
||||
this.canvas.style.left = '0';
|
||||
this.canvas.style.zIndex = zIndex;
|
||||
this.canvas.style.pointerEvents = 'none'; // Pour ne pas bloquer les clics sur les boutons
|
||||
|
||||
// Gestion du redimensionnement
|
||||
window.addEventListener('resize', () => this.resize());
|
||||
this.resize();
|
||||
this.draw(sens);
|
||||
}
|
||||
|
||||
resize() {
|
||||
this.canvas.width = window.innerWidth;
|
||||
this.canvas.height = window.innerHeight;
|
||||
}
|
||||
|
||||
draw(sens = "normal") {
|
||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
this.ctx.strokeStyle = this.color;
|
||||
this.ctx.lineWidth = 1;
|
||||
|
||||
// Mise à jour de l'offset
|
||||
this.offset = (this.offset + this.speed) % this.gridSize;
|
||||
if (sens === "normal") {
|
||||
// Lignes verticales
|
||||
for (let x = this.offset; x < this.canvas.width; x += this.gridSize) {
|
||||
this.ctx.beginPath();
|
||||
this.ctx.moveTo(x, 0);
|
||||
this.ctx.lineTo(x, this.canvas.height);
|
||||
this.ctx.stroke();
|
||||
}
|
||||
|
||||
// Lignes horizontales
|
||||
for (let y = this.offset; y < this.canvas.height; y += this.gridSize) {
|
||||
this.ctx.beginPath();
|
||||
this.ctx.moveTo(0, y);
|
||||
this.ctx.lineTo(this.canvas.width, y);
|
||||
this.ctx.stroke();
|
||||
}
|
||||
}
|
||||
//pareillement pour le sens reverse
|
||||
else if (sens === "reverse") {
|
||||
// Lignes verticales
|
||||
for (let x = this.gridSize - this.offset; x < this.canvas.width; x += this.gridSize) {
|
||||
this.ctx.beginPath();
|
||||
this.ctx.moveTo(x, 0);
|
||||
this.ctx.lineTo(x, this.canvas.height);
|
||||
this.ctx.stroke();
|
||||
}
|
||||
// Lignes horizontales
|
||||
for (let y = this.gridSize - this.offset; y < this.canvas.height; y += this.gridSize) {
|
||||
this.ctx.beginPath();
|
||||
this.ctx.moveTo(0, y);
|
||||
this.ctx.lineTo(this.canvas.width, y);
|
||||
this.ctx.stroke();
|
||||
}
|
||||
}
|
||||
// Appel récursif pour l'animation
|
||||
requestAnimationFrame(() => this.draw(sens));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,13 +4,13 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>scribl.lidl_edition</title>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<script src="https://cdn.socket.io/4.8.1/socket.io.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>scribl.lidl_edition</h1>
|
||||
|
||||
<!-- Menu principal -->
|
||||
<!-- Main menu -->
|
||||
<nav id="menu" aria-label="Menu principal">
|
||||
<button id="accueil" aria-label="Accueil">Accueil</button>
|
||||
<button id="explorer" aria-label="Explorer">Explorer</button>
|
||||
@@ -30,4 +30,4 @@
|
||||
|
||||
</html></script>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -33,14 +33,14 @@ export class LoginWindow extends fenetre {
|
||||
this.applyStyles();
|
||||
this.bindEvents();
|
||||
|
||||
// **** AJOUT FONCTION GITHUB ****
|
||||
// Dans constructor() de LoginWindow
|
||||
// **** ADDED GITHUB FUNCTION ****
|
||||
// In constructor() of LoginWindow
|
||||
this.githubBtn = document.createElement("button");
|
||||
this.githubBtn.innerText = "Se connecter avec GitHub";
|
||||
this.githubBtn.style.backgroundColor = "#24292e";
|
||||
this.githubBtn.style.color = "white";
|
||||
this.githubBtn.onclick = () => {
|
||||
// Ouvre le OAuth GitHub dans une popup et reçoit le token via postMessage
|
||||
// Open the OAUTH Github in a popup and receive the token from postMessage
|
||||
const w = 600;
|
||||
const h = 700;
|
||||
const left = (screen.width - w) / 2;
|
||||
@@ -59,7 +59,7 @@ export class LoginWindow extends fenetre {
|
||||
};
|
||||
this.body.appendChild(this.githubBtn);
|
||||
|
||||
this.checkIfAlreadyLoggedIn(); //verifie si l'utilisateur est connecté au démarrage
|
||||
this.checkIfAlreadyLoggedIn(); // Verify if the user is connected on startup
|
||||
}
|
||||
|
||||
applyStyles() {
|
||||
@@ -93,13 +93,13 @@ export class LoginWindow extends fenetre {
|
||||
|
||||
if (response.ok) {
|
||||
console.log("connexion ok", data);
|
||||
// *** STOCKAGE DU TOKEN ***
|
||||
// *** TOKEN STORAGE ***
|
||||
if (data.token) {
|
||||
localStorage.setItem("auth_token", data.token);
|
||||
this.message.innerText = "Connexion réussie ! Bienvenue.";
|
||||
this.message.style.color = "#3cff01";
|
||||
|
||||
// masquer la fenêtre après 1.5s
|
||||
// mask the window after 1.5s
|
||||
setTimeout(() => this.hide(), 1500);
|
||||
|
||||
}
|
||||
@@ -109,7 +109,7 @@ export class LoginWindow extends fenetre {
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Afficher une erreur utilisateur plus visible
|
||||
// Show a more visible user error
|
||||
const errMsg = data && data.message ? data.message : "Échec de la connexion";
|
||||
this.message.innerText = errMsg;
|
||||
this.message.style.color = "#ff4d4d";
|
||||
|
||||
Reference in New Issue
Block a user