Compare commits

...

3 Commits

Author SHA1 Message Date
Alexandre POMMIER
abd822dfc7 update master 2023-06-23 16:09:45 +02:00
Little Dipper
f9a26e8e0f longeur messages et logueur modal nouveau message 2023-06-18 23:04:49 +02:00
Little Dipper
263e3332a1 js to ts 2023-06-18 21:22:25 +02:00
58 changed files with 1043 additions and 1482 deletions

View File

@ -3,14 +3,14 @@ server {
# listen 80 ssl; # listen 80 ssl;
# listen 443 ssl; # listen 443 ssl;
# listen ${NGINX_PORT}; # listen ${NGINX_PORT};
listen 8080; listen 80;
location /{ location /{
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://react_app:8001; proxy_pass http://react_app:8080;
} }
location /api { location /api {
@ -20,18 +20,4 @@ server {
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://api:3000/api; proxy_pass http://api:3000/api;
} }
location /socket {
# Forward requests to socket server running on port 4001
if ($request_uri ~ ^/socket/4001) {
proxy_pass http://chat:4001;
break;
}
# Forward requests to socket server running on port 4000
if ($request_uri ~ ^/socket/4000) {
proxy_pass http://pong:4000;
break;
}
}
} }

View File

@ -6,7 +6,7 @@
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/17 01:00:00 by apommier #+# #+# */ /* Created: 2023/06/17 01:00:00 by apommier #+# #+# */
/* Updated: 2023/06/21 01:19:01 by apommier ### ########.fr */ /* Updated: 2023/06/18 13:30:50 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -27,7 +27,6 @@ import { generateOTP } from './users/2fa';
import { VerifyOTP } from './users/2fa'; import { VerifyOTP } from './users/2fa';
import { ValidateOTP } from './users/2fa'; import { ValidateOTP } from './users/2fa';
import { privateDecrypt } from 'crypto'; import { privateDecrypt } from 'crypto';
import { formatWithOptions } from 'util';
//2fa //2fa
@ -129,8 +128,6 @@ export class AppController {
async newBlocked(@Request() req, @Body() data: any) { async newBlocked(@Request() req, @Body() data: any) {
// return await this.userService.getFriends(req.user.username); // return await this.userService.getFriends(req.user.username);
console.log(`user= ${req.user.username}`) console.log(`user= ${req.user.username}`)
if (data.username === req.user.username)
return (0);
const user = await this.userService.findOne(req.user.username) const user = await this.userService.findOne(req.user.username)
return await this.userService.addBlocked(user, data.username); return await this.userService.addBlocked(user, data.username);
} }
@ -139,8 +136,6 @@ export class AppController {
@Post('/invite') @Post('/invite')
async newInvite(@Request() req, @Body() data: any) { async newInvite(@Request() req, @Body() data: any) {
console.log(`user= ${req.user.username}`) console.log(`user= ${req.user.username}`)
if (data.username === req.user.username)
return (0);
const user = await this.userService.findOne(data.username) const user = await this.userService.findOne(data.username)
if (!user) if (!user)
return (0); return (0);
@ -220,10 +215,7 @@ export class AppController {
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/win') @Post('/win')
async addWin(@Request() req, @Body() data: any) { async addWin(@Request() req, @Body() data: any) {
console.log("WIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIN: ", req.user.username)
const user = await this.userService.findOne(req.user.username); const user = await this.userService.findOne(req.user.username);
console.log("User", user)
// const user2 = await this.userService.findOne(data.opName);
user.win++; user.win++;
const Esp = 1 / (1 + Math.pow(10, (data.opRank - user.rank) / this.scaleFactor)) const Esp = 1 / (1 + Math.pow(10, (data.opRank - user.rank) / this.scaleFactor))
const newRank = user.rank + this.kFactor * (1 - Esp); const newRank = user.rank + this.kFactor * (1 - Esp);
@ -237,16 +229,14 @@ export class AppController {
newMatch.opScore = data.opScore; newMatch.opScore = data.opScore;
newMatch.opponent = data.opName; newMatch.opponent = data.opName;
newMatch.parent = user; newMatch.parent = user;
console.log(`newMatch WIIIN = ${newMatch}`);
await this.userService.saveChild(user, newMatch); await this.userService.saveChild(user, newMatch);
} }
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/loss') @Post('/loss')
async addLoss(@Request() req, @Body() data: any) { async addLoss(@Request() req, @Body() data: any) {
console.log("LOOOOOOOOOOOOOOOSE: ", req.user.username)
const user = await this.userService.findOne(req.user.username); const user = await this.userService.findOne(req.user.username);
console.log("User", user)
user.loss++; user.loss++;
const Esp = 1 / (1 + Math.pow(10, (data.opRank - user.rank) / this.scaleFactor)) const Esp = 1 / (1 + Math.pow(10, (data.opRank - user.rank) / this.scaleFactor))
@ -261,7 +251,7 @@ export class AppController {
newMatch.opScore = data.opScore; newMatch.opScore = data.opScore;
newMatch.opponent = data.opName; newMatch.opponent = data.opName;
newMatch.parent = user; newMatch.parent = user;
console.log(`newMatch Loose= ${newMatch}`);
await this.userService.saveChild(user, newMatch); await this.userService.saveChild(user, newMatch);
} }
@ -280,49 +270,6 @@ export class AppController {
return await this.userService.getRanking(); return await this.userService.getRanking();
} }
@UseGuards(JwtAuthGuard)
@Post('/partyInvite')
async partyInvite(@Request() req, @Body() data: any)
{
//find data.username and add invite to list
console.log("data post priv invite=", data);
const user = await this.userService.findOne(data.username);
user.partyInvite = user.partyInvite || [];
user.partyInvite.push({ username: req.user.username, gameId: data.gameId });
console.log("usr === ", user)
await this.userService.save(user);
// user.partyInvite.push(data);
console.log("invite === ", user.partyInvite)
}
@UseGuards(JwtAuthGuard)
@Get('/partyInvite')
async getPartyInvite(@Request() req, @Body() data: any)
{
//find data.username and add invite to list
const user = await this.userService.findOne(req.user.username);
user.partyInvite = user.partyInvite || [];
// this.userService.save(user);
// user.partyInvite.push(data);
// console.log("data invite === ", data.username)
return user.partyInvite;
}
@UseGuards(JwtAuthGuard)
@Post('/deleteInvite')
async deleteInvite(@Request() req, @Body() data: any)
{
console.log("delete invite user= ", data.username)
const user = await this.userService.findOne(req.user.username);
// user.partyInvite = user.partyInvite.filter(item => Object.values(item)[1] !== req.user.username);
console.log("user.partyInvite before", user.partyInvite)
user.partyInvite = user.partyInvite.filter((item) => Object.values(item)[1] !== data.username);
console.log("user.partyInvite after", user.partyInvite)
this.userService.save(user);
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/history') @Post('/history')
async getHistory(@Body() data: any) async getHistory(@Body() data: any)
@ -472,8 +419,6 @@ export class AppController {
if (!amIhere) if (!amIhere)
data.members.push(req.user.username) data.members.push(req.user.username)
// let test = {id: 2, members: "cc"}; // let test = {id: 2, members: "cc"};
data.admin = []
data.admin.push(req.user.username)
data.owner = req.user.username data.owner = req.user.username
data.group = true; data.group = true;
return await this.chatService.createConv(data); return await this.chatService.createConv(data);
@ -494,13 +439,6 @@ export class AppController {
return await this.chatService.findAll(); return await this.chatService.findAll();
} }
@UseGuards(JwtAuthGuard)
@Post('/convId')
async getConvById(@Body() data: any) {
return await this.chatService.findConv(data.convId);
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/message') @Post('/message')
async postMessage(@Request() req, @Body() data: any) { async postMessage(@Request() req, @Body() data: any) {
@ -541,6 +479,12 @@ export class AppController {
// res.json(messages); // res.json(messages);
} }
@UseGuards(JwtAuthGuard)
@Post('/ban')
async banUser(@Body() data: any) {
return await this.chatService.banUser(data.convId, data.username)
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/name') @Post('/name')
async setName(@Body() data: any) { async setName(@Body() data: any) {
@ -549,6 +493,12 @@ export class AppController {
return await this.chatService.setName(data.convId, data.name) return await this.chatService.setName(data.convId, data.name)
} }
@UseGuards(JwtAuthGuard)
@Post('/invite')
async inviteUser(@Body() data: any) {
return await this.chatService.inviteUser(data.convId, data.username)
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/password') @Post('/password')
async setPassword(@Body() data: any) { async setPassword(@Body() data: any) {
@ -561,36 +511,12 @@ export class AppController {
return await this.chatService.verifyPassword(data.convId, data.password) return await this.chatService.verifyPassword(data.convId, data.password)
} }
@UseGuards(JwtAuthGuard)
@Post('/invite')
async inviteUser(@Body() data: any) {
return await this.chatService.inviteUser(data.convId, data.username)
}
@UseGuards(JwtAuthGuard)
@Post('/ban')
async banUser(@Body() data: any) {
if (!data.username)
return ;
return await this.chatService.banUser(data.convId, data.username)
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/admin') @Post('/admin')
async setAdmin(@Body() data: any) { async setAdmin(@Body() data: any) {
if (!data.username)
return ;
return await this.chatService.setAdmin(data.convId, data.username) return await this.chatService.setAdmin(data.convId, data.username)
} }
@UseGuards(JwtAuthGuard)
@Post('/mute')
async muteUser(@Body() data: any) {
if (!data.username)
return ;
return await this.chatService.muteUser(data.convId, data.username)
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/isAdmin') @Post('/isAdmin')
async isAdmin(@Request() req, @Body() data: any) { async isAdmin(@Request() req, @Body() data: any) {
@ -598,6 +524,11 @@ export class AppController {
return await this.chatService.isAdmin(data.convId, req.user.username) return await this.chatService.isAdmin(data.convId, req.user.username)
} }
@UseGuards(JwtAuthGuard)
@Post('/mute')
async muteUser(@Body() data: any) {
return await this.chatService.muteUser(data.convId, data.username)
}
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Post('/private') @Post('/private')

View File

@ -58,7 +58,6 @@ export class loginClass {
console.log(`no user, creating one`); console.log(`no user, creating one`);
user = { user = {
id: null, id: null,
partyInvite: null,
password: null, password: null,
username: userName, username: userName,
nickname: userName, nickname: userName,

View File

@ -6,7 +6,7 @@
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/17 01:00:25 by apommier #+# #+# */ /* Created: 2023/06/17 01:00:25 by apommier #+# #+# */
/* Updated: 2023/06/20 16:47:02 by apommier ### ########.fr */ /* Updated: 2023/06/18 13:14:51 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -85,7 +85,6 @@ async banUser(convId: number, username: string) {
conv.banned = conv.banned || []; conv.banned = conv.banned || [];
if (conv.banned.find(item => item === username)) if (conv.banned.find(item => item === username))
return (1); return (1);
conv.members = conv.members.filter((item) => item !== username);
conv.banned.push(username); conv.banned.push(username);
this.save(conv); this.save(conv);
} }

View File

@ -6,7 +6,7 @@
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/04/09 14:53:49 by apommier #+# #+# */ /* Created: 2023/04/09 14:53:49 by apommier #+# #+# */
/* Updated: 2023/06/22 20:42:32 by apommier ### ########.fr */ /* Updated: 2023/06/12 14:51:44 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -17,7 +17,7 @@ export const getTypeOrmConfig = (): TypeOrmModuleOptions => ({
host: process.env.POSTGRES_HOST || 'postgresql', host: process.env.POSTGRES_HOST || 'postgresql',
port: parseInt(process.env.POSTGRES_PORT, 10) || 5432, port: parseInt(process.env.POSTGRES_PORT, 10) || 5432,
username: process.env.POSTGRES_USER || 'postgres', username: process.env.POSTGRES_USER || 'postgres',
password: process.env.POSTGRES_PASSWORD || 'postgres', password: process.env.POSTGRES_PASSWORD || 'pass',
database: process.env.POSTGRES_DATABASE || 'postgres', database: process.env.POSTGRES_DATABASE || 'postgres',
entities: ["dist/**/*.entity.js"], entities: ["dist/**/*.entity.js"],
// entities: [join(__dirname, '**', '*.entity.{ts,js}')] // entities: [join(__dirname, '**', '*.entity.{ts,js}')]

View File

@ -6,7 +6,7 @@
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/17 01:00:20 by apommier #+# #+# */ /* Created: 2023/06/17 01:00:20 by apommier #+# #+# */
/* Updated: 2023/06/23 15:18:19 by apommier ### ########.fr */ /* Updated: 2023/06/17 01:31:29 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */

View File

@ -65,12 +65,6 @@ export class User {
@Column('text', { array: true, nullable: true }) @Column('text', { array: true, nullable: true })
friendRequest: string[]; friendRequest: string[];
@Column({ type: 'jsonb', nullable: true })
partyInvite: Record<string, string>[];
// @Column('text', { array: true, nullable: true })
// friendRequest: string[];
@Column('text', { array: true, nullable: true }) @Column('text', { array: true, nullable: true })
friends: string[]; friends: string[];

View File

@ -6,7 +6,7 @@
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/17 01:00:07 by apommier #+# #+# */ /* Created: 2023/06/17 01:00:07 by apommier #+# #+# */
/* Updated: 2023/06/21 01:31:44 by apommier ### ########.fr */ /* Updated: 2023/06/17 01:00:08 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -47,7 +47,6 @@ export class UsersService {
async saveChild(user: User, match: MatchLog): Promise<User> { async saveChild(user: User, match: MatchLog): Promise<User> {
// user.match = savedChild; // user.match = savedChild;
user.children.push(match)
await this.matchRepository.save(match); await this.matchRepository.save(match);
return await this.userRepository.save(user); return await this.userRepository.save(user);
} }

View File

@ -8,20 +8,16 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
@WebSocketServer() @WebSocketServer()
server: Server; server: Server;
private clients: Record<string, Socket> = {}; private clients: Record<string, Socket> = {};
// private clientsNames: Record<string, Socket[]> = {}; // private clientsNames: Record<string, Socket[]> = {};
private clientsNames: Map<string, string[]> = new Map(); private clientsNames: Map<string, string[]> = new Map();
// private games: Map<string, Socket[]> = new Map();// Chat en cours, identifiées par un ID // private games: Map<string, Socket[]> = new Map();// Chat en cours, identifiées par un ID
afterInit(server: Server) afterInit(server: Server)
{ {
console.log('ChatGateway initialized'); console.log('ChatGateway initialized');
} }
handleConnection(client: Socket, ...args: any[]) handleConnection(client: Socket, ...args: any[])
{ {
console.log(`Client connected: ${client.id}`); console.log(`Client connected: ${client.id}`);
@ -96,82 +92,93 @@ export class ChatGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
console.log("create") console.log("create")
this.clientsNames.set(payload.username, [client.id]); // Create a new array with the new client as the value this.clientsNames.set(payload.username, [client.id]); // Create a new array with the new client as the value
} }
// let clientLenght = Object.keys(this.clientsNames[payload.username]).length
// const clientArray = this.clientsNames.get(payload.username)
// let clientLenght = clientArray.
// console.log(`lenght= ${clientLenght}`)
// this.clientsNames[payload.username][clientLenght] = this.clients[client.id];
// console.log(`clients: ${Object.keys(this.clientsNames).length}`)
// this.clients[clientId] = client;
//add a new client with socket and name for key
//payload.username
} }
// @SubscribeMessage('socket.io')
// socketConnect(client: any, payload: any): void {
// console.log("/socket.io")
// }
@SubscribeMessage('ban') // @SubscribeMessage('sendMessage')
banUser(client: any, payload: any): void { // handleMessage(user: any, payload: any): void {
if (!this.clientsNames.has(payload.username)) // console.log(`message recceveid: ${payload}`)
{ // console.log(`message recceveid: ${payload.sender}`)
console.log("No user found."); // console.log(`message recceveid: ${payload.convId}`)
return; // console.log(`message recceveid: ${payload.members}`)
}
const bannedClients = this.clientsNames.get(payload.username);
bannedClients.forEach(client => {
console.log("Banning client:", client);
// Perform ban operation on each client, e.g., emit a 'ban' event
console.log("clietn socket=", this.clients[client])
this.clients[client].emit('ban', payload);
});
// console.log("/ban")
// console.log("in ban username=", payload.username)
// if (!this.clientsNames[payload.username])
// {
// console.log("no user ??")
// return ;
// }
// this.clientsNames[payload.username].forEach()
// console.log("client=", this.clientsNames)
// this.clients[payload.username].emit('ban', payload)
}
@SubscribeMessage('mute') // console.log(`client id: ${user.id}`)
muteUser(client: any, payload: any): void {
if (!this.clientsNames.has(payload.username))
{
console.log("No user found.");
return;
}
const mutedClients = this.clientsNames.get(payload.username);
mutedClients.forEach(client => {
console.log("Banning client:", client);
// Perform ban operation on each client, e.g., emit a 'ban' event
console.log("clietn socket=", this.clients[client])
this.clients[client].emit('mute', payload);
});
console.log("/mute")
}
// this.clientsNames.forEach((clientArray, clientName) => {
// console.log(`Clients with name ${clientName}:`);
// // clientArray.forEach((client) => {
// this.clientsNames[clientName]
// // .forEach(client => {
// // // if(client.id != user.id)
// // // {
// // console.log("send to someone")
// // console.log(client); // Perform actions on each client
// // // clients.emit('message', payload)
// // client.emit('message')
// // // }
// // });
// // .forEach((client) => {
// // if(client.id != user.id)
// // {
// // console.log("send to someone")
// // console.log(client); // Perform actions on each client
// // // clients.emit('message', payload)
// // client.emit('message')
// // }
// });
// };
@SubscribeMessage('sendMessage') @SubscribeMessage('sendMessage')
handleMessage(client: Socket, payload: any): void { handleMessage(client: Socket, payload: any): void {
// console.log(`message received: ${payload}`); // console.log(`message received: ${payload}`);
// console.log(`message sender: ${payload.sender}`); console.log(`message sender: ${payload.sender}`);
// console.log(`client id: ${client.id}`); console.log(`client id: ${client.id}`);
// console.log(`conversation ID: ${payload.convId}`); console.log(`conversation ID: ${payload.convId}`);
// console.log(`members: ${payload.members}`); console.log(`members: ${payload.members}`);
this.clientsNames.forEach((clientArray, clientName) => this.clientsNames.forEach((clientArray, clientName) =>
{ {
// console.log(` 5Clients with name ${clientName}:`); console.log(` 5Clients with name ${clientName}:`);
if (payload.members.includes(clientName)) if (payload.members.includes(clientName))
{ {
clientArray.forEach((targetClient, index) => clientArray.forEach((targetClient, index) =>
{ {
// console.log(`client id: ${client.id}`); console.log(`client id: ${client.id}`);
// console.log(`target: ${targetClient}`); console.log(`target: ${targetClient}`);
// console.log(`target id: ${targetClient}`); console.log(`target id: ${targetClient}`);
if (targetClient && targetClient !== client.id) if (targetClient && targetClient !== client.id)
{ {
// console.log("Sending to someone"); console.log("Sending to someone");
// console.log(`index= ${index}`); console.log(`index= ${index}`);
// console.log(`target: ${targetClient}`); // Perform actions on each target client console.log(`target: ${targetClient}`); // Perform actions on each target client
// targetClient.emit('message')
// this.clientsNames[clientName].emit('message')
// this.clientsNames["apommier"].emit('message')
this.clients[targetClient].emit('message', payload) this.clients[targetClient].emit('message', payload)
// console.log(test)
// console.log(test)
// this.clientsNames[clientName][index].emit('message');
// const socket = this.server.sockets.sockets.get(targetClient.id);
// if (socket) {
// socket.emit('message', payload);
// } else {
// console.log(`Socket with ID ${client.id} not found.`);
// }
// targetClient.emit('message', payload);
// targetClient.emit('message', payload);
} }
else { else {
console.log("not sending"); console.log("not sending");
@ -186,3 +193,41 @@ muteUser(client: any, payload: any): void {
// for (let key in this.clientsNames) {
// if (payload.members.includes(key)) {
// console.log("Key exists in the array");
// // if (key !== payload.sender)
// // {
// for (let key2 in this.clientsNames[key])
// {
// if (client.id !== this.clientsNames[key][key2])
// {
// console.log("send to someone")
// this.clientsNames[key][key2].emit('message', payload)
// }
// }
// // }
// //if member socket different from mine
// //send
// } else {
// console.log("Key does not exist in the array");
// }
//if key is in member
// let socket = this.clients[key];
// console.log("Clé:", key);
// console.log("Socket:", socket);
// }
// payload.convId // conv user instead ?
//find user to send message to
//const res = {
//convId: payload.convId
//sender: payload.sender
// }
//while (user of conv)//how to get conv user
// if (user connected)
//send res to user
// }

View File

@ -1,26 +1,7 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* pong.gateway.ts :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/19 15:18:38 by apommier #+# #+# */
/* Updated: 2023/06/23 15:19:12 by apommier ### ########.fr */
/* */
/* ************************************************************************** */
import { SubscribeMessage, WebSocketGateway, OnGatewayInit, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets'; import { SubscribeMessage, WebSocketGateway, OnGatewayInit, WebSocketServer, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';
import { Server, Socket } from 'socket.io'; import { Server, Socket } from 'socket.io';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
//========================================================================================================
//========================================================================================================
// Connection/Disconnection
//========================================================================================================
//========================================================================================================
@WebSocketGateway({ cors: true }) @WebSocketGateway({ cors: true })
export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect { export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect {
@WebSocketServer() server: Server; @WebSocketServer() server: Server;
@ -50,82 +31,50 @@ export class PongGateway implements OnGatewayInit, OnGatewayConnection, OnGatewa
handleDisconnect(client: Socket) handleDisconnect(client: Socket)
{ {
console.log(`Normal disconnected: ${client.id}`); console.log(`Client disconnected: ${client.id}`);
// this.waitingClients.delete(client);
this.waitingClients.forEach((item) => { this.waitingClients.forEach((waitingClient) => {
if (item.client === client) if (waitingClient.client === client) {
this.waitingClients.delete(item); this.waitingClients.delete(waitingClient);
}); }})
// Delete the socket from the 'games' map
this.games.forEach((sockets, gameId) => {
const index = sockets.indexOf(client);
if (index !== -1)
{
if (index === 0)
{
console.log("emit boy1")
sockets[1].emit("pong:win")
// sockets[0].emit("/win")
}
else
{
console.log("emit boy2")
sockets[0].emit("pong:win")
// sockets[1].emit("/win")
}
this.games.delete(gameId);
delete this.clients[client.id]; delete this.clients[client.id];
}
})
console.log(`Total connected clients: ${Object.keys(this.clients).length}`); console.log(`Total connected clients: ${Object.keys(this.clients).length}`);
} }
// @SubscribeMessage('pong:matchmaking')
// addMatchmaking(client: Socket, payload: any): void
// {
// console.log("matchmaking");
// console.log(payload);
// // this.waitingClients.add(client);
// this.waitingClients.add(client);
// console.log("Adding client to waiting list...");
// if (this.waitingClients.size >= 2) {
// console.log("Creating new game...");
// const players = Array.from(this.waitingClients).slice(0, 2);
// players.forEach((player) => {
// this.waitingClients.delete(player);
// });
// const gameId = uuidv4();
// this.games.set(gameId, players);
// players.forEach((player) => {
// player.join(gameId);
// console.log(`Player ${player.id} joined game ${gameId}`);
// });
// players.forEach((player) => {
// // const playersIds = game.map(socket => socket.id);
// player.emit('pong:gameId', gameId);
// });
// }
// // console.log(`from: ${client.id}`);
// }
@SubscribeMessage('pong:invite')
createPrivateGame(client: Socket, payload: any): void {
//after invite accepted ?
//set the two user in a game ?
@SubscribeMessage('pong:disconnect')
disconnectClient(client: Socket, payload: any): void {
console.log("disconnect forced client= ", client.id)
for (const key in this.clients) {
if (this.clients.hasOwnProperty(key) && this.clients[key] === client)
delete this.clients[key];
}
// Delete the socket from the 'waitingClients' set
this.waitingClients.forEach((item) => {
if (item.client === client)
this.waitingClients.delete(item);
});
// Delete the socket from the 'games' map
this.games.forEach((sockets, gameId) => {
const index = sockets.indexOf(client);
if (index !== -1)
{
if (index === 0)
{
console.log("emit boy1")
sockets[1].emit("pong:win")
// sockets[0].emit("/win")
}
else
{
console.log("emit boy2")
sockets[0].emit("pong:win")
// sockets[1].emit("/win")
}
this.games.delete(gameId);
delete this.clients[client.id];
} }
})
}
//========================================================================================================
//========================================================================================================
// Matchmaking
//========================================================================================================
//========================================================================================================
@SubscribeMessage('pong:matchmaking') @SubscribeMessage('pong:matchmaking')
addMatchmaking(client: Socket, payload: any): void { addMatchmaking(client: Socket, payload: any): void {
@ -142,7 +91,6 @@ addMatchmaking(client: Socket, payload: any): void {
waitingClient.option === payload.option && waitingClient.client !== client waitingClient.option === payload.option && waitingClient.client !== client
); );
if (matchingClients.length > 0) { if (matchingClients.length > 0) {
console.log("Creating new game..."); console.log("Creating new game...");
const players = [matchingClients[0].client, client]; // Add the current client to the players array const players = [matchingClients[0].client, client]; // Add the current client to the players array
@ -169,76 +117,43 @@ addMatchmaking(client: Socket, payload: any): void {
player.emit('pong:gameId', gameId); player.emit('pong:gameId', gameId);
}); });
} }
// console.log(`from: ${client.id}`); // console.log(`from: ${client.id}`);
} }
// @SubscribeMessage('pong:message')
// handleMessage(client: Socket, payload: any): void
// {
// console.log(`from: ${client.id}`);
// console.log(payload);
// const game = this.games.get(payload.gameId);
// const playersIds = game.map(socket => socket.id);
// // const players = Object.keys(game);
//======================================================================================================== // // if (Object.keys(this.clients).length === 2)
//======================================================================================================== // // {
// Private Match // // const clientIds = Object.keys(this.clients);
//======================================================================================================== // // console.log(`id of 0= ${clientIds[0]}`);
//========================================================================================================
// // payload.ballX
// // payload.ballY
// // payload.
// if (clientIds[0] === payload.id)
// @SubscribeMessage('pong:invite') // {
// createPrivateGame(client: Socket, payload: any): void { // // console.log("client 0 true");
// //after invite accepted ? // if (payload.ballX <= payload.width / 2)
// //set the two user in a game ? // this.clients[clientIds[1]].emit('pong:info', payload);
// }
// else if (clientIds[1] === payload.id)
// {
// if (payload.ballX < payload.width / 2)
// this.clients[clientIds[0]].emit('pong:info', payload);
// // console.log("client 0 true");
// }
// // }
// console.log("END OF HANDLE");
// } // }
@SubscribeMessage('pong:joinParty')
joinPrivateParty(client: Socket, payload: any): void {
console.log(" join PrivateParty")
const game = this.games.get(payload.gameId);
if (game)
{
game.push(client);
const playersIds = game.map(socket => socket.id);
this.clients[playersIds[0]].emit('pong:gameId', payload.gameId);
this.clients[playersIds[1]].emit('pong:gameId', payload.gameId);
}
else
{
console.log("emit else")
client.emit("pong:win")
}
// console.log("no game ???")
}
@SubscribeMessage('pong:privateParty')
addPrivateParty(client: Socket, payload: any): void {
console.log("addPrivateParty")
const gameId = uuidv4();
const players = [client];
this.games.set(gameId, players);
console.log("game created private")
client.emit('pong:privateId', gameId);
//create game
//emit private gameId to canvas (don't launch canvas)
}
//========================================================================================================
//========================================================================================================
// In Game
//========================================================================================================
//========================================================================================================
@SubscribeMessage('pong:power') @SubscribeMessage('pong:power')
sendPower(client: Socket, payload: any): void sendPower(client: Socket, payload: any): void
@ -276,6 +191,29 @@ addPrivateParty(client: Socket, payload: any): void {
console.log("END OF HANDLE"); console.log("END OF HANDLE");
} }
// @SubscribeMessage('pong:forced')
// forcedMessage(client: Socket, payload: any): void
// {
// console.log(`from: ${client.id}`);
// console.log(payload);
// if (Object.keys(this.clients).length === 2)
// {
// const clientIds = Object.keys(this.clients);
// console.log(`id of 0= ${clientIds[0]}`);
// if (clientIds[0] === payload.id)
// {
// this.clients[clientIds[1]].emit('pong:info', payload);
// }
// else if (clientIds[1] === payload.id)
// {
// this.clients[clientIds[0]].emit('pong:info', payload);
// }
// }
// console.log("END OF HANDLE");
// }
@SubscribeMessage('pong:forced') @SubscribeMessage('pong:forced')
forcedMessage(client: Socket, payload: any): void forcedMessage(client: Socket, payload: any): void
{ {
@ -298,6 +236,29 @@ addPrivateParty(client: Socket, payload: any): void {
console.log("END OF HANDLE"); console.log("END OF HANDLE");
} }
// @SubscribeMessage('pong:paddle')
// handlePaddle(client: Socket, payload: any): void
// {
// console.log(`from: ${client.id}`);
// console.log(payload);
// if (Object.keys(this.clients).length === 2)
// {
// const clientIds = Object.keys(this.clients);
// console.log(`id of 0= ${clientIds[0]}`);
// if (clientIds[0] === payload.id)
// {
// this.clients[clientIds[1]].emit('pong:paddle', payload);
// }
// else if (clientIds[1] === payload.id)
// {
// this.clients[clientIds[0]].emit('pong:paddle', payload);
// }
// }
// console.log("END OF HANDLE");
// }
@SubscribeMessage('pong:paddle') @SubscribeMessage('pong:paddle')
handlePaddle(client: Socket, payload: any): void handlePaddle(client: Socket, payload: any): void
{ {

View File

@ -1,5 +1,2 @@
REACT_APP_BASE_URL=localhost:8080 REACT_APP_BASE_URL=localhost
REACT_APP_API_SECRET=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
REACT_APP_CLIENT_UID=u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41
# REACT_APP_BASE_URL=92.143.191.152
# REACT_APP_BASE_URL=192.168.1.19 # REACT_APP_BASE_URL=192.168.1.19

View File

@ -23,11 +23,8 @@
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"socket.io-client": "^4.6.1", "socket.io-client": "^4.6.1",
"styled-components": "^5.3.10", "styled-components": "^5.3.10",
"typescript": "^3.2.1", "typescript": "^3.9.10",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
},
"devDependencies": {
"@types/node": "^20.3.1"
} }
}, },
"node_modules/@adobe/css-tools": { "node_modules/@adobe/css-tools": {
@ -4538,9 +4535,9 @@
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.3.1", "version": "20.1.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.4.tgz",
"integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" "integrity": "sha512-At4pvmIOki8yuwLtd7BNHl3CiWNbtclUbNtScGx4OHfBd4/oWoJC8KRCIxXwkdndzhxOsPXihrsOoydxBjlE9Q=="
}, },
"node_modules/@types/parse-json": { "node_modules/@types/parse-json": {
"version": "4.0.0", "version": "4.0.0",
@ -20224,9 +20221,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "3.2.1", "version": "3.9.10",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.1.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
"integrity": "sha512-jw7P2z/h6aPT4AENXDGjcfHTu5CSqzsbZc6YlUIebTyBAq8XaKp78x7VcSh30xwSCcsu5irZkYZUSFP1MrAMbg==", "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"
@ -24455,9 +24452,9 @@
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
}, },
"@types/node": { "@types/node": {
"version": "20.3.1", "version": "20.1.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.4.tgz",
"integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" "integrity": "sha512-At4pvmIOki8yuwLtd7BNHl3CiWNbtclUbNtScGx4OHfBd4/oWoJC8KRCIxXwkdndzhxOsPXihrsOoydxBjlE9Q=="
}, },
"@types/parse-json": { "@types/parse-json": {
"version": "4.0.0", "version": "4.0.0",
@ -35365,9 +35362,9 @@
} }
}, },
"typescript": { "typescript": {
"version": "3.2.1", "version": "3.9.10",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.1.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
"integrity": "sha512-jw7P2z/h6aPT4AENXDGjcfHTu5CSqzsbZc6YlUIebTyBAq8XaKp78x7VcSh30xwSCcsu5irZkYZUSFP1MrAMbg==" "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q=="
}, },
"unbox-primitive": { "unbox-primitive": {
"version": "1.0.2", "version": "1.0.2",

View File

@ -18,11 +18,11 @@
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"socket.io-client": "^4.6.1", "socket.io-client": "^4.6.1",
"styled-components": "^5.3.10", "styled-components": "^5.3.10",
"typescript": "^3.2.1", "typescript": "^3.9.10",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"scripts": { "scripts": {
"start": "HOST=0.0.0.0 PORT=8001 react-scripts start", "start": "HOST=0.0.0.0 PORT=8080 react-scripts start",
"start:dev": "npm run start --watch", "start:dev": "npm run start --watch",
"build": "react-scripts build", "build": "react-scripts build",
"test": "react-scripts test", "test": "react-scripts test",
@ -45,8 +45,5 @@
"last 1 firefox version", "last 1 firefox version",
"last 1 safari version" "last 1 safari version"
] ]
},
"devDependencies": {
"@types/node": "^20.3.1"
} }
} }

View File

@ -2,7 +2,6 @@ import Backdrop from "../Sidebar/Backdrop.tsx"
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { AiOutlineCheckCircle } from "react-icons/ai"; import { AiOutlineCheckCircle } from "react-icons/ai";
import '../../styles/Messages.css' import '../../styles/Messages.css'
import React from "react";
const dropIn = { const dropIn = {
@ -17,19 +16,14 @@ const dropIn = {
}, },
}; };
interface AlertProps { function GreenAlert ({handleClose, text}){
handleClose: Function,
text: string
}
function GreenAlert ({handleClose, text}: AlertProps){
return( return(
<Backdrop onClick={handleClose}> <Backdrop>
<motion.div <motion.div
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
className="greenAlert" className="greenAlert"
// variant={dropIn} variant={dropIn}
initial="hidden" initial="hidden"
animate="visible" animate="visible"
exit="exit" exit="exit"

View File

@ -2,7 +2,6 @@ import Backdrop from "../Sidebar/Backdrop.tsx"
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { BiErrorCircle } from "react-icons/bi"; import { BiErrorCircle } from "react-icons/bi";
import '../../styles/Messages.css' import '../../styles/Messages.css'
import React from "react";
const dropIn = { const dropIn = {
@ -17,18 +16,13 @@ const dropIn = {
}, },
}; };
interface AlertProps { function RedAlert ({handleClose, text}) {
handleClose: Function,
text: string
}
function RedAlert ({handleClose, text}: AlertProps) {
return( return(
<Backdrop onClick={handleClose}> <Backdrop>
<motion.div <motion.div
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
className="redAlert" className="redAlert"
// variant={dropIn} variant={dropIn}
initial="hidden" initial="hidden"
animate="visible" animate="visible"
exit="exit" exit="exit"

View File

@ -2,9 +2,6 @@ import Backdrop from "../Sidebar/Backdrop.tsx"
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { GrTrophy } from "react-icons/gr"; import { GrTrophy } from "react-icons/gr";
import '../../styles/Messages.css' import '../../styles/Messages.css'
import React from "react";
import { MdQrCodeScanner } from "react-icons/md";
import { GiCrownedSkull, GiWingedSword } from "react-icons/gi";
const dropIn = { const dropIn = {
hidden: { hidden: {
@ -18,40 +15,19 @@ const dropIn = {
}, },
}; };
interface AlertProps { function YellowAlert ({handleClose, text}) {
handleClose: Function,
text: string,
icon: number
}
function YellowAlert ({handleClose, text, icon}: AlertProps) {
return( return(
<Backdrop onClick={handleClose}> <Backdrop>
<motion.div <motion.div
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
className="yellowAlert" className="yellowAlert"
// variant={dropIn} variant={dropIn}
initial="hidden" initial="hidden"
animate="visible" animate="visible"
exit="exit" exit="exit"
> >
{icon === 0 ? (
<GrTrophy/> <GrTrophy/>
):("")} <p>{text}</p>
{icon === 1 ? (
<MdQrCodeScanner/>
):("")}
{icon === 2 ? (
<GiCrownedSkull/>
):("")}
{icon === 3 ? (
<GiWingedSword/>
):("")}
<h5>{text}</h5>
</motion.div> </motion.div>
{setTimeout(handleClose, 3000)} {setTimeout(handleClose, 3000)}
</Backdrop> </Backdrop>

View File

@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import {Routes, Route} from 'react-router-dom'; import {Routes, Route} from 'react-router-dom';
import Home from "../pages/Home.jsx"; import Home from "../pages/Home.jsx";
import PlayButton from "./Game/PlayButton.tsx"; import PlayButton from "../pages/PlayButton.js";
import Field from "../pages/Field"; import Field from "../pages/Field";
import Login42 from "../pages/Login42.js"; import Login42 from "../pages/Login42.js";
import Messages from "../pages/Messages.jsx"; import Messages from "../pages/Messages.jsx";
@ -13,11 +13,11 @@ function AnimatedRoute () {
return ( return (
<AnimatePresence> <AnimatePresence>
<Routes location={location} key={location.pathname}> <Routes location={location} key={location.pathname}>
<Route path="/" element={<Home/>}/> <Route exact path="/" element={<Home/>}/>
<Route path="/game" element={<PlayButton />}/> <Route path="/game" element={<PlayButton />}/>
<Route path="/pong/play" element={<Field />}/> <Route exact path="/pong/play" element={<Field />}/>
<Route path="/login42" element={<Login42 />}/> <Route exact path="/login42" element={<Login42 />}/>
<Route path="/messages" element={<Messages />}/> <Route exact path="/messages" element={<Messages />}/>
</Routes> </Routes>
</AnimatePresence> </AnimatePresence>
) )

View File

@ -1,4 +1,3 @@
import React from 'react';
import '../../styles/field.css'; import '../../styles/field.css';
// import { useHistory } from 'react-router-dom'; // import { useHistory } from 'react-router-dom';
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
@ -14,18 +13,18 @@ function PlayButton() {
const handleButtonClick = () => { const handleButtonClick = () => {
let path = `play?`; let path = `play?`;
const superpowerCheckbox = document.querySelector<HTMLInputElement>('input[value="superpower"]'); const superpowerCheckbox = document.querySelector('input[value="superpower"]');
if (superpowerCheckbox && superpowerCheckbox.checked) { if (superpowerCheckbox.checked) {
path += 'superpower=true&'; path += 'superpower=true&';
} }
const obstacleCheckbox = document.querySelector<HTMLInputElement>('input[value="obstacle"]'); const obstacleCheckbox = document.querySelector('input[value="obstacle"]');
if (obstacleCheckbox && obstacleCheckbox.checked) { if (obstacleCheckbox.checked) {
path += 'obstacle=true&'; path += 'obstacle=true&';
} }
const speedCheckbox = document.querySelector<HTMLInputElement>('input[value="speed"]'); const speedCheckbox = document.querySelector('input[value="speed"]');
if (speedCheckbox && speedCheckbox.checked) { if (speedCheckbox.checked) {
path += 'speed=true&'; path += 'speed=true&';
} }

View File

@ -1,31 +1,25 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* Rank.tsx :+: :+: :+: */ /* Rank.jsx :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/09 08:49:24 by apommier #+# #+# */ /* Created: 2023/06/09 08:49:24 by apommier #+# #+# */
/* Updated: 2023/06/20 13:06:35 by apommier ### ########.fr */ /* Updated: 2023/06/09 08:55:22 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
// import React from "react" // import React from "react"
import React, { useState, useEffect, useRef } from "react"; import React, { useState, useEffect, useRef } from "react";
// import {Rank} from '../../DataBase/DataRank.js' // import {Rank} from '../../DataBase/DataRank.js'
import DefaultPicture from '../../assets/profile.jpg' // import DefaultPicture from '../../assets/profile.jpg'
import api from '../../script/axiosApi.tsx'; import api from '../../script/axiosApi';
import {Matchlog, User} from "../../../interfaces.tsx"
// import { Match } from "@testing-library/react";
interface RankProps { function Rank({user, index}){
user: User
index: number
}
function Rank({user, index}: RankProps){
const [profilePicture, setProfilePicture] = useState(''); const [profilePicture, setProfilePicture] = useState('');
const DefaultPicture:string = '../../assets/profile.jpg';
useEffect(() => { useEffect(() => {
const fetchProfilePicture = async () => { const fetchProfilePicture = async () => {
@ -43,12 +37,10 @@ function Rank({user, index}: RankProps){
fetchProfilePicture(); fetchProfilePicture();
}) })
// console.log(index);
return ( return (
<div className='rank_elements'> <div className='rank_elements'>
<div> <div>
{/* <p>{(index + 1).toString()}</p> */} <p>{index + 1}</p>
<p>{(index + 1)}</p>
<h4>{user.rank}: {user.nickname} <h4>{user.rank}: {user.nickname}
{profilePicture ? ( {profilePicture ? (
<img className="profilePic" src={`data:image/jpeg;base64,${profilePicture}`} /> <img className="profilePic" src={`data:image/jpeg;base64,${profilePicture}`} />
@ -58,7 +50,7 @@ function Rank({user, index}: RankProps){
{/* <img className="profilePic" src={defaultpic}/> */} {/* <img className="profilePic" src={defaultpic}/> */}
</h4> </h4>
</div> </div>
{/* <h4 className='content'>{user.opponent}</h4> */} <h4 className='content'>{user.opponent}</h4>
</div> </div>
) )
} }

View File

@ -3,12 +3,11 @@ import React, { useState, useEffect, useRef } from "react";
import Rank from './Rank.tsx' import Rank from './Rank.tsx'
import defaultpic from '../../assets/profile.jpg' import defaultpic from '../../assets/profile.jpg'
import api from '../../script/axiosApi.tsx'; import api from '../../script/axiosApi.tsx';
import {User} from "../../../interfaces.tsx"
function Ranking(){ function Ranking(){
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [ranking, setRanking] = useState<User[]>([]); const [ranking, setRanking] = useState([]);
useEffect(()=> { useEffect(()=> {
@ -42,7 +41,16 @@ function Ranking(){
// <h1 className='title'>Ranking</h1> // <h1 className='title'>Ranking</h1>
<div className='scroll'> <div className='scroll'>
{ranking.map((user, index) => ( {ranking.map((user, index) => (
<Rank user={user} index={index} key={user.username}/> <Rank user={user} index={index}/>
// return (
// <div className='rank_elements'>
// <div>
// <p>{index + 1}</p>
// <h4>{user.rank}: {user.nickname} <img className="profilePic" src={defaultpic}/></h4>
// </div>
// <h4 className='content'>{user.opponent}</h4>
// </div>
// )
))} ))}
</div> </div>
)} )}

View File

@ -4,14 +4,10 @@ import {Link} from 'react-router-dom';
import DefaultPicture from '../assets/profile.jpg' import DefaultPicture from '../assets/profile.jpg'
import { motion, AnimatePresence } from 'framer-motion' import { motion, AnimatePresence } from 'framer-motion'
import Modal from './Sidebar/Modal.tsx'; import Modal from './Sidebar/Modal.tsx';
import YellowAlert from './Alert/YellowAlert.tsx';
import '../styles/Header.css'; import '../styles/Header.css';
import api from '../script/axiosApi.tsx'; import api from '../script/axiosApi.tsx';
import { MdQrCodeScanner } from 'react-icons/md';
import { GiWingedSword, GiCrownedSkull } from 'react-icons/gi';
function Header() { function Header() {
// const [sidebar, setSidebar] = useState(false); // const [sidebar, setSidebar] = useState(false);
// const showSidebar = () => setSidebar(!sidebar); // const showSidebar = () => setSidebar(!sidebar);
@ -19,8 +15,6 @@ function Header() {
const close = () => setModalOpen(false); const close = () => setModalOpen(false);
const open = () => setModalOpen(true); const open = () => setModalOpen(true);
const [success, setSuccess] = useState([]);
const [profilePicture, setProfilePicture] = useState(''); const [profilePicture, setProfilePicture] = useState('');
useEffect(() => { useEffect(() => {
@ -29,8 +23,6 @@ function Header() {
const user = await api.get("/profile"); const user = await api.get("/profile");
const pic = await api.post("/getPicture", {username: user.data.username}) const pic = await api.post("/getPicture", {username: user.data.username})
setProfilePicture(pic.data); setProfilePicture(pic.data);
// console.log("test ===", user.data)
setSuccess(user.data);
// console.log(`profile pic222= ${pic.data}`) // console.log(`profile pic222= ${pic.data}`)
} catch (error) { } catch (error) {
console.error('Error fetching profile picture:', error); console.error('Error fetching profile picture:', error);
@ -40,6 +32,10 @@ function Header() {
fetchProfilePicture(); fetchProfilePicture();
}, []); }, []);
// console.log(`profile pic= ${profilePicture}`)
// photo.toString('base64')
return ( return (
<div className='Header'> <div className='Header'>
<motion.div <motion.div
@ -49,7 +45,6 @@ function Header() {
</Link> </Link>
</motion.div> </motion.div>
<div className='end'> <div className='end'>
<Link to="/profile" className='menu-bars'> <Link to="/profile" className='menu-bars'>
<div> <div>
@ -67,7 +62,7 @@ function Header() {
<AnimatePresence <AnimatePresence
initial={false} initial={false}
onExitComplete={() => null}> onExitComplete={() => null}>
{modalOpen && <Modal handleclose={close}/>} {modalOpen && <Modal modalOpen={modalOpen} handleclose={close}/>}
</AnimatePresence> </AnimatePresence>
</div> </div>
); );

View File

@ -1,14 +1,13 @@
import React, { useState, useEffect, useRef } from "react"; import React, { useState, useEffect, useRef } from "react";
import io, { Socket } from 'socket.io-client'; import io from 'socket.io-client';
import '../../styles/Messages.css' import '../../styles/Messages.css'
import styled from "styled-components"; import styled from "styled-components";
import DefaultPic from '../../assets/profile.jpg' import DefaultPic from '../../assets/profile.jpg'
import api from '../../script/axiosApi.tsx'; import api from '../../script/axiosApi.tsx'
import { motion , AnimatePresence} from "framer-motion"; import { motion , AnimatePresence} from "framer-motion";
import Modal from "./Modal.tsx"; import Modal from "./Modal.tsx";
import GameModal from "./GameModal.tsx";
import Message from "./Message.tsx" import Message from './Message.tsx';
// import Input from "./Input"; // import Input from "./Input";
//react icons //react icons
@ -18,15 +17,12 @@ import { MdOutlineGroupAdd } from 'react-icons/md';
import { GrAdd } from 'react-icons/gr'; import { GrAdd } from 'react-icons/gr';
import { RiListSettingsLine } from 'react-icons/ri' import { RiListSettingsLine } from 'react-icons/ri'
// import { Rank } from "../../DataBase/DataRank"; import { Rank } from "../../DataBase/DataRank";
import GreenAlert from "../Alert/GreenAlert.tsx"; import GreenAlert from "../Alert/GreenAlert.tsx";
import RedAlert from "../Alert/RedAlert.tsx"; import RedAlert from "../Alert/RedAlert.tsx";
import YellowAlert from "../Alert/YellowAlert"; import YellowAlert from "../Alert/YellowAlert";
import ModalSetting from "./ModalSetting.tsx"; import ModalSetting from "./ModalSetting.tsx";
import PartyInvite from "./PartyInvite.tsx";
// import {User, Conv, Message} from "../../../interfaces.tsx"
import {User, Conv} from "../../../interfaces.tsx"
const TouchDiv = styled.div` const TouchDiv = styled.div`
margin-left: 10px; margin-left: 10px;
@ -74,31 +70,20 @@ const SideP = styled.p`
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
interface MessageProps {
id: number;
convId: number;
sender: string;
text: string;
createdAt?: Date;
}
function Chats(){ function Chats(){
const [isLoading, setIsLoading] = useState<boolean>(true); const [isLoading, setIsLoading] = useState(true);
const [conversations, setConversation] = useState([]); const [conversations, setConversation] = useState([]);
const [partyInvite, setPartyInvite] = useState([]); const [user, setUser] = useState(null);
const [user, setUser] = useState<User>(); const [currentChat, setCurrentChat] = useState(false); // false is good?
const [currentChat, setCurrentChat] = useState<Conv>(); // false is good? const [isAdmin, setIsAdmin] = useState(false); // false is good?
const [isAdmin, setIsAdmin] = useState<boolean>(false); // false is good?
// const [currentChat, setCurrentChat] = useState(false); // false is good? // const [currentChat, setCurrentChat] = useState(false); // false is good?
const [messages, setMessage] = useState<MessageProps[]>([]); const [messages, setMessage] = useState([]);
const [newMessages, setNewMessage] = useState(""); const [newMessages, setNewMessage] = useState("");
const [incomingMessage, setIncomingMessage] = useState<MessageProps>(); const [incomingMessage, setIncomingMessage] = useState("");
const socket = useRef();
// let socket: Socket;
const socket = useRef<Socket | null>(null);
// const socket = Socket<DefaultEventsMap, DefaultEventsMap> | null
// socket = useRef( useRef<SocketIOClient.Socket | null>(null));
useEffect(()=> { useEffect(()=> {
@ -106,55 +91,29 @@ function Chats(){
const getConv = async ()=>{ const getConv = async ()=>{
try{ try{
const convs = await api.get("/conv") const convs = await api.get("/conv")
const tmpInvite = await api.get("/partyInvite")
const tmpUser = await api.get("/profile") const tmpUser = await api.get("/profile")
const tmpUsers = await api.get("/users");
console.log(convs); console.log(convs);
// console.log("invite data use effect= ", tmpInvite.data);
setPartyInvite(tmpInvite.data);
setUser(tmpUser.data); setUser(tmpUser.data);
setConversation(convs.data); setConversation(convs.data);
setUsers(tmpUsers.data); socket.current = io('http://' + process.env.REACT_APP_BASE_URL + ':4001');
console.log(`connection....`);
// console.log(`connection....`);
socket.current = io('http://' + process.env.REACT_APP_BASE_URL + ':4001', { transports: ['polling'] });
// console.log(`connection done`);
socket.current.emit('connection', {username: tmpUser.data.username}) socket.current.emit('connection', {username: tmpUser.data.username})
socket.current.on('message', (data) => { //data should be a message ?) socket.current.on('message', (data) => { //data should be a message ?
console.log(`message received data= ${data.sender}`)
console.log(`message received data= ${data.convId}`)
console.log(`message received data= ${data.sender}`)
console.log(`current chat = ${currentChat}`)
setIncomingMessage(data); setIncomingMessage(data);
}); });
socket.current.on('ban', (data) => {
// setIncomingMessage(data);
console.log("banned hehe");
window.location.reload()
});
socket.current.on('mute', (data) => {
console.log("muted hehe");
//set mute var to true and do nothing
});
setIsLoading(false) setIsLoading(false)
} }
catch(err){ catch(err){
console.log("ERRORRRRR")
console.log(err); console.log(err);
} }
}; };
getConv(); getConv();
return () => {
console.log("Cleanup");
if (socket.current)
socket.current.disconnect();
// cleanup(); // Call the cleanup function to stop the ongoing process or perform necessary cleanup tasks
// cleanup();
};
}, []) }, [])
useEffect(()=> { useEffect(()=> {
@ -174,12 +133,9 @@ function Chats(){
} }
} }
// console.log(`result1 = ${currentChat.id !== incomingMessage.convId}`) // console.log(`result1 = ${currentChat.id !== incomingMessage.convId}`)
if (currentChat && incomingMessage && currentChat.id === incomingMessage.convId) if (currentChat !== null && currentChat.id === incomingMessage.convId)
{ {
console.log("incoming meaasge=",incomingMessage)
// if (user && !user.blocked.find(incomingMessage.sender))
// setMessage((prev) => [...prev, incomingMessage, key: incomingMessage.id]);
// setMessage((prev) => [...prev, { ...incomingMessage, key: incomingMessage.id }]);
setMessage((prev) => [...prev, incomingMessage]); setMessage((prev) => [...prev, incomingMessage]);
} }
} }
@ -190,13 +146,10 @@ function Chats(){
useEffect(()=> { useEffect(()=> {
const getMessage = async ()=> const getMessage = async ()=>
{ {
if (!currentChat)
return ;
const data = {convId: currentChat.id}; const data = {convId: currentChat.id};
try { try {
const res = await api.post('/getMessage', data); const res = await api.post('/getMessage', data);
console.log("message of conv=", res.data)
setMessage(res.data); setMessage(res.data);
} catch(err) { } catch(err) {
@ -205,36 +158,30 @@ function Chats(){
getMessage(); getMessage();
}, [currentChat]); }, [currentChat]);
const handleSubmit = async (e: { preventDefault: () => void; })=>{ const handleSubmit = async (e)=>{
e.preventDefault(); e.preventDefault();
// console.log(`e= ${e.key}`) // console.log(`e= ${e.key}`)
// console.log(`name= ${user.username}`) // console.log(`name= ${user.username}`)
// let message;
if (!user || !currentChat)
return ;
const message = { const message = {
sender: user.username, sender: user.username,
text: newMessages, text: newMessages,
convId: currentChat.id, convId: currentChat.id,
members: null, members: null
id: null,
}; };
try{ try{
const allowed = await api.post('/allowed', {convId: currentChat.id}); console.log(`id= ${currentChat.id}`)
console.log("convid:", currentChat.id); const allowed = await api.post('/allowed', {convId: message.convId, username: user.username});
console.log("allowed= ", allowed.data)
if (!allowed.data) if (!allowed.data)
{
console.log("muted or banned");
return ; return ;
}
console.log("not muted or banned");
const res = await api.post('/message', message); const res = await api.post('/message', message);
const convMember = await api.post('/member', message); const convMember = await api.post('/member', message);
message.members = convMember.data.members; message.members = convMember.data.members;
message.id = res.data.id console.log(convMember);
// console.log(`currentChat= ${currentChat.id}`)
setMessage([...messages, res.data]); setMessage([...messages, res.data]);
setNewMessage(""); setNewMessage("");
if (socket.current)
socket.current.emit('sendMessage', message); socket.current.emit('sendMessage', message);
} }
catch(err){ catch(err){
@ -242,28 +189,27 @@ function Chats(){
} }
} }
const handleKeyPress = async (e: { key: string; })=> { const handleKeyPress = async (e)=>{
// console.log(`e in press= ${e.key}`) // console.log(`e in press= ${e.key}`)
if (e.key !== "Enter") if (e.key !== "Enter")
return ; return ;
// console.log(`name= ${user.username}`) // console.log(`name= ${user.username}`)
if (!user || !currentChat)
return ;
const message = { const message = {
sender: user.username, sender: user.username,
text: newMessages, text: newMessages,
convId: currentChat.id, convId: currentChat.id,
members: null, members: null
id: null,
}; };
try{ try{
console.log(`id= ${currentChat.id}`)
const res = await api.post('/message', message); const res = await api.post('/message', message);
const convMember = await api.post('/member', message); const convMember = await api.post('/member', message);
message.members = convMember.data.members; message.members = convMember.data.members;
message.id = res.data.id console.log(convMember);
// console.log(`currentChat= ${currentChat.id}`)
setMessage([...messages, res.data]); setMessage([...messages, res.data]);
setNewMessage(""); setNewMessage("");
if (socket.current)
socket.current.emit('sendMessage', message); socket.current.emit('sendMessage', message);
} }
catch(err){ catch(err){
@ -274,7 +220,7 @@ function Chats(){
const [friend, setFriend] = useState(""); const [friend, setFriend] = useState("");
// const [modalOpen, setModalOpen] = useState(false); const [modalOpen, setModalOpen] = useState(false);
const [addFriend, setAddFriend] = useState(false); const [addFriend, setAddFriend] = useState(false);
const [block, setBlock] = useState(false); const [block, setBlock] = useState(false);
@ -282,32 +228,8 @@ function Chats(){
const [showBlockAlert, setShowBlockAlert] = useState(false); const [showBlockAlert, setShowBlockAlert] = useState(false);
const [setting, setSetting] = useState(false); const [setting, setSetting] = useState(false);
const close = () => setModalOpen(false);
const [newGameModalOpen, setNewGameModalOpen] = useState(false); const open = () => setModalOpen(true);
const [newConversationModalOpen, setNewConversationModalOpen] = useState(false);
const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
const [users, setUsers] = useState<User[]>([]);
const openNewGameModal = () => {
setNewGameModalOpen(true);
};
const closeNewGameModal = () => {
setNewGameModalOpen(false);
};
const openNewConversationModal = () => {
setNewConversationModalOpen(true);
};
const closeNewConversationModal = () => {
setNewConversationModalOpen(false);
};
// const close = () => setModalOpen(false);
// const open = () => setModalOpen(true);
// const closeAddFriend = () => setAddFriend(false); // const closeAddFriend = () => setAddFriend(false);
// const closeBlock = () => setBlock(false); // const closeBlock = () => setBlock(false);
const closeSetting = () => setSetting(false); const closeSetting = () => setSetting(false);
@ -317,7 +239,7 @@ function Chats(){
// const closeBlock = () => setBlock(false); // const closeBlock = () => setBlock(false);
const handleFriend = (event: { target: { value: React.SetStateAction<string>; }; }) => { const handleFriend = (event) => {
setFriend(event.target.value); setFriend(event.target.value);
}; };
@ -369,15 +291,6 @@ function Chats(){
setShowBlockAlert(false); setShowBlockAlert(false);
}; };
const handleOptionChange = (selectId: number, selectedOption: string) => {
console.log("selected Option=", selectedOption)
setSelectTag((prevTags) =>
prevTags.map((tag) =>
tag.id === selectId ? { ...tag, selectedOption } : tag
)
);
};
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// HTML // HTML
@ -391,7 +304,7 @@ function Chats(){
<div className='navbar'> <div className='navbar'>
<img src={DefaultPic} alt="profile" className="pic"/> <img src={DefaultPic} alt="profile" className="pic"/>
<span> <span>
{isLoading || !user ? ( {isLoading ? (
<h4>Loading...</h4> <h4>Loading...</h4>
) : ( ) : (
<h4>{user.nickname}</h4> <h4>{user.nickname}</h4>
@ -443,24 +356,7 @@ function Chats(){
</div> */} </div> */}
<div className="end"> <div className="end">
{selectTags.map((selectTag) => ( <input className="lookForFriends" type="text" value={friend} onChange={handleFriend} />
<div key={selectTag.id}>
<select
value={selectTag.selectedOption}
className="lookForFriends"
onChange={(a) => handleOptionChange(selectTag.id, a.target.value)}
>
<option value="">{
selectTag.selectedOption ? selectTag.selectedOption : "Select an option"
}</option>
{users.filter((item) => !selectTags.some((tag) => tag.selectedOption === item.username)).map((item, index) => (
<option key={index} value={item.username}>
{item.username}
</option>
))}
</select>
</div>
))}
<TouchDiv> <TouchDiv>
<motion.div onClick={handleAddFriend}> <motion.div onClick={handleAddFriend}>
<MdOutlineGroupAdd /> <MdOutlineGroupAdd />
@ -497,7 +393,7 @@ function Chats(){
initial={false} initial={false}
onExitComplete={() => null} onExitComplete={() => null}
> >
{setting && <ModalSetting handleClose={closeSetting} convId={currentChat.id.toString()} socket={socket.current}/>} {setting && <ModalSetting handleClose={closeSetting} convId={currentChat.id}/>}
</AnimatePresence> </AnimatePresence>
</motion.div> </motion.div>
</TouchDiv> </TouchDiv>
@ -508,37 +404,18 @@ function Chats(){
</div> </div>
<div className="messages_box"> <div className="messages_box">
<div className="contact"> <div className="contact">
<UserChat> <UserChat>
<motion.div className="newMessage" onClick={openNewGameModal}>
<GrAdd />
<span>New Game</span>
</motion.div>
{newGameModalOpen && <GameModal handleClose={closeNewGameModal} />}
</UserChat>
<UserChat> <motion.div className="newMessage"
<motion.div className="newMessage" onClick={openNewConversationModal}> onClick={() => (modalOpen ? close() : open())}
>
<GrAdd/> <GrAdd/>
<span>New Conversation</span> <span>New Conversation</span>
</motion.div> </motion.div>
{newConversationModalOpen && ( {modalOpen && <Modal modalOpen={modalOpen} handleClose={close}/>}
<Modal handleClose={closeNewConversationModal} />
)}
</UserChat> </UserChat>
{conversations.map((c, index ) => {
{/* {partyInvite.map((c) => {
return (
)})
} */}
{partyInvite.map( i =>(
<PartyInvite currentInvite={i}/>
))}
{conversations.map((c: Conv, index ) => {
return ( return (
<div key={index} <div key={index}
onClick={() => setCurrentChat(c)}> onClick={() => setCurrentChat(c)}>
@ -546,7 +423,7 @@ function Chats(){
<img className="pic-user" src={DefaultPic} alt="User" /> <img className="pic-user" src={DefaultPic} alt="User" />
<div className="infoSideBar"> <div className="infoSideBar">
<span>{c.name}</span> <span>{c.name}</span>
{/* <SideP>Desc?</SideP> */} <SideP>Desc?</SideP>
</div> </div>
</UserChat> </UserChat>
</div> </div>
@ -555,12 +432,12 @@ function Chats(){
</div> </div>
{ {
currentChat && user ? ( currentChat ? (
<> <>
<div className="messages"> <div className="messages">
<div className="scroll"> <div className="scroll">
{messages.map(m=>( {messages.map(m=>(
<Message key={m.id} message= {m} own={m.sender === user.username}/> <Message message = {m} own={m.sender === user.username} user={m}/>
))} ))}
</div> </div>
{/* <Input/> */} {/* <Input/> */}

View File

@ -1,4 +1,3 @@
import React from 'react';
import { TbSend } from 'react-icons/tb'; import { TbSend } from 'react-icons/tb';

View File

@ -1,24 +1,23 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* Message.tsx :+: :+: :+: */ /* Message.jsx :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/01 18:24:46 by apommier #+# #+# */ /* Created: 2023/06/01 18:24:46 by apommier #+# #+# */
/* Updated: 2023/06/20 19:05:10 by apommier ### ########.fr */ /* Updated: 2023/06/12 17:05:08 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
import React, { HtmlHTMLAttributes } from "react";
import { useEffect, useState, useRef } from "react"; import { useEffect, useState, useRef } from "react";
import api from '../../script/axiosApi.tsx'; import api from '../../script/axiosApi';
import styled from "styled-components" import styled from "styled-components"
import DefaultPicture from '../../assets/profile.jpg' // import DefaultPicture from '../../assets/profile.jpg'
// import { useRef } from "react"; // import { useRef } from "react";
// import { useEffect } from "react"; // import { useEffect } from "react";
import '../../styles/Messages.css' import '../../styles/Messages.css'
import {User, Conv, Message} from "../../../interfaces.tsx"
import React from "react";
const MeStyleP = styled.p` const MeStyleP = styled.p`
background-color: #5843e4; background-color: #5843e4;
@ -27,23 +26,11 @@ const MeStyleP = styled.p`
color: white; color: white;
margin-right: 20px; margin-right: 20px;
` `
function MessageMe({message, own}){
interface MessageMeProps {
message: Message;
own: boolean;
}
function MessageMe({message, own}: MessageMeProps){
const [profilePicture, setProfilePicture] = useState(''); const [profilePicture, setProfilePicture] = useState('');
const [sender, setSender] = useState<User>();
const [conv, setConv] = useState<Conv>();
const [user, setUser] = useState<User>();
const scrollRef = useRef<HTMLDivElement>(null); const scrollRef = useRef<HTMLDivElement>(null);
const DefaultPicture: string = '../../assets/profile.jpg'
// console.log("Message eher")
useEffect(() => { useEffect(() => {
if (scrollRef.current) if (scrollRef.current)
{ {
@ -52,16 +39,9 @@ function MessageMe({message, own}: MessageMeProps){
const fetchProfilePicture = async () => { const fetchProfilePicture = async () => {
try { try {
// const user = await api.get("/profile"); // const user = await api.get("/profile");
const tmpSender = await api.post("/user", {username: message.sender})
const tmpConv = await api.post("/convId", {convId: message.convId})
// const tmpSender = await api.post("/user", {username: message.sender})
const tmpUser = await api.get("/profile")
const pic = await api.post("/getPicture", {username: message.sender}) const pic = await api.post("/getPicture", {username: message.sender})
// console.log(`user naem profile pic222= ${currentUser.username}`) // console.log(`user naem profile pic222= ${currentUser.username}`)
// console.log(` profile pic222= ${pic.data}`) // console.log(` profile pic222= ${pic.data}`)
setConv(tmpConv.data);
setUser(tmpUser.data);
setSender(tmpSender.data);
setProfilePicture(pic.data); setProfilePicture(pic.data);
} catch (error) { } catch (error) {
console.error('Error fetching profile picture:', error); console.error('Error fetching profile picture:', error);
@ -70,52 +50,23 @@ function MessageMe({message, own}: MessageMeProps){
fetchProfilePicture(); fetchProfilePicture();
}, []) }, [])
const handleButtonClick = () => {
if (!sender)
return ;
let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${sender.username}`;
// console.log("path= ", path)
// history(path, { replace: true });
// window.location.replace(path);
window.history.pushState({}, '', path);
window.location.reload();
};
if (!user || !sender || !conv)
{
// console.log("return")
return (<></>);
}
// console.log("result includes=", conv.banned.includes(user.username))
// console.log("result includes=", conv.blocked.includes(user.username))
if (user.blocked && user.blocked.includes(message.sender))
return (<></>);
// else if (conv.banned && conv.banned.includes(user.username))
// {
// console.log("return2")
// return (<></>);
// }
// console.log("noy return")
// if (user.blocked.includes(message.sender))/
return ( return (
<div className={own ? "meMessage" : "youMessage"} ref={scrollRef}> <div className={own ? "meMessage" : "youMessage"} ref={scrollRef}>
<div> <div>
{/* <img className="messageInfo" src={DefaultPic} alt="profile" />
*/}
{profilePicture ? ( {profilePicture ? (
<img className="messageInfo" onClick={() => handleButtonClick()} src={`data:image/jpeg;base64,${profilePicture}`} /> <img className="messageInfo" src={`data:image/jpeg;base64,${profilePicture}`} />
) : ( ) : (
<img className="messageInfo" onClick={() => handleButtonClick()} src={DefaultPicture} alt="Default Profile Picture" /> <img className="messageInfo" src={DefaultPicture} alt="Default Profile Picture" />
)} )}
</div> </div>
{/* <div className="usernameMesage">{message.senderNickname}</div> */} {/* <div className="usernameMesage">{message.senderNickname}</div> */}
{sender ? ( <div className="usernameMesage">{message.sender}</div>
<div className="usernameMesage">{sender.nickname}</div>
): ""}
<div className="messageContent"> <div className="messageContent">
<MeStyleP>{message.text}</MeStyleP> <MeStyleP>{message.text}</MeStyleP>
</div> </div>
</div> </div>
) )
} }

View File

@ -14,8 +14,7 @@ const MeStyleP = styled.p`
` `
function MessageMe(){ function MessageMe(){
// const scrollRef = useRef(); const scrollRef = useRef();
const scrollRef = useRef<HTMLDivElement>(null);
useEffect(() => { useEffect(() => {
scrollRef.current?.scrollIntoView({ behavior: "smooth"}) scrollRef.current?.scrollIntoView({ behavior: "smooth"})

View File

@ -14,7 +14,7 @@ const StyleP = styled.p`
` `
function MessageYou(){ function MessageYou(){
const scrollRef = useRef<HTMLDivElement>(null); const scrollRef = useRef();
useEffect(() => { useEffect(() => {
scrollRef.current?.scrollIntoView({ behavior: "smooth"}) scrollRef.current?.scrollIntoView({ behavior: "smooth"})

View File

@ -1,11 +1,11 @@
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import Backdrop from "../Sidebar/Backdrop.tsx"; import Backdrop from "../Sidebar/Backdrop";
// import { Rank } from "../../DataBase/DataRank" // import { Rank } from "../../DataBase/DataRank"
import '../../styles/Messages.css' import '../../styles/Messages.css'
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { GrAdd } from "react-icons/gr"; import { GrAdd } from "react-icons/gr";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import api from "../../script/axiosApi.tsx"; import api from "../../script/axiosApi";
import React from "react"; import React from "react";
const dropIn = { const dropIn = {
@ -77,7 +77,7 @@ const Modal = ({handleClose}) => {
} }
}; };
const saveSelectedOptions = async () => { const saveSelectedOptions = () => {
// const selectedOptions = selectTags.map((tag) => tag.selectedOption); // const selectedOptions = selectTags.map((tag) => tag.selectedOption);
const selectedOptions = selectTags.map((tag) => tag.selectedOption).filter((option) => option !== ''); const selectedOptions = selectTags.map((tag) => tag.selectedOption).filter((option) => option !== '');
@ -88,9 +88,8 @@ const Modal = ({handleClose}) => {
} }
try{ try{
// test // test
await api.post("/conv", data); api.post("/conv", data);
handleClose(); handleClose();
window.location.reload();
} catch(err) { } catch(err) {
console.log(err); console.log(err);
} }
@ -100,15 +99,17 @@ const Modal = ({handleClose}) => {
// let new_name; // let new_name;
return ( return (
<Backdrop onClick={handleClose}> <Backdrop >
<motion.div <motion.div
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
className="modal" className="modal"
// variant={dropIn} variant={dropIn}
initial="hidden" initial="hidden"
animate="visible" animate="visible"
exit="exit" exit="exit"
> >
{/* <p>New Conversation</p> */}
{selectTags.map((selectTag) => ( {selectTags.map((selectTag) => (
<div key={selectTag.id}> <div key={selectTag.id}>
<select <select
@ -145,7 +146,7 @@ const Modal = ({handleClose}) => {
> >
<option value="">Select an option</option> <option value="">Select an option</option>
{convs.map((conv) => ( {convs.map((conv) => (
!(!conv.group || conv.private || (conv.banned && conv.banned.includes(user.username)) || (conv.members && conv.members.includes(user.username))) && ( !(!conv.group || conv.private || (conv.banned && conv.banned.includes(channel)) || (conv.members && conv.members.includes(user.username))) && (
<option key={conv.id} value={conv.id}> <option key={conv.id} value={conv.id}>
{conv.name} {conv.name}
</option> </option>
@ -153,16 +154,36 @@ const Modal = ({handleClose}) => {
))} ))}
</select> </select>
)} )}
{channel.private ? (
<input className="mdp" placeholder="password" type="text" />
):("")}
<div className="div_submit"> <div className="div_submit">
<Link to='#' className="submit" onClick={ joinChannel }>Join</Link> <Link to='#' className="submit" onClick={ joinChannel }>Join</Link>
</div> </div>
{/* {selectTags.map((selectTag) => (
<div key={selectTag.id}>
<select
value={selectTag.selectedOption}
onChange={(a) => handleOptionChange(selectTag.id, a.target.value)}
>
<option value="">{
selectTag.selectedOption ? selectTag.selectedOption : "Select an option"
}</option>
{convs.filter((item) => !selectTags.some((tag) => tag.selectedOption === item.name)).map((item, index) => (
<option key={index} value={item.name}>
{item.name}
</option>
))}
</select>
</div>
))} */}
{/* <div>
<GrAdd onClick={addNewSelectedTag}/>
</div> */}
</motion.div> </motion.div>
</Backdrop> </Backdrop>

View File

@ -1,14 +1,11 @@
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import Backdrop from "../Sidebar/Backdrop.tsx"; import Backdrop from "../Sidebar/Backdrop.tsx";
// import { Rank } from "../../DataBase/DataRank" import { Rank } from "../../DataBase/DataRank"
import '../../styles/Messages.css' import '../../styles/Messages.css'
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { GrAdd } from "react-icons/gr"; import { GrAdd } from "react-icons/gr";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import api from "../../script/axiosApi.tsx"; import api from "../../script/axiosApi.tsx";
import React from "react";
import {User} from "../../../interfaces.tsx"
import { Socket } from "socket.io-client";
const dropIn = { const dropIn = {
@ -27,26 +24,13 @@ const dropIn = {
}; };
interface ModalSettingProps { const ModalSetting = ({handleClose, convId}) => {
handleClose: Function,
convId: string,
socket: Socket | null,
}
const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
const [password, setPassword] = useState(false); const [password, setPassword] = useState(false);
const [users, setUsers] = useState<User[]>([]); const [users, setUsers] = useState([]);
const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]); const [selectTags, setSelectTag] = useState([{ id: 1, selectedOption: ''}]);
const [selectedUser, setSelectedUser] = useState(""); const [selectedUser, setSelectedUser] = useState([]);
const [newName, setNewName] = useState(""); const [newName, setNewName] = useState("");
const [newPassword, setNewPassword] = useState(""); const [newPassword, setNewPassword] = useState("");
const [privateConv, setPrivateConv] = useState(false);
const dark = () => setPrivateConv(true);
const light = () => setPrivateConv(false);
const [mute, setMute] = useState(false);
const darkMute = () => setMute(false);
const lightMute = () => setMute(true);
useEffect(()=> { useEffect(()=> {
@ -67,7 +51,7 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
// const [selectedOptionArray, setSelectedOptionArray] = useState([]); // const [selectedOptionArray, setSelectedOptionArray] = useState([]);
const handleOptionChange = (selectId: number, selectedOption: string) => { const handleOptionChange = (selectId, selectedOption) => {
console.log("tag= ", selectTags) console.log("tag= ", selectTags)
console.log("option= ", selectedOption) console.log("option= ", selectedOption)
setSelectTag((prevTags) => setSelectTag((prevTags) =>
@ -78,12 +62,12 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
setSelectedUser(selectedOption) setSelectedUser(selectedOption)
}; };
const handleCheckPass = (e: { target: { checked: boolean | ((prevState: boolean) => boolean); }; }) => { const handleCheckPass = (e) => {
setPassword(e.target.checked); setPassword(e.target.checked);
console.log("password??", e.target.checked) console.log("password??", e.target.checked)
} }
const handleCheckPriv = (e: { target: { checked: any; }; }) => { const handleCheckPriv = (e) => {
// setPassword(e.target.checked); // setPassword(e.target.checked);
if (e.target.checked) if (e.target.checked)
{ {
@ -105,72 +89,59 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
} }
} }
const handleName = async (e: { key: string; })=>{ const handleName = async (e)=>{
if (e.key !== "Enter") if (e.key !== "Enter")
return ; return ;
try{ try{
api.post("/name", {convId: convId, name: newName}) api.post("/name", {convId: convId, name: newName})
window.location.reload()
} catch(err) { } catch(err) {
console.log(err); console.log(err);
} }
handleClose(); handleClose();
} }
const handlePassword = async (e: { key: string; })=>{ const handlePassword = async (e)=>{
if (e.key !== "Enter") if (e.key !== "Enter")
return ; return ;
try{ try{
await api.post("/password", {convId: convId, password: newPassword}) api.post("/password", {convId: convId, password: newPassword})
} catch(err) { } catch(err) {
console.log(err); console.log(err);
} }
handleClose(); handleClose();
} }
const handleBan = async () => { const handleBan = () => {
// console.log("ban option= ", selectedUser) // console.log("ban option= ", selectedUser)
try{ try{
// console.log("user select=", selectedUser.length) api.post("/ban", {convId: convId, username: selectedUser})
if (!selectedUser.length)
return ;
await api.post("/ban", {convId: convId, username: selectedUser})
if (socket)
{
console.log("emit to ban server")
socket.emit("ban", {username: selectedUser})
}
} catch(err) { } catch(err) {
console.log(err); console.log(err);
} }
handleClose(); handleClose();
}; };
const handleAdmin = async () => { const handleAdmin = () => {
if (!selectedUser.length)
return ;
try{ try{
await api.post("/admin", {convId: convId, username: selectedUser}) api.post("/admin", {convId: convId, username: selectedUser})
} catch(err) { } catch(err) {
console.log(err); console.log(err);
} }
handleClose(); handleClose();
}; };
const handleMute = async () => { const handleMute = () => {
if (!selectedUser.length)
return ;
try{ try{
await api.post("/mute", {convId: convId, username: selectedUser}) api.post("/mute", {convId: convId, username: selectedUser})
} catch(err) { } catch(err) {
console.log(err); console.log(err);
} }
handleClose(); handleClose();
}; };
const handleInvite = async () => { const handleInvite = () => {
try{ try{
await api.post("/invite", {convId: convId, username: selectedUser}) api.post("/invite", {convId: convId, username: selectedUser})
} catch(err) { } catch(err) {
console.log(err); console.log(err);
} }
@ -178,10 +149,11 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
}; };
return ( return (
<Backdrop onClick={handleClose}> <Backdrop>
<motion.div <motion.div
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
className="modalSetting" className="modalSetting"
variant={dropIn}
initial="hidden" initial="hidden"
animate="visible" animate="visible"
exit="exit" exit="exit"
@ -190,19 +162,15 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
{/* First selection */} {/* First selection */}
<div className="settingFirstPart"> <div className="settingFirstPart">
<div> <div>
<div> <p className="checkbox">Private<input class="check"type="checkbox" value="private" onChange={handleCheckPriv}/></p>
<Link to="#" onClick={light} className={ privateConv ? "submit" : "darkSubmit"}>Public</Link>
<Link to="#" onClick={dark} className={ privateConv ? "darkSubmit" : "submit"}>Private</Link>
</div>
{/* <p className="checkbox">Private<input className="check"type="checkbox" value="private" onChange={handleCheckPriv}/></p> */}
<p className="checkbox">Password<input type="checkbox" value="password" checked={password} onChange={handleCheckPass}/> </p> <p className="checkbox">Password<input type="checkbox" value="password" checked={password} onChange={handleCheckPass}/> </p>
{password || privateConv ? ( {password ? (
<input <input
onChange={(e) => setNewPassword(e.target.value)} onChange={(e) => setNewPassword(e.target.value)}
onKeyDown={handlePassword} onKeyDown={handlePassword}
type="password" type="text"
className="in" className="in"
placeholder="Password"/> placeholder="Password"/>
): ):
@ -248,14 +216,11 @@ const ModalSetting = ({handleClose, convId, socket }: ModalSettingProps) => {
<div> <div>
<Link to="#" onClick={handleInvite} className="submit">Send</Link> <Link to="#" onClick={handleInvite} className="submit">Send</Link>
<Link to="#" onClick={handleBan} className="submit">Ban</Link> <Link to="#" onClick={handleBan} className="submit">Ban</Link>
<Link to="#" onClick={mute ? darkMute : lightMute} className={mute ? "darkSubmit": "submit"}>Mute</Link> <Link to="#" onClick={handleMute} className="submit">Mute</Link>
<Link to="#" onClick={handleAdmin} className="submit">Admin</Link> <Link to="#" onClick={handleAdmin} className="submit">Admin</Link>
</div> </div>
</div> </div>
{mute ? (
<input type="text" className="in_howLong" placeholder="How long ?" />
):("")}
</motion.div> </motion.div>
</Backdrop> </Backdrop>

View File

@ -33,7 +33,6 @@ const ModalEdit = ( handleClose ) => {
const handler = e => const handler = e =>
{ {
setNickname(e.target.value); setNickname(e.target.value);
console.log("testeeeee")
const postNickname = async ()=>{ const postNickname = async ()=>{
try{ try{
await api.post("/nickname", {nickname: nickname}) await api.post("/nickname", {nickname: nickname})
@ -46,22 +45,6 @@ const ModalEdit = ( handleClose ) => {
}; };
postNickname(); postNickname();
} }
const handlePostNickname = async () =>
{
console.log("nickname=" ,nickname)
try{
await api.post("/nickname", {nickname: nickname})
window.location.reload();
// setUser(tmpUser.data);
// setIsLoading(false)
}
catch(err){
console.log(err);
}
}
// function handleClose(){ // function handleClose(){
// //do nothing // //do nothing
// } // }
@ -73,11 +56,10 @@ const ModalEdit = ( handleClose ) => {
animate="visible" animate="visible"
exit="exit"> exit="exit">
<h2>Type your new name</h2> <h2>Type your new name</h2>
<input className="text" maxLength="10" type="text" value={nickname} onChange={handler} handleClose/> <input className="text" type="text" value={nickname} onChange={handler} handleClose/>
<div> <div onClick={handleClose}>
<div className="button" onClick={ () => handlePostNickname()}> <div onClick={() => {UserProfile.UserName = nickname;}}>
change <Link className="button" to={""}>change</Link>
{/* <Link className="button" to={""}>change</Link> */}
</div> </div>
</div> </div>
</motion.div> </motion.div>

View File

@ -1,4 +1,3 @@
import React from "react";
@ -9,9 +8,8 @@ function Logout(){
// history(path, { replace: true }); // history(path, { replace: true });
// window.location.replace(path); // window.location.replace(path);
// window.history.pushState({}, '', path); // window.history.pushState({}, '', path);
window.history.pushState({}, '', path); window.history.pushState({}, null, path);
window.location.reload(); window.location.reload(false);
return (<></>)
} }
export default Logout; export default Logout;

View File

@ -4,7 +4,6 @@
// import '../DataBase/DataProfileUser.js' // import '../DataBase/DataProfileUser.js'
// import { DBWinLoss } from '../../DataBase/DummyDBWinLoss.js'; // import { DBWinLoss } from '../../DataBase/DummyDBWinLoss.js';
import '../../styles/Win_Loss.css' import '../../styles/Win_Loss.css'
import { User, Matchlog } from "../../../interfaces.tsx"
// import { UserProfile } from '../../DataBase/DataUserProfile'; // import { UserProfile } from '../../DataBase/DataUserProfile';
// import color from '../../utils/style/color.js'; // import color from '../../utils/style/color.js';
@ -47,12 +46,12 @@ import { User, Matchlog } from "../../../interfaces.tsx"
import React, { useState, useEffect, useRef } from "react"; import React, { useState, useEffect, useRef } from "react";
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import api from '../../script/axiosApi.tsx'; import api from '../../script/axiosApi';
function WinLoss() { function WinLoss() {
const [user, setUser] = useState<User>(); const [user, setUser] = useState(null);
const [history, setHistory] = useState([]); const [history, setHistory] = useState([]);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
@ -89,19 +88,19 @@ function WinLoss() {
<div className='tab'> <div className='tab'>
{isLoading || !history || !user ? ( {isLoading ? (
<h1>Loading...</h1> <h1>Loading...</h1>
// <span>Loading...</span> // <span>Loading...</span>
) : ( ) : (
<div className='scroll'> <div className='scroll'>
<h2 className='title'>Match history Win/Loss</h2> <h2 className='title'>Match history Win/Loss</h2>
{history.map((c: Matchlog, index) => { {history.map((c, index) => {
return ( return (
<div key={index} className='elements'> <div key={index} className='elements'>
<li key={index}> <li key={index}>
{/* <h4 className='content'>{c.id}</h4> */} {/* <h4 className='content'>{c.id}</h4> */}
<div className='content2nd'> <div key={index} className='content2nd'>
<h4 className='me'>{user.username}</h4> <h4 className='score'>{c.myScore} - {c.opScore} </h4> <h4 className="opponent">{c.opponent}</h4> <h4 key={index} className='me'>{user.username}</h4> <h4 key={index} className='score'>{c.myScore} - {c.opScore} </h4> <h4 key={index} className="opponent">{c.opponent}</h4>
</div> </div>
{/* <h4 className='content'>{c.openent}</h4> */} {/* <h4 className='content'>{c.openent}</h4> */}
</li> </li>

View File

@ -1,13 +1,7 @@
import React, { MouseEventHandler, ReactNode, HTMLAttributes } from "react";
import { motion } from "framer-motion" import { motion } from "framer-motion"
import "../../styles/Header.css" import "../../styles/Header.css"
interface backProps { const Backdrop = ({ children, onClick }) => {
children: ReactNode,
onClick: any
}
const Backdrop = ({ children, onClick }: backProps) => {
return ( return (
<motion.div className="backdrop" <motion.div className="backdrop"
onClick={onClick} onClick={onClick}

View File

@ -1,12 +1,12 @@
import React from "react";
import {motion} from "framer-motion" import {motion} from "framer-motion"
import Backdrop from "./Backdrop.tsx" import Backdrop from "./Backdrop"
import { SidebarData } from "./SidebarData.tsx" import { SidebarData } from "./SidebarData"
import {Link} from 'react-router-dom'; import {Link} from 'react-router-dom';
import * as AiIcons from 'react-icons/ai'; import * as AiIcons from 'react-icons/ai';
import "../../styles/Header.css" import "../../styles/Header.css"
import React from "react";
const dropIn = { const dropIn = {
hidden: { hidden: {
@ -20,11 +20,7 @@ const dropIn = {
}, },
} }
interface CloseProps { const Modal = ({ handleclose }) => {
handleclose: Function;
}
const Modal = ({ handleclose }: CloseProps) => {
return ( return (
<Backdrop onClick={handleclose}> <Backdrop onClick={handleclose}>
<motion.div <motion.div

View File

@ -26,7 +26,7 @@ export const SidebarData = [
cName: 'nav-text' cName: 'nav-text'
}, },
{ {
title: 'Friend', title: 'Social',
path: '/social', path: '/social',
icon: <IoIcons.IoMdPeople />, icon: <IoIcons.IoMdPeople />,
cName: 'nav-text' cName: 'nav-text'

View File

@ -6,7 +6,7 @@
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/09 08:18:58 by apommier #+# #+# */ /* Created: 2023/06/09 08:18:58 by apommier #+# #+# */
/* Updated: 2023/06/20 13:41:44 by apommier ### ########.fr */ /* Updated: 2023/06/18 13:12:26 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@ -18,7 +18,6 @@ import styled from "styled-components";
import { RxCircle } from "react-icons/rx"; import { RxCircle } from "react-icons/rx";
import { CgFontSpacing } from "react-icons/cg"; import { CgFontSpacing } from "react-icons/cg";
import React from "react"; import React from "react";
import {User} from "../../../interfaces.tsx"
const UserChat = styled.div ` const UserChat = styled.div `
padding: 5px; padding: 5px;
@ -38,12 +37,8 @@ const SideP = styled.p`
color: lightgray; color: lightgray;
margin-left: 15px; margin-left: 15px;
` `
interface UserProps {
currentUser: User
}
// export default function Friend({currentUser}) export default function Friend({currentUser})
export default function Friend({currentUser}: UserProps)
{ {
const [profilePicture, setProfilePicture] = useState(''); const [profilePicture, setProfilePicture] = useState('');
@ -63,7 +58,7 @@ export default function Friend({currentUser}: UserProps)
fetchProfilePicture(); fetchProfilePicture();
}) })
function getStatus(friend: User) function getStatus(friend)
{ {
let status = friend.status let status = friend.status
console.log(`status= ${status}`) console.log(`status= ${status}`)
@ -78,19 +73,19 @@ export default function Friend({currentUser}: UserProps)
return statusColor; return statusColor;
} }
const handleSpectate = (user: User) => { const handleSpectate = (user) => {
//socket connection and add to party with one with username //socket connection and add to party with one with username
console.log(`spectate hehe`) console.log(`spectate hehe`)
console.log(`user= ${user}`) console.log(`user= ${user}`)
}; };
const handleButtonClick = (user: User) => { const handleButtonClick = (user) => {
let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`; let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`;
console.log("path= ", path) console.log("path= ", path)
// history(path, { replace: true }); // history(path, { replace: true });
// window.location.replace(path); // window.location.replace(path);
window.history.pushState({}, '', path); window.history.pushState({}, null, path);
window.location.reload(); window.location.reload(false);
}; };
return ( return (
@ -102,7 +97,7 @@ export default function Friend({currentUser}: UserProps)
)} )}
<div className="infoSideBar"> <div className="infoSideBar">
<span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span> <span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span>
<RxCircle color={getStatus(currentUser)} /> <RxCircle icon={RxCircle} color={getStatus(currentUser)} />
<button onClick={() => handleSpectate(currentUser)} >Invite</button> <button onClick={() => handleSpectate(currentUser)} >Invite</button>
{getStatus(currentUser) !== 'blue' ? ( {getStatus(currentUser) !== 'blue' ? (
<></> <></>

View File

@ -0,0 +1,111 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* Friend.jsx :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/09 08:18:58 by apommier #+# #+# */
/* Updated: 2023/06/15 19:05:14 by apommier ### ########.fr */
/* */
/* ************************************************************************** */
import { useEffect, useState } from "react";
import api from '../../script/axiosApi.tsx';
import DefaultPicture from '../../assets/profile.jpg'
import styled from "styled-components";
import { RxCircle } from "react-icons/rx";
import { CgFontSpacing } from "react-icons/cg";
const UserChat = styled.div `
padding: 5px;
display: flex;
align-items: center;
gap: 5px;
color: white;
cursor: pointer;
&:hover{
background-color: #3e3c61;
}
`
const SideP = styled.p`
font-size: 14px;
color: lightgray;
margin-left: 15px;
`
export default function Friend({currentUser})
{
const [profilePicture, setProfilePicture] = useState('');
useEffect(() => {
const fetchProfilePicture = async () => {
try {
// const user = await api.get("/profile");
const pic = await api.post("/getPicture", {username: currentUser.username})
// console.log(`user naem profile pic222= ${currentUser.username}`)
// console.log(` profile pic222= ${pic.data}`)
setProfilePicture(pic.data);
} catch (error) {
console.error('Error fetching profile picture:', error);
}
};
fetchProfilePicture();
})
function getStatus(friend)
{
let status = friend.status
console.log(`status= ${status}`)
let statusColor;
if (status === 0)
statusColor = 'grey';
else if (status === 1)
statusColor = 'green';
else if (status === 2)
statusColor = 'blue';
return statusColor;
}
const handleSpectate = (user) => {
//socket connection and add to party with one with username
console.log(`spectate hehe`)
console.log(`user= ${user}`)
};
const handleButtonClick = (user) => {
let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`;
console.log("path= ", path)
// history(path, { replace: true });
// window.location.replace(path);
window.history.pushState({}, null, path);
window.location.reload(false);
};
return (
<UserChat>
{profilePicture ? (
<img className="pic-user" src={`data:image/jpeg;base64,${profilePicture}`} />
) : (
<img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" />
)}
<div className="infoSideBar">
<span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span>
<RxCircle icon={RxCircle} color={getStatus(currentUser)} />
<button onClick={() => handleSpectate(currentUser)} >Invite</button>
{getStatus(currentUser) !== 'blue' ? (
<></>
) : (
<button onClick={() => handleSpectate(currentUser)} >Spectate</button>
)}
</div>
</UserChat>
)
}

View File

@ -5,8 +5,6 @@ import DefaultPicture from '../../assets/profile.jpg'
import styled from "styled-components"; import styled from "styled-components";
import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx"; import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx";
import React from "react";
import {User} from "../../../interfaces.tsx"
const UserChat = styled.div ` const UserChat = styled.div `
padding: 5px; padding: 5px;
@ -27,14 +25,10 @@ const SideP = styled.p`
margin-left: 15px; margin-left: 15px;
` `
interface UserProps { export default function Friend({currentUser})
currentUser: User
}
export default function Friend({currentUser}: UserProps)
{ {
const [profilePicture, setProfilePicture] = useState(''); const [profilePicture, setProfilePicture] = useState('');
const [request, setRequest] = useState<User>(); //user who invite const [request, setRequest] = useState(''); //user who invite
const [clickEvent, setClickEvent] = useState(false); const [clickEvent, setClickEvent] = useState(false);
// const [user, setUser] = useState(null); // const [user, setUser] = useState(null);
@ -58,15 +52,15 @@ export default function Friend({currentUser}: UserProps)
fetchProfilePicture(); fetchProfilePicture();
}, [clickEvent]) }, [clickEvent])
const handleButtonClick = (user: User) => { const handleButtonClick = (user) => {
let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`; let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`;
// history(path, { replace: true }); // history(path, { replace: true });
// window.location.replace(path); // window.location.replace(path);
window.history.pushState({}, '', path); window.history.pushState({}, null, path);
window.location.reload(); window.location.reload(false);
}; };
const Accept = async (request: User) => { const Accept = async (request) => {
try{ try{
await api.post("/friend", {username: request.username}) await api.post("/friend", {username: request.username})
setClickEvent(true); setClickEvent(true);
@ -77,7 +71,7 @@ export default function Friend({currentUser}: UserProps)
console.log(`request = ${request}`) console.log(`request = ${request}`)
} }
const Refuse = async (request: User) => { const Refuse = async (request) => {
try{ try{
await api.post("/refuseInvite", {username: request.username}) await api.post("/refuseInvite", {username: request.username})
setClickEvent(true); setClickEvent(true);
@ -100,13 +94,12 @@ export default function Friend({currentUser}: UserProps)
) : ( ) : (
<img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" /> <img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" />
)} )}
{request ? (
<div className="infoSideBar"> <div className="infoSideBar">
<span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span> <span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span>
<RxCheckCircled onClick={() => Accept(request)} color={'green'}/> <RxCheckCircled onClick={() => Accept(request)} color={'green'}/>
<RxCircleBackslash onClick={() => Refuse(request)} color={'red'}/> <RxCircleBackslash onClick={() => Refuse(request)} color={'red'}/>
</div> </div>
) : ( "" )}
</UserChat> </UserChat>
) )
} }

View File

@ -0,0 +1,106 @@
import { useEffect, useState } from "react";
import api from '../../script/axiosApi.tsx';
import DefaultPicture from '../../assets/profile.jpg'
import styled from "styled-components";
import { RxCheckCircled, RxCircleBackslash } from "react-icons/rx";
const UserChat = styled.div `
padding: 5px;
display: flex;
align-items: center;
gap: 5px;
color: white;
cursor: pointer;
&:hover{
background-color: #3e3c61;
}
`
const SideP = styled.p`
font-size: 14px;
color: lightgray;
margin-left: 15px;
`
export default function Friend({currentUser})
{
const [profilePicture, setProfilePicture] = useState('');
const [request, setRequest] = useState(''); //user who invite
const [clickEvent, setClickEvent] = useState(false);
// const [user, setUser] = useState(null);
useEffect(() => {
const fetchProfilePicture = async () => {
try {
// const user = await api.get("/profile");\
// const tmpUser = await api.get("/profile")
const pic = await api.post("/getPicture", {username: currentUser.username})
const tmpRequest = await api.post("/user", {username: currentUser.username})
// setUser(tmpUser.data);
setRequest(tmpRequest.data);
// console.log(`user naem profile pic222= ${currentUser.username}`)
// console.log(` profile pic222= ${pic.data}`)
setProfilePicture(pic.data);
} catch (error) {
console.error('Error fetching profile picture:', error);
}
};
fetchProfilePicture();
}, [clickEvent])
const handleButtonClick = (user) => {
let path = `http://` + process.env.REACT_APP_BASE_URL + `/profile/${user.username}`;
// history(path, { replace: true });
// window.location.replace(path);
window.history.pushState({}, null, path);
window.location.reload(false);
};
const Accept = async (request) => {
try{
await api.post("/friend", {username: request.username})
setClickEvent(true);
} catch(err) {
console.log(err);
}
console.log("accept")
console.log(`request = ${request}`)
}
const Refuse = async (request) => {
try{
await api.post("/refuseInvite", {username: request.username})
setClickEvent(true);
} catch(err) {
console.log(err);
}
console.log("refuse")
console.log(`request = ${request}`)
}
// Vérifier si le contenu doit être caché
if (clickEvent) {
return null; // Rendre null pour ne pas afficher le contenu
}
return (
<UserChat>
{profilePicture ? (
<img className="pic-user" src={`data:image/jpeg;base64,${profilePicture}`} />
) : (
<img className="pic-user" src={DefaultPicture} alt="Default Profile Picture" />
)}
<div className="infoSideBar">
<span onClick={() => handleButtonClick(currentUser)}>{currentUser.nickname}</span>
<RxCheckCircled onClick={() => Accept(request)} color={'green'}/>
<RxCircleBackslash onClick={() => Refuse(request)} color={'red'}/>
</div>
</UserChat>
)
}

View File

@ -9,7 +9,6 @@ import FriendRequest from './FriendRequest.tsx';
import { ImBlocked } from 'react-icons/im'; import { ImBlocked } from 'react-icons/im';
import { MdOutlineGroupAdd } from 'react-icons/md'; import { MdOutlineGroupAdd } from 'react-icons/md';
import {User} from "../../../interfaces.tsx"
// import React from "react"; // import React from "react";
@ -35,11 +34,12 @@ function Social (){
const [friends, setFriends] = useState([]); const [friends, setFriends] = useState([]);
const [invite, setInvite] = useState([]); const [invite, setInvite] = useState([]);
const [isLoading, setIsLoading] = useState<boolean>(true); const [isLoading, setIsLoading] = useState(true);
const [user, setUser] = useState<User>(); const [user, setUser] = useState(null);
const [profilePicture, setProfilePicture] = useState(''); const [profilePicture, setProfilePicture] = useState('');
useEffect(()=> { useEffect(()=> {
const getFriend = async ()=>{ const getFriend = async ()=>{
try{ try{
const tmpFriends = await api.get("/friends") const tmpFriends = await api.get("/friends")
@ -94,7 +94,7 @@ function Social (){
<img className="pic" src={DefaultPicture} alt="Default Profile Picture" /> <img className="pic" src={DefaultPicture} alt="Default Profile Picture" />
)} )}
<span> <span>
{isLoading || !user ? ( {isLoading ? (
<h4>Loading...</h4> <h4>Loading...</h4>
) : ( ) : (
<h4>{user.nickname}</h4> <h4>{user.nickname}</h4>

View File

@ -1,20 +1,14 @@
import React from 'react';
import { useEffect } from 'react'; import { useEffect } from 'react';
// import { useState, useRef } from 'react'; // import { useState, useRef } from 'react';
import DrawCanvas from './canvas.tsx'; import DrawCanvas from './canvas';
import queryString from 'query-string'; import queryString from 'query-string';
import '../styles/field.css'; import '../styles/field.css';
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import React from 'react';
// import { withRouter } from 'react-router-dom'; // import { withRouter } from 'react-router-dom';
interface GameProps {
privateParty: boolean,
username?: string
gameId?: number
}
function Field() function Field()
{ {
useEffect(() => { useEffect(() => {
@ -23,7 +17,6 @@ function Field()
console.log("launch canva hehe") console.log("launch canva hehe")
let Modifiers = 0; let Modifiers = 0;
let info: GameProps;
if (queryParams.superpower === 'true') { if (queryParams.superpower === 'true') {
Modifiers += 1; Modifiers += 1;
@ -36,37 +29,81 @@ function Field()
if (queryParams.speed === 'true') { if (queryParams.speed === 'true') {
Modifiers += 4; Modifiers += 4;
} }
// console.log(`modifiers= ${Modifiers}`)
// DrawCanvas(Modifiers);
// return () => {
// console.log("000000000000000000000000000000000")
// // socketRef.current.disconnect();
// };
info = { // console.log(`modifiers= ${Modifiers}`)
privateParty: false, const cleanup = DrawCanvas(Modifiers);
}
if (queryParams.username)
{
console.log("user= ", queryParams.username)
info = {
privateParty: true,
username: queryParams.username as string,
gameId: queryParams.gameId as unknown as number
}
console.log("info of param vefore canvas=", info)
}
const cleanup = DrawCanvas(Modifiers, info);
return () => { return () => {
console.log("Cleanup"); console.log("Cleanup");
// cleanup(); // Call the cleanup function to stop the ongoing process or perform necessary cleanup tasks cleanup(); // Call the cleanup function to stop the ongoing process or perform necessary cleanup tasks
if (cleanup)
cleanup();
}; };
}, []); }, []);
// const [buttonClicked, setButtonClicked] = useState(false);
// const handleButtonClick = () => {
// drawCanvas();
// setButtonClicked(true);
// };
return ( return (
<div className="field" id="canvas_container"> <div className="field" id="canvas_container">
<canvas id="myCanvas"></canvas> <canvas id="myCanvas"></canvas>
{/* <button onClick={handleButtonClick}>Draw on Canvas</button> */}
{/* {buttonClicked && <canvas id="myCanvas"></canvas>}
{!buttonClicked && <button onClick={handleButtonClick}>Draw on Canvas</button>} */}
</div> </div>
); );
} }
export default Field; export default Field;
// export default withRouter(Field);
// function Field() {
// const [buttonClicked, setButtonClicked] = useState(false);
// const handleButtonClick = () => {
// const canvas = document.createElement('canvas');
// canvas.id = 'myCanvas';
// console.log("button clicked")
// document.getElementById('canvas_container').appendChild(canvas);
// setButtonClicked(true);
// drawCanvas(canvas);
// };
// setButtonClicked(true);
// return (
// // <div className="field" id="canvas_container">
// <div className={`notClicked ${buttonClicked ? 'clicked' : ''}`} id="canvas_container">
// {!buttonClicked && <button className="playButton" onClick={handleButtonClick}>Play</button>}
// </div>
// );
// }
// export default Field;
// function draw() {
// // Effacer le canvas
// ctx.clearRect(0, 0, canvas.width, canvas.height);
// // Dessiner la raquette
// ctx.fillRect(canvas.width - paddleWidth, paddleY, paddleWidth, paddleHeight);
// // Appeler la fonction draw à chaque frame
// requestAnimationFrame(draw);
// }
// draw(); // Appeler la fonction draw pour la première fois
// const canvas = document.getElementById('myCanvas');
// canvas.width = 500;
// canvas.height = 500;
// const ctx = canvas.getContext('2d');
// ctx.fillRect(50, 50, 1000, 1000);

View File

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import PlayButton from "../components/Game/PlayButton.tsx"; import PlayButton from "../components/Game/PlayButton";
import Ranking from "../components/Game/Ranking.tsx"; import Ranking from "../components/Game/Ranking";
import '../styles/Game.css' import '../styles/Game.css'
function Game(){ function Game(){

View File

@ -9,7 +9,7 @@ function Head()
<title>BEST PONG EVER</title> <title>BEST PONG EVER</title>
{/* <script src="./script/login.js"></script> */} {/* <script src="./script/login.js"></script> */}
<link rel="preconnect" href="https://fonts.googleapis.com"></link> <link rel="preconnect" href="https://fonts.googleapis.com"></link>
{/* <link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="true"></link> */} <link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="true"></link>
<link href="https://fonts.googleapis.com/css2?family=Rubik+Iso&display=swap" rel="stylesheet"></link> <link href="https://fonts.googleapis.com/css2?family=Rubik+Iso&display=swap" rel="stylesheet"></link>
</div> </div>
); );

View File

@ -1,42 +1,37 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* Home.tsx :+: :+: :+: */ /* Home.jsx :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */ /* By: apommier <apommier@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2023/06/09 08:19:04 by apommier #+# #+# */ /* Created: 2023/06/09 08:19:04 by apommier #+# #+# */
/* Updated: 2023/06/23 15:58:14 by apommier ### ########.fr */ /* Updated: 2023/06/09 08:19:05 by apommier ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
// import { React, useState } from "react"; // import { React, useState } from "react";
import '../styles/Profile.css' import '../styles/Profile.css'
// import '../styles/App.css' // import '../styles/App.css'
import DefaultPicture from "../assets/profile.jpg"; // import DefaultPicture from "../assets/profile.jpg";
import WinLoss from "../components/Profile/Win_Loss.tsx"; import WinLoss from "../components/Profile/Win_Loss";
import { motion, AnimatePresence } from 'framer-motion' import { motion, AnimatePresence } from 'framer-motion'
// import { AiFillEdit } from 'react-icons/ai' // import { AiFillEdit } from 'react-icons/ai'
// import { GrClose } from 'react-icons/gr' // import { GrClose } from 'react-icons/gr'
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import ModalEdit from "../components/Profile/EditName.tsx"; import ModalEdit from "../components/Profile/EditName";
import {AiOutlineHistory} from 'react-icons/ai' import {AiOutlineHistory} from 'react-icons/ai'
import { MdQrCodeScanner, MdOutlinePhotoLibrary } from 'react-icons/md';
import { GiWingedSword, GiCrownedSkull } from 'react-icons/gi';
// import { Link } from "react-router-dom"; // import { Link } from "react-router-dom";
// import {UserProfile} from "../DataBase/DataUserProfile"; // import {UserProfile} from "../DataBase/DataUserProfile";
// import axios from "axios"; // import axios from "axios";
import api from '../script/axiosApi.tsx'; import api from '../script/axiosApi';
import { CgEditMarkup } from 'react-icons/cg' import { CgEditMarkup } from 'react-icons/cg'
import { IoCloseCircleOutline } from "react-icons/io5"; import { IoCloseCircleOutline } from "react-icons/io5";
// import * as React from 'react'; // import * as React from 'react';
// import { useState, useEffect, useParams} from "react"; // import { useState, useEffect, useParams} from "react";
import React, { useState, useEffect, useRef, ChangeEventHandler } from "react"; import React, { useState, useEffect, useRef } from "react";
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import {User, Conv} from "../../interfaces.tsx"
import YellowAlert from '../components/Alert/YellowAlert.tsx';
// axios.get("http://localhost/api") // axios.get("http://localhost/api")
// .then((response) => { // .then((response) => {
// response = response.json() // response = response.json()
@ -48,70 +43,43 @@ import YellowAlert from '../components/Alert/YellowAlert.tsx';
function Profile () { function Profile () {
const [user, setUser] = useState<User>(); const DefaultPicture: string = "../assets/profile.jpg";
const [isLoading, setIsLoading] = useState<boolean>(true); const [user, setUser] = useState(null);
const [modalOpen, setModalOpen] = useState<boolean>(false); const [isLoading, setIsLoading] = useState(true);
const [mine, setMine] = useState<boolean>(false); const [modalOpen, setModalOpen] = useState(false);
const [mine, setMine] = useState(false);
const close = () => setModalOpen(false); const close = () => setModalOpen(false);
const open = () => setModalOpen(true); const open = () => setModalOpen(true);
const { username } = useParams(); const { username } = useParams();
// const [selectedPhoto, setSelectedPhoto] = useState(); const [selectedPhoto, setSelectedPhoto] = useState(null);
// const [selectedPhoto, setSelectedPhoto] = useState(null);
const [profilePicture, setProfilePicture] = useState(''); const [profilePicture, setProfilePicture] = useState('');
const handleFileChange = async (event: { target: { files: any; }; }) => { const handleFileChange = (event) => {
// const files = event.target.files; // const file = event.target.files[0];
// if (files && files.length > 0) { setSelectedPhoto(event.target.files[0]);
const photo = (event.target.files[0]); // try{
console.log("file selected") // api.post("/picture", {picture: URL.createObjectURL(file)})
if (photo) { // }
console.log("selected photo") // catch(err){
const formData = new FormData(); // console.log(err);
formData.append('photo', photo);
try {
await api.post('/picture', formData);
console.log('File uploaded successfully');
window.location.reload();
} catch (error) {
console.error('Error uploading file:', error);
}
}
// } // }
}; };
// const handleUpload = async () => { const handleUpload = async () => {
// const formData = new FormData(); const formData: FormData = new FormData();
// formData.append('photo', selectedPhoto); if (selectedPhoto){
// try { formData.append('photo', selectedPhoto);
// await api.post('/picture', formData); }
// console.log('File uploaded successfully'); try {
// window.location.reload(); await api.post('/picture', formData);
// } catch (error) { console.log('File uploaded successfully');
// console.error('Error uploading file:', error); window.location.reload(false);
// } } catch (error) {
// }; console.error('Error uploading file:', error);
}
// const handleUpload = async (event: React.FormEvent) => { };
// event.preventDefault()
// console.log("up photo")
// if (selectedPhoto) {
// console.log("selected photo")
// const formData = new FormData();
// formData.append('photo', selectedPhoto);
// try {
// await api.post('/picture', formData);
// console.log('File uploaded successfully');
// window.location.reload();
// } catch (error) {
// console.error('Error uploading file:', error);
// }
// } else {
// console.log('No file selected');
// }
// };
useEffect(()=> { useEffect(()=> {
const getUser = async ()=>{ const getUser = async ()=>{
@ -157,10 +125,12 @@ function Profile () {
<img className="profile-pic" src={DefaultPicture} alt="Default Profile Picture" /> <img className="profile-pic" src={DefaultPicture} alt="Default Profile Picture" />
)} )}
<span> <span>
{isLoading || !user ? ( {isLoading ? (
<h1>Loading...</h1> <h1>Loading...</h1>
) : ( ) : (
user ? (
<h1>{user.nickname}</h1> <h1>{user.nickname}</h1>
) : ("")
)} )}
</span> </span>
@ -168,22 +138,16 @@ function Profile () {
{mine ? ( {mine ? (
<div> <div>
<motion.div > <motion.div onClick={() => (modalOpen ? close() : open())}>
<Link to="#" className="edit_name" onClick={() => (modalOpen ? close() : open())}> <Link to="#" className="edit_name">
{modalOpen === true ? <IoCloseCircleOutline/> : <CgEditMarkup/>} {modalOpen === true ? <IoCloseCircleOutline/> : <CgEditMarkup/>}
</Link> </Link>
{modalOpen === true ? ("") : (
<>
<label htmlFor="file-input" className="edit_name"><MdOutlinePhotoLibrary/></label>
<input type="file" id="file-input" className="file-input" accept="image/*" onChange={handleFileChange} />
</>
)}
</motion.div> </motion.div>
{/* <div className="file-upload-container"> */} <div>
{/* <button onClick={handleUpload} className="upload-button">Upload</button> */} <input type="file" accept="image/*" onChange={handleFileChange} />
{/* <button onClick={handleUpload} className="upload-button">Upload</button> */} <button onClick={handleUpload}>Upload</button>
{/* </div> */} </div>
</div> </div>
) : ( ) : (
<></> <></>
@ -202,49 +166,13 @@ function Profile () {
function Home () { function Home () {
const [move, setmove ] = useState(false); const [move, setmove ] = useState(false);
const [user, setUser] = useState([]);
const [successQr, setSuccessQr] = useState(false);
const [successSword, setSuccessSword] = useState(false);
const [successCrown, setSuccessCrown] = useState(false);
const closeQr = () => setSuccessQr(false);
const closeSword = () => setSuccessSword(false);
const closeCrown = () => setSuccessCrown(false);
useEffect(() => {
const fetchSuccess = async () => {
try {
const tmpUser = await api.get("/profile");
setUser(tmpUser.data);
}
catch (error)
{
console.log(error);
}
};
fetchSuccess();
})
return ( return (
<motion.div className="page" <motion.div className="page"
initial={{opacity: -1}} initial={{opacity: -1}}
animate={{opacity: 1}} animate={{opacity: 1}}
exit={{opacity: -1}}> exit={{opacity: -1}}>
<div>
{user.otp_verified ? (
<MdQrCodeScanner className='success' onClick={() => setSuccessQr(true)}/>
):("")}
{user.win >= 2 ? (
<GiWingedSword className="success" onClick={() => setSuccessSword(true)}/>
):("")}
{user.win >= 5 ? (
<GiCrownedSkull className="success" onClick={() => setSuccessCrown(true)}/>
):("")}
</div>
<div className="home"> <div className="home">
<motion.div animate={{x: move ? -200: 120}} <motion.div animate={{x: move ? -200: 170}}
transition={{type: "tween", duration: 0.5}}> transition={{type: "tween", duration: 0.5}}>
<Profile/> <Profile/>
</motion.div> </motion.div>
@ -258,19 +186,6 @@ function Home () {
onClick={ () => setmove(!move)}> onClick={ () => setmove(!move)}>
<Link to="#" className="history"><AiOutlineHistory/> Match History</Link> <Link to="#" className="history"><AiOutlineHistory/> Match History</Link>
</motion.div> </motion.div>
<AnimatePresence initial={false} onExitComplete={() => null}>
{successQr ? (
<YellowAlert handleClose={closeQr} text={"Success: You have the 2fa success!"} icon={1} />
) : ("")}
{successCrown ? (
<YellowAlert handleClose={closeCrown} text={"Success: 5 victory ? You won king slayer success!"} icon={2}/>
) : ("")}
{successSword ? (
<YellowAlert handleClose={closeSword} text={"Success: 2 victory ? You won the noobi warrior success!"} icon={3}/>
) : ("")}
</AnimatePresence>
</motion.div> </motion.div>
) )
} }

View File

@ -16,15 +16,12 @@ function Login42()
const data = { const data = {
grant_type: 'authorization_code', grant_type: 'authorization_code',
// client_id: 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41', client_id: 'u-s4t2ud-6d29dfa49ba7146577ffd8bf595ae8d9e5aaa3e0a9615df18777171ebf836a41',
// client_secret: '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', client_secret: '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',
client_id: process.env.REACT_APP_CLIENT_UID,
client_secret: process.env.REACT_APP_API_SECRET,
code: code, code: code,
redirect_uri: 'http://' + process.env.REACT_APP_BASE_URL + '/login42', redirect_uri: 'http://localhost:8080/login42',
}; };
axios.post('https://api.intra.42.fr/oauth/token', data) axios.post('https://api.intra.42.fr/oauth/token', data)
.then(response => { .then(response => {
// handle success response // handle success response
@ -38,7 +35,7 @@ function Login42()
return ( return (
<div> <div>
<p>"COUCOU LOGIN" </p> <p>"COUCOU LOGIN$@ jeje" </p>
{/* <script src="../script/login42.js"></script> */} {/* <script src="../script/login42.js"></script> */}
</div> </div>
); );

View File

@ -1,31 +1,14 @@
import React from "react"; import React from "react";
// import Sidebar from '../components/Messages/Sidebar' // import Sidebar from '../components/Messages/Sidebar'
import Chats from "../components/Messages/Chats.tsx" import Chats from "../components/Messages/Chats"
import '../styles/Messages.css' import '../styles/Messages.css'
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
// import {io} from 'socket.io-client' // import {io} from 'socket.io-client'
function Messages() { function Messages() {
// const socket = useRef(io("ws://localhost:8900"))
// useEffect(() => {
// setSocket(io("ws://localhost:8900"))
// }, [])
// const socket = socketIO.connect('http://localhost:4000');
// axios.get('http://localhost/api/user/id')
// .then(function());
// console.log(socket)
// useEffect(() => {
// socket.current.emit("addUser", user._id);
// socket.current.on("getUsers", users=>{
// console.log(users)
// })
// }, [user])
return ( return (
<> <div>
<motion.div className="home" <motion.div className="home"
initial={{opacity: 0}} initial={{opacity: 0}}
animate={{opacity: 1}} animate={{opacity: 1}}
@ -35,7 +18,7 @@ function Messages() {
<Chats/> <Chats/>
</div> </div>
</motion.div> </motion.div>
</> </div>
); );
} }

View File

@ -3,10 +3,11 @@ import React, { useEffect, useRef, useState } from "react";
// import { redirect } from "react-router-dom"; // import { redirect } from "react-router-dom";
import "../styles/App.css"; import "../styles/App.css";
import api from '../script/axiosApi.tsx'; import api from '../script/axiosApi';
import QRCodeStyling from "qr-code-styling"; import QRCodeStyling from "qr-code-styling";
import { motion } from 'framer-motion' import { motion } from 'framer-motion'
import { MutableRefObject } from "react";
@ -30,9 +31,9 @@ const qrCode = new QRCodeStyling({
function QrCode () { function QrCode () {
// const url = "https://www.youtube.com"; // const url = "https://www.youtube.com";
// const ref = useRef(null); // const ref = useRef(null);
const ref = useRef<HTMLDivElement>(null); const ref: MutableRefObject<HTMLElement | null> = {current: null};
const [user, setUser] = useState(false); const [user, setUser] = useState(false);
const [url, setUrl] = useState(""); const [url, setUrl] = useState(false);
const [secret, setSecret] = useState(false); const [secret, setSecret] = useState(false);
const [code, setCode] = useState(''); const [code, setCode] = useState('');
const [activated, setActivated] = useState(false); const [activated, setActivated] = useState(false);
@ -40,8 +41,10 @@ function QrCode () {
// const history = useHistory(); // const history = useHistory();
useEffect(() => { useEffect(() => {
if (ref.current) if (ref.current){
qrCode.append(ref.current); qrCode.append(ref.current);
}
const getUser = async ()=>{ const getUser = async ()=>{
try{ try{
const tmpUser = await api.get("/profile"); const tmpUser = await api.get("/profile");
@ -67,11 +70,13 @@ function QrCode () {
}, []); }, []);
useEffect(() => { useEffect(() => {
qrCode.update({data: url}); qrCode.update({
data: url
});
}, [url]); }, [url]);
const handleKeyPress = async (e: { key: string; })=>{ const handleKeyPress = async (e)=>{
// console.log(`e in press= ${e.key}`) // console.log(`e in press= ${e.key}`)
if (e.key !== "Enter") if (e.key !== "Enter")
return ; return ;
@ -86,8 +91,8 @@ function QrCode () {
// history.push('/login') // history.push('/login')
const path = 'http://' + process.env.REACT_APP_BASE_URL + '/'; const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
window.history.pushState({}, '', path); window.history.pushState({}, null, path);
window.location.reload(); window.location.reload(false);
} }
else else
@ -106,8 +111,8 @@ function QrCode () {
try { try {
await api.post("/deleteOtp") await api.post("/deleteOtp")
// const path = 'http://' + process.env.REACT_APP_BASE_URL + '/'; // const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
// window.history.pushState({}, '', path); // window.history.pushState({}, null, path);
window.location.reload(); window.location.reload(false);
} catch(err) { } catch(err) {
console.log(err); console.log(err);
} }
@ -138,7 +143,6 @@ function QrCode () {
<h3>{secret}</h3> <h3>{secret}</h3>
<h1>Or Scan The QRCode</h1> <h1>Or Scan The QRCode</h1>
<div ref={ref} /> <div ref={ref} />
{/* <div>{ref}</div> */}
</> </>
)} )}

View File

@ -1,6 +1,6 @@
// import io from 'socket.io-client'; // import io from 'socket.io-client';
import api from '../script/axiosApi.tsx'; import api from '../script/axiosApi';
// import { useEffect, useRef } from 'react'; // import { useEffect, useRef } from 'react';
import io from 'socket.io-client'; import io from 'socket.io-client';
@ -8,13 +8,9 @@ import io from 'socket.io-client';
// const socket = io('http://86.209.110.20:4000'); // const socket = io('http://86.209.110.20:4000');
// const socket = io('http://172.29.113.91:4000'); // const socket = io('http://172.29.113.91:4000');
interface GameProps { function DrawCanvas(option) {
privateParty: boolean,
username?: string
gameId?: number
}
function DrawCanvas(option: number, gameParam: GameProps) {
console.log(`option= ${option}`); console.log(`option= ${option}`);
const superpowerModifier = option & 1; // Retrieves the superpower modifier const superpowerModifier = option & 1; // Retrieves the superpower modifier
@ -29,39 +25,12 @@ function DrawCanvas(option: number, gameParam: GameProps) {
// const socketRef = useRef(null); // const socketRef = useRef(null);
// socketRef.current = io('http://localhost:4000'); // socketRef.current = io('http://localhost:4000');
const socket = io('http://' + process.env.REACT_APP_BASE_URL + ':4000');
function launchGame()
{
if (!gameParam.privateParty)
{
console.log("laucnh matchmaking")
matchmaking();
}
else if (!gameParam.gameId)
{
console.log("laucnh private")
privateParty();
}
else
{
console.log("join private")
joinPrivateParty();
}
}
// const socket = socketRef.current // const socket = socketRef.current
console.log("start function"); console.log("start function");
const canvas = document.getElementById('myCanvas');
// let canvas: HTMLElement | null;
const canvas = document.getElementById('myCanvas') as HTMLCanvasElement | null;;
if (!canvas)
return ;
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
if(!ctx)
return ;
const socket = io('http://localhost:4000', { transports: ['polling'] });
// useEffect(() => { // useEffect(() => {
// console.log("useeffect?????????????????") // console.log("useeffect?????????????????")
// return () => { // return () => {
@ -80,8 +49,8 @@ function DrawCanvas(option: number, gameParam: GameProps) {
//socket //socket
let myId = 0; let myId = 0;
let gameId = 0; let gameId = 0;
let opName: string let opName;
let opRank: number; let opRank;
//general canvas //general canvas
let running = true; let running = true;
@ -130,43 +99,46 @@ function DrawCanvas(option: number, gameParam: GameProps) {
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// Socket ON // Socket handler
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
socket.on('pong:win', async () => { function matchmaking()
myScore = maxScore; {
console.log("instant win opponent disconnect") console.log(`id ion matcj= ${myId}`)
// const data = { const info = {
// myScore: myScore, id: myId,
// opScore: hisScore, option: option,
// opName: opName, };
// opRank: opRank, socket.emit('pong:matchmaking', info);
// };
// await api.post('/win', data);
console.log("after request1")
await api.post('/status', {status: 1});
console.log("after request2")
//disconnect ?
running = false;
socket.emit('pong:disconnect', {id: myId});
console.log("before reload")
// window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong");
// window.location.reload();
return ;
// console.log("send all ?? win");
});
socket.on('pong:privateId', async (data) => {
console.log("private id = ", data)
try{
await api.post("/partyInvite", {username: gameParam.username, gameId: data});
} catch(err) {
console.log(err)
} }
});
// socket.on('pong:gameId', (data) => {
// console.log("gameId received")
// gameId = data;
// // api.get('/profile');
// let myName;
// api.get('/profile').then((data) => {
// // Faire quelque chose avec les données
// console.log(data);
// myName = data.data.username;
// console.log(`myname= ${myName}`);
// }).catch((error) => {
// console.log(error);
// // exit() ;
// return;
// });
// const info = {
// id: myId,
// name: myName,
// gameId: gameId,
// };
// console.log("emit to name")
// socket.emit('pong:name', info);
// });
socket.on('pong:gameId', async (data) => { socket.on('pong:gameId', async (data) => {
console.log("gameId received"); console.log("gameId received");
@ -210,7 +182,6 @@ socket.on('pong:clientId', (data) => {
console.log("receive id") console.log("receive id")
myId = data; myId = data;
console.log(`id is= ${myId}`) console.log(`id is= ${myId}`)
launchGame();
}); });
socket.on('pong:info', (data) => { socket.on('pong:info', (data) => {
@ -243,60 +214,9 @@ socket.on('pong:power', (data) => {
// oPaddleY = (data.paddleY / data.height) * canvas.height // oPaddleY = (data.paddleY / data.height) * canvas.height
}); });
socket.on('pong:point', (data) => {
// hisScore += 1;
console.log("gain point");
// if (vX != 0)
// {
// console.log("up point");
myScore = data.point;
// }
vX = 0;
vY = 0;
ballX = canvas.width / 2;
ballY = canvas.height / 2;
});
//========================================================================================================
//========================================================================================================
// Socket EMIT
//========================================================================================================
//========================================================================================================
function matchmaking()
{
console.log(`id ion matcj= ${myId}`)
const info = {
id: myId,
option: option,
};
socket.emit('pong:matchmaking', info);
}
function privateParty()
{
console.log(`id private party= ${myId}`)
const info = {
id: myId,
option: option,
};
socket.emit('pong:privateParty', info);
}
function joinPrivateParty()
{
console.log(`id private party= ${myId}`)
const info = {
id: myId,
gameId: gameParam.gameId,
option: option,
};
socket.emit('pong:joinParty', info);
}
function send_info() function send_info()
{ {
if (!gameId || !canvas) if (gameId === 0)
return ; return ;
const info = { const info = {
id: myId, id: myId,
@ -314,7 +234,7 @@ socket.on('pong:point', (data) => {
function send_point() function send_point()
{ {
if (!gameId || !canvas) if (gameId === 0)
return ; return ;
console.log("send point"); console.log("send point");
const info = { const info = {
@ -325,9 +245,23 @@ socket.on('pong:point', (data) => {
socket.emit('pong:point', info); socket.emit('pong:point', info);
} }
socket.on('pong:point', (data) => {
// hisScore += 1;
console.log("gain point");
// if (vX != 0)
// {
// console.log("up point");
myScore = data.point;
// }
vX = 0;
vY = 0;
ballX = canvas.width / 2;
ballY = canvas.height / 2;
});
function send_paddle_info() function send_paddle_info()
{ {
if (!gameId || !canvas) if (gameId === 0)
return ; return ;
const info = { const info = {
id: myId, id: myId,
@ -341,8 +275,6 @@ socket.on('pong:point', (data) => {
function use_power() function use_power()
{ {
if (!canvas)
return ;
const info = { const info = {
gameId: gameId, gameId: gameId,
width: canvas.width, width: canvas.width,
@ -354,7 +286,7 @@ socket.on('pong:point', (data) => {
function send_forced_info() function send_forced_info()
{ {
if (!gameId || !canvas) if (gameId === 0)
return ; return ;
const info = { const info = {
gameId: gameId, gameId: gameId,
@ -379,8 +311,6 @@ socket.on('pong:point', (data) => {
function drawcenter() function drawcenter()
{ {
// ctx.restore(); // ctx.restore();
if (!ctx || !canvas)
return ;
ctx.fillStyle = 'white'; ctx.fillStyle = 'white';
ctx.fillRect(canvas.width / 2 - ctx.lineWidth / 2, 0, canvas.width / 300, canvas.height); ctx.fillRect(canvas.width / 2 - ctx.lineWidth / 2, 0, canvas.width / 300, canvas.height);
@ -393,13 +323,11 @@ socket.on('pong:point', (data) => {
ctx.font = canvas.width * 0.1 + "px Arial"; ctx.font = canvas.width * 0.1 + "px Arial";
ctx.textAlign = "center"; ctx.textAlign = "center";
ctx.textBaseline = "middle"; ctx.textBaseline = "middle";
ctx.fillText(myScore.toString(), canvas.width/4, canvas.height/8); ctx.fillText(myScore, canvas.width/4, canvas.height/8);
ctx.fillText(hisScore.toString(), canvas.width/1.25, canvas.height/8); ctx.fillText(hisScore, canvas.width/1.25, canvas.height/8);
} }
function drawPaddle() { function drawPaddle() {
if (!ctx || !canvas)
return ;
ctx.fillStyle = 'white'; ctx.fillStyle = 'white';
ctx.fillRect(paddleX, paddleY, paddleWidth, paddleHeight); ctx.fillRect(paddleX, paddleY, paddleWidth, paddleHeight);
ctx.fillRect(canvas.width - paddleX - paddleWidth, oPaddleY, paddleWidth, opPaddleHeight); ctx.fillRect(canvas.width - paddleX - paddleWidth, oPaddleY, paddleWidth, opPaddleHeight);
@ -407,8 +335,6 @@ socket.on('pong:point', (data) => {
function drawball() function drawball()
{ {
if (!ctx)
return ;
ctx.beginPath(); ctx.beginPath();
ctx.arc(ballX, ballY, ballRadius, 0, 2 * Math.PI); ctx.arc(ballX, ballY, ballRadius, 0, 2 * Math.PI);
// ctx.lineWidth = 2; // ctx.lineWidth = 2;
@ -423,52 +349,29 @@ socket.on('pong:point', (data) => {
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
matchmaking();
// while (!gameId) // while (!gameId)
// ; // ;
// Define a function to stop the drawing process // Define a function to stop the drawing process
const stopDrawCanvas = async () => { const stopDrawCanvas = () => {
running = false; running = false;
console.log("stopDrawCanvas 1")
if (gameParam.privateParty && !gameId) //delete invite
{
console.log("stopDrawCanvas2")
try{
// const info = {
// id: myId,
// option: option,
// };
await api.post("deleteInvite", {username: gameParam.username})
}
catch (err){
console.log(err)
}
}
socket.emit('pong:disconnect', {id: myId});
window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong");
// window.location.reload();
// Perform any necessary cleanup tasks // Perform any necessary cleanup tasks
// ... // ...
}; };
async function draw(timestamp: number) function draw(timestamp)
{ {
console.log("turning, running= ", running); console.log("turning");
if (!running) if (!running)
return ; return ;
if (!gameId || !canvas ) if (gameId === 0 )
{ {
// console.log("nogameid score= ", myScore);
requestAnimationFrame(draw); requestAnimationFrame(draw);
return ; return ;
} }
if (myScore === maxScore || hisScore === maxScore) if (myScore === maxScore || hisScore === maxScore)
{ {
console.log("maxScore!!!!")
const data = { const data = {
myScore: myScore, myScore: myScore,
opScore: hisScore, opScore: hisScore,
@ -477,23 +380,17 @@ async function draw(timestamp: number)
}; };
if (myScore === maxScore) if (myScore === maxScore)
{ {
await api.post('/win', data); api.post('/win', data);
await api.post('/status', {status: 1}); api.post('/status', {status: 1});
//disconnect ? console.log("send win");
socket.emit('pong:disconnect', {id: myId});
console.log("send all ?? win");
} }
else else
{ {
await api.post('/loss', data); api.post('/loss', data);
await api.post('/status', {status: 1}); api.post('/status', {status: 1});
socket.emit('pong:disconnect', {id: myId});
//disconnect ?
console.log("send loose"); console.log("send loose");
} }
window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong"); window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong");
// window.location.reload();
return ; return ;
} }
@ -502,9 +399,6 @@ async function draw(timestamp: number)
ballX += vX * deltaTime * canvas.width; ballX += vX * deltaTime * canvas.width;
ballY += vY * deltaTime * canvas.height; ballY += vY * deltaTime * canvas.height;
if (!ctx)
return ;
// requestAnimationFrame(draw);
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
drawPaddle(); drawPaddle();
drawcenter(); drawcenter();
@ -541,17 +435,14 @@ async function draw(timestamp: number)
} }
function updatePaddlePosition(newY: number) function updatePaddlePosition(newY)
{ {
if (newY >= 0 && newY <= canvas.height - paddleHeight)
if (canvas && newY >= 0 && newY <= canvas.height - paddleHeight)
paddleY = newY; paddleY = newY;
} }
function is_collision() function is_collision()
{ {
if (!canvas)
return ;
if (ballX <= paddleX + paddleWidth + ballRadius) if (ballX <= paddleX + paddleWidth + ballRadius)
{ {
if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)//touch paddle if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)//touch paddle
@ -576,12 +467,15 @@ async function draw(timestamp: number)
ballY = ballRadius + 2 ballY = ballRadius + 2
// send_info(); // send_info();
} }
// else if (ballX + ballRadius + 2 >= canvas.width) //touch right wall
// {
// vX = -vX;
// // send_info();
// }
} }
function is_out() function is_out()
{ {
if (!canvas)
return ;
if (ballX < 0) if (ballX < 0)
{ {
if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius) if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)
@ -601,9 +495,7 @@ async function draw(timestamp: number)
} }
if (ballX > canvas.width) if (ballX > canvas.width)
{ {
// if (ballX > canvas.width * 2) console.log("win point")
// socket.emit
// console.log("win point")
// if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius) // if (ballY <= paddleY + paddleHeight + ballRadius && ballY >= paddleY - ballRadius)
// { // {
// console.log('true hehe'); // console.log('true hehe');
@ -626,10 +518,17 @@ async function draw(timestamp: number)
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
// Key/Mouse/Finger Listener // Listener
//======================================================================================================== //========================================================================================================
//======================================================================================================== //========================================================================================================
document.addEventListener('resize', event => {
// event.height
// event.width
const { clientWidth, clientHeight } = canvas.parentElement;
console.log(`resize detected widht= ${clientWidth} height= ${clientHeight}`)
});
document.addEventListener('mousemove', event => { document.addEventListener('mousemove', event => {
const mouseY = event.clientY; const mouseY = event.clientY;

View File

@ -68,8 +68,8 @@ function SuccessToken() {
window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong"); window.location.replace("http://" + process.env.REACT_APP_BASE_URL + "/pong");
// const path = 'http://' + process.env.REACT_APP_BASE_URL + '/'; // const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
// window.history.pushState({}, '', path); // window.history.pushState({}, null, path);
// window.location.reload(); // window.location.reload(false);
} }
else else
@ -197,8 +197,8 @@ function SuccessToken() {
// // history.push('/login') // // history.push('/login')
// const path = 'http://' + process.env.REACT_APP_BASE_URL + '/'; // const path = 'http://' + process.env.REACT_APP_BASE_URL + '/';
// window.history.pushState({}, '', path); // window.history.pushState({}, null, path);
// window.location.reload(); // window.location.reload(false);
// } // }
// else // else

View File

@ -9,7 +9,7 @@
input.qr{ input.qr{
width: 20%; width: 20%;
border-radius: 5px; border-radius: 5px;
background-color: rgb(0, 0, 0); background-color: rgb(66, 66, 66);
margin : 1%; margin : 1%;
color:white; color:white;
} }

View File

@ -89,17 +89,6 @@ span {
border-radius: 50%; border-radius: 50%;
} }
.success {
height: 2%;
width: 2%;
/* border: solid; */
margin-top: 1%;
margin: 3vh;
/* margin-bottom: -12vh; */
/* border-color: black; */
/* border-radius: 50%; */
}
.header-pic{ .header-pic{
text-align: end; text-align: end;
/* id: right; */ /* id: right; */

View File

@ -204,18 +204,6 @@ p {
margin: 1%; margin: 1%;
} }
.darkSubmit{
display: inline-block;
color: white;
background-color: #282155;
border-radius: 10px;
padding: 5px;
font-size: 1.2rem;
text-decoration: none;
font-weight:lighter;
margin: 1%;
}
.div_submit { .div_submit {
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
@ -288,12 +276,6 @@ p {
background-color: rgba(212, 175, 55, 0.7); background-color: rgba(212, 175, 55, 0.7);
font-size: 25px; font-size: 25px;
color: rgba(255, 255, 255, 1); color: rgba(255, 255, 255, 1);
flex-wrap: wrap;
}
.yellowAlert::p {
overflow-wrap: break-word;
max-width: 1000px;
} }
.modalSetting{ .modalSetting{
@ -316,7 +298,7 @@ p {
.settingSecondPart{ .settingSecondPart{
margin-top: 10%; margin-top: 10%;
margin-left: 5%; margin-left: 10%;
/* margin-left: 20%; */ /* margin-left: 20%; */
} }
@ -334,20 +316,3 @@ input.in{
border-radius: 12px; border-radius: 12px;
width: 70%; width: 70%;
} }
input.in_howLong{
margin-top: 14.5%;
margin-left: 0px;
background-color: black;
color: white;
border-radius: 12px;
width: 15%;
}
.mdp{
background-color : black;
border-radius: 8px;
color: white;
width: 20%;
}

View File

@ -1,75 +1,11 @@
/* Container style */
.file-upload-container {
margin-left: 2rem;
font-size: 1.7rem;
/* background: #5843e4; */
/* color:#f5f5f5; */
margin: 0 16px;
text-decoration: none;
padding: 10px 16px;
border-radius: 20px;
display: flex;
align-items: center;
gap: 10px;
}
/* File input style */
.file-input {
/* background: #5843e4; */
/* color:#f5f5f5; */
display: none; /* Hide the default file input */
}
.file-label {
padding: 8px 12px;
background-color: #f2f2f2;
color: #555;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.file-label:hover {
background-color: #e0e0e0;
}
/* Button style */
.upload-button {
padding: 8px 12px;
background-color: #5843e4;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.upload-button:hover {
background-color: #0056b3;
}
.page { .page {
text-align: center; text-align: center;
overflow-y: scroll;
/* height: 50vh; */ /* height: 50vh; */
/* width: 50vh; */ /* width: 50vh; */
/* background-color: black; */ /* background-color: black; */
} }
.profile { .profile {
align-items: center;
text-align: center;
flex-direction: row; flex-direction: row;
color: white; color: white;
} }
@ -82,7 +18,7 @@
border-color: red; border-color: red;
/* border-image: linear-gradient(90deg, #5843e4, #5a0760); */ /* border-image: linear-gradient(90deg, #5843e4, #5a0760); */
/* margin-top: 20px; */ margin-top: 20px;
} }
.home{ .home{
@ -109,7 +45,7 @@
.div_history { .div_history {
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
/* margin-top: -80px; */ margin-top: -80px;
} }
.edit_name { .edit_name {

View File

@ -2,7 +2,7 @@
/* display: flex; */ /* display: flex; */
/* flex-direction: column; */ /* flex-direction: column; */
/* background-color: red; */ /* background-color: red; */
height: 60vh; height: 70vh;
/* padding: 15px; */ /* padding: 15px; */
/* overflow: scroll; */ /* overflow: scroll; */

View File

@ -1,21 +1,16 @@
.playButton { .playButton {
background-image: linear-gradient(90deg, #5843e4, #5a0760); background-image: linear-gradient(90deg, #5843e4, #5a0760);;
display: flex;
flex-wrap: wrap;
overflow: hidden;
border-radius: 5vh; border-radius: 5vh;
color: white; color: white;
/* display: block; */ display: block;
margin: auto; margin: auto;
margin-top: 30vh; margin-top: 30vh;
padding: 2vh 4vw; padding: 2vh 5vw;
height: 10vh; height: 10vh;
width: 20vw; width: 20vw;
font-size: 250%; font-size: 300%;
text-align: center;
} }
.field { .field {
background-color: rgb(249, 249, 249); background-color: rgb(249, 249, 249);
/* border-radius: 5vh; */ /* border-radius: 5vh; */
@ -45,29 +40,6 @@
/* padding-top: 25; */ /* padding-top: 25; */
/* padding-top: 177.77% */ /* padding-top: 177.77% */
} }
@media screen and (max-width: 900px){
.playButton{
font-size: 200%;
}
}
@media screen and (max-width: 700px){
.playButton{
font-size: 150%;
}
}
@media screen and (max-width: 530px){
.playButton{
font-size: 100%;
}
}
@media screen and (max-width: 350px){
.playButton{
font-size: 50%;
}
}
#myCanvas { #myCanvas {
background-color: rgb(124, 47, 47); background-color: rgb(124, 47, 47);

View File

@ -77,6 +77,11 @@ input{
text-decoration: none; text-decoration: none;
} }
label{
}
.login {
}
.loginForm { .loginForm {
align-items: center; align-items: center;

View File

@ -0,0 +1,8 @@
{
"compiledOptions": {
"composite": true,
"allowJs": true,
"allowImportingTsExtensions": true,
"jsx": "react"
}
}

2
containers/test Normal file
View File

@ -0,0 +1,2 @@
cc toi
cc 2

View File

@ -11,7 +11,7 @@ services:
# command: sh -c "envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'" # command: sh -c "envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
ports: ports:
- 8080:8080 - 80:80
volumes: volumes:
- ./conf/nginx.conf:/etc/nginx/conf.d/default.conf - ./conf/nginx.conf:/etc/nginx/conf.d/default.conf
# volumes: # volumes:
@ -34,7 +34,7 @@ services:
# depends_on: # depends_on:
# - nginx # - nginx
ports: ports:
- 8001:8001 - 8080:8080
volumes: volumes:
- ./containers/react:/app - ./containers/react:/app
# - ./containers/react:/app # - ./containers/react:/app